JavaWeb——Servlet

前言:什么是Servlet?

Servlet是采用Java写的Web服务器端程序。

当客户端(浏览器)向服务器端发起请求时,服务器将请求(Request)进行封装后便调用Servlet程序处理请求,Servlrt将处理后的结果(Response)返回给服务器,服务器对结果进行封装后返回给客户端。

我们在学习开发中往往采用TomCat来作为服务器,由TomCat来调用Servlet处理Web请求。

Servlet

Servlet中的方法

1
2
3
4
5
6
7
8
9
10
11
public interface Servlet {
void init(ServletConfig var1) throws ServletException;

ServletConfig getServletConfig();

void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

String getServletInfo();

void destroy();
}

当客户端向服务器发起请求时,服务器启动Servlet,Servlet首先调用 getServletConfig() 方法获得Servlet相关配置,并作为参数传递给 init() 方法,init() 方法用来初始化Servlet,Servlet初始化完成后就会调用 service() 方法处理请求 ,getServletInfo() 可以获得Servlet的一段描述信息,当请求处理结束后,便会调用 destroy() 方法销毁Servlet。这也是Servlet的生命周期。

ServletRequest 及 ServletResponse

Servlet在调用 service() 方法前会生成ServletRequest对象和ServletResponse对象。

我们可以通过ServletRequest中的方法来获取请求的相关信息:

1
2
3
4
5
6
7
8
9
public interface ServletRequest {

int getContentLength();//返回请求主体的字节数

String getContentType();//返回主体的MIME类型

String getParameter(String var1);//返回请求参数的值

}

可以通过ServletResponse中的方法自定义返回结果:

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
public interface ServletResponse {
String getCharacterEncoding();// 获取字符编码格式

String getContentType();//获取内容类型

ServletOutputStream getOutputStream() throws IOException;//获取二进制输出流,可用于(通过缓冲区)向响应体中书写内容

PrintWriter getWriter() throws IOException;//获取文本输出流,可用于(通过缓冲区)向响应体中书写内容

void setCharacterEncoding(String var1);// 设置字符编码格式

void setContentLength(int var1);// 设置响应体长度

void setContentType(String var1);// 设置响应数据类型

void setBufferSize(int var1);// 设置缓冲区大小

int getBufferSize();// 获取缓冲区大小

void flushBuffer() throws IOException;// 刷新缓冲区

void resetBuffer();// 清空缓冲区

boolean isCommitted();// 响应是否已提交

void reset();// 清空缓冲区以及响应状态码和响应头

}

GenericServlet

直接实现Servlet接口较为复杂,我们需要实现其中的全部方法。GenericServlet抽象类的出现很好的解决了这个问题:

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
private transient ServletConfig config;

public GenericServlet() {
}

public void destroy() {
}

public String getInitParameter(String name) {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getInitParameter(name);
}
}

public Enumeration<String> getInitParameterNames() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getInitParameterNames();
}
}

public ServletConfig getServletConfig() {
return this.config;
}

public ServletContext getServletContext() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getServletContext();
}
}

public String getServletInfo() {
return "";
}

public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}

public void init() throws ServletException {
}

public void log(String msg) {
this.getServletContext().log(this.getServletName() + ": " + msg);
}

public void log(String message, Throwable t) {
this.getServletContext().log(this.getServletName() + ": " + message, t);
}

public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

public String getServletName() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getServletName();
}
}
}

GenericServlet抽象类为我们提供了Servlet接口中方法的默认实现,我们可以只实现我们需要的方法。

HttpServlet

在实际的开发中,我们更常使用HttpServlet抽象类,它继承了GenericServlet抽象类。

HttpServlet覆盖了GenericServlet中的 service() 方法,在方法中调用了提供的另一个 service() 方法:

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
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if (ifModifiedSince < lastModified) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}

}

根据不同的Http请求类型调用不同的doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete方法,当我们需要实现具体的逻辑时只需要覆盖相应的do方法即可。

HttpServletRequest

HttpServletRequest继承自ServletRequest,新增了几个方法:

1
2
3
4
5
6
7
8
9
10
11
String getContextPath();//返回请求上下文的请求URI部分

Cookie[] getCookies();//返回一个cookie对象数组

String getHeader(String var1);//返回指定HTTP标题的值

String getMethod();//返回生成这个请求HTTP的方法名称

String getQueryString();//返回请求URL中的查询字符串

HttpSession getSession();//返回与这个请求相关的会话对象

HttpServletResponse

HttpServletResponse继承自ServletResPonse,新增了几个方法:

1
2
3
4
5
6
7
8
9
void addCookie(Cookie var1);//给这个响应添加一个cookie

void addHeader(String var1, String var2);//给这个请求添加一个响应头

void setHeader(String name, String value);// 设置响应头的值

void sendRedirect(String var1) throws IOException;//发送一条响应码,将浏览器跳转到指定的位置

void setStatus(int var1);//设置响应行的状态码

JavaWeb——Servlet
https://www.wananhome.site/2024/02/03/JavaWeb——Servlet/
作者
WanAn
发布于
2024年2月3日
许可协议