Java Web

前言

这篇文章用来记录java web的学习,想到哪记录到哪。主要参考韩顺平老师的讲义。

每次记录是当下的理解,可能存在有误差的地方,随着深入可能会不停的增加或修改。如果错误,欢迎批评指正。

这部分学习用的idea2024加上tomcat8 整个浏览器与后端交互的过程参考下图:

pZazSJJ.png

这里的Tomcat是web中间件,本质上也是JAVA程序代码,作为浏览器与容器之间的“中间人”,Tomcat处理浏览器的http请求,从而去调用容器里面相应的java程序和Servlet。结果再通过Tomcat返回给浏览器。

简单的tomcat demo

tomcat的目录说明:

javaweb17

以下是韩老师讲义中关于tomcat的一个demo,这里它通过监听9999端口,并且将src/hello.html的内容进行读取并返回。这是一个非常非常简单的demo,实际的tomcat的程序代码要比这个复杂的多,但是从中可以知道tomcat其实并没有那么神秘,无非是做了容器与浏览器之间的一个桥梁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 这是我们自己写的一个web服务, 可以返回hello.html给浏览器
*/
public class MyTomcat {
public static void main(String[] args) throws IOException {
//1.在9999端口监听
ServerSocket serverSocket = new ServerSocket(9999);
//如果serverSocket 没有关闭,就等待连接, 不停的等待
while (!serverSocket.isClosed()) {
System.out.println("=====我的web服务在 9999端口监听=====");
//2. 等待浏览器/客户端连接, 得到socket
// 该socket用于通信
Socket socket = serverSocket.accept();

//3. 通过socket 得到 输出流,[]
OutputStream outputStream = socket.getOutputStream();
// 返回给浏览器/客户端
//4. 读取 hello.html 文件返回即可=> 如何读取文件内容
// 得到文件输入流(字符输入流), 和 src/hello.html
BufferedReader bufferedReader =
new BufferedReader(new FileReader("src/hello.html"));
String buf = "";
// 循环读取hello.html
while ((buf = bufferedReader.readLine()) != null) {
outputStream.write(buf.getBytes());
}

outputStream.close();
socket.close();
}
serverSocket.close();
}
}

Servlet

Servlet本质上也是一段段封装好的java代码,封装,也就是功能集成,比如它的http板块,就可以直接拿来用。拿来处理http请求。有点类似于python里面的那些库。当然只能说是类比,java里面包的概念和python不是一回事。

idea部署web应用

这里包括tomcat以及servlet

简单来看的话,分三步,第一步是添加web工件(add web framework ),第二步就是配置tomcat ,第三步引入servlet。这里还是记录一下:

1.文件 -> 新建 -> 项目

pZazeFe.png

2.添加web框架

pZazQyt.png

pZazlOP.png

3.配置tomcat

pZazaSs.png

接下来对tomcat进行详细配置,注意底下有个修复,我们可以修复下:

pZaz6kF.png

pZazcY4.png

改完之后先点击应用,然后再点击确定。

到这里我们可以试着运行一下,看tomcat有没有配置成功,毕竟别忘了我们web目录下面是有一个index.jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<%--
Created by IntelliJ IDEA.
User: 51261
Date: 2026/1/5
Time: 下午6:28
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
$END$
</body>
</html>

我们在idea里面运行一下,然后访问可以发现成功了:

pZazRp9.png

pZazf61.png

接下来就是配置Servlet,这里首先把Servlet的jar包导进来(Servlet的包在tomcat里面的lib下E:\security\tomcat\apache-tomcat-8.5.100\lib\servlet-api.jar)

在web下的WEB-INF下新建一个lib,然后把servlet-api.jar包复制进去

pZazjXt.png

接着添加为库,导入进去

javaweb11

确定:

javaweb12

可以发现成功导入:

javaweb13

接下来就是继承Servlet类,对五个主要方法进行重写,我们可以在src目录下新建一个com,然后再新建一个HelloServlet.java文件。

javaweb14

javaweb15

接着对方法进行重写,这里简单重写做测试用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com;
import javax.servlet.*;
import java.io.IOException;

public class HelloServlet implements Servlet {

@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init() is called!");

}

@Override
public ServletConfig getServletConfig() {
return null;
}

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello!Service!");

}

@Override
public String getServletInfo() {
return "";
}

@Override
public void destroy() {

}
}

重写方法完之后还是不能访问,需要在web.xml做配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>HelloServlet</servlet-name>> //和底下<servlet-mapping>里面的<servlet-name>保持一致
<servlet-class>com.HelloServlet</servlet-class> //HelloServlet类所在路径
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern> //访问路由
</servlet-mapping>
</web-app>

到此,我们就可以正常访问了,并且能在console里面看到输出结果:

javaweb16

idea web工程目录说明

javaweb18

out目录:会在tomcat运行的时候生成,这个才是展示给外界去访问的工作目录。

src目录:存放java文件

web目录:web目录下可以直接放html文件。web-inf目录下一般放第三方lib比如之前提到的servlet-api.jarweb.xml 用作配置信息,比如上面提到的给servlet做配置。

GET和POST分发处理

通过继承Servlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class HelloServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException
{
System.out.println("init() is called!");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("Hello!Service!");
HttpServletRequest httpServletRequest=(HttpServletRequest)servletRequest;
String method=httpServletRequest.getMethod();
if("GET".equals(method))
{
System.out.println("GET");
}
else if("POST".equals(method))
{

System.out.println("POST");
}
else
{
System.out.println("else");
}

}
@Override
public String getServletInfo() {
return "";
}
@Override
public void destroy() {
}
}

通过继承HttpServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HiServlet extends HttpServlet {
@Override //这里面的doPost和doGet方法 已经在HttpServlet里面实现了,这里进行重写即可。
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost() is called!");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet() is called!");
}
}

可以发现直接通过继承HttpServlet 对比 继承 Servlet 省了很多事。

ServletConfig

用来获取Servlet的配置信息,比如web.xml 里面配置的<init-param></init-param>

1
2
3
4
5
6
7
8
9
10
11
12
<servlet>
<servlet-name>DBServlet</servlet-name>
<servlet-class>com.DBServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>my0n9s</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123456</param-value>
</init-param>
</servlet>

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;

public class DBServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig();
String username1 = servletConfig.getInitParameter("username");
String password1 = servletConfig.getInitParameter("password");
System.out.println(username1);
System.out.println(password1);
}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}

ServletContext

用来获取web.xml配置的上下文参数context-param ,获取工程路径,绝对路径等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletContext_ extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
String contextPath = servletContext.getContextPath(); //获取路径:/Servlet
String website = servletContext.getInitParameter("website"); //获取到website对应的value
String realPath = servletContext.getRealPath("/"); //获取到工程的绝对路径
System.out.println("contextPath: " + contextPath);
System.out.println("website: " + website);
System.out.println("realPath: " + realPath);

}

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}