- Servlet注解简化配置
3.简化配置
3.1 Servlet注解简化配置
分析 oa 项目中的
web.xml
文件:- 现在只是一个单表的 CRUD,没有复杂的业务逻辑,很简单的一丢丢功能,
web.xml
文件中就有如此多的配置信息。如果采用这种配置方式,对于一个大的项目来说,web.xml
文件会非常庞大,有可能最终会达到几十兆。 - 在
web.xml
文件中进行servlet
信息的配置,显然开发效率比较低,每一个都需要配置一下。而且在web.xml
文件中的配置是很少被修改的,所以这种配置信息能不能直接写到 java 类当中呢?答案是可以的。
- 现在只是一个单表的 CRUD,没有复杂的业务逻辑,很简单的一丢丢功能,
Servlet3.0 版本之后,推出了各种
Servlet
基于注解式开发。优点是什么?- 开发效率高,不需要编写大量的配置信息,直接在 java 类上使用注解进行标注。
web.xml
文件体积变小了。
并不是说注解有了之后,
web.xml
文件就不需要了:- 有一些需要变化的信息,还是要配置到
web.xml
文件中。一般都是“注解+配置文件”的开发模式。 - 一些不会经常变化修改的配置建议使用注解。一些可能会被修改的建议写到配置文件中。
- 有一些需要变化的信息,还是要配置到
★注解配置的使用
注解对象的使用格式:
@注解名称(属性名=属性值, 属性名=属性值, 属性名=属性值, ...)
通过在 Servlet 类上使用
@WebServlet
,来达到等同于在web.xml
中进行配置的效果。@WebServlet
注解中有哪些属性呢?name
属性:用来指定 Servlet 的名字。等同于<servlet-name>
urlPatterns
属性:用来指定 Servlet 的映射路径,可以指定多个字符串。等同于<url-pattern>
注意:映射路径是可以有多个的,表明当使用这些映射路径时,调用的都是该 Servlet 的服务。
loadOnStartUp
属性:用来指定在服务器启动阶段是否加载该 Servlet。等同于<load-on-startup>
value
属性:value 属性的作用等同于 urlPatterns,当注解中只有 Servlet 的映射路径的时候,value 属性名是可以省略的。等同于<url-pattern>
注意:不是必须将所有属性都写上,只需要提供需要的,(需要什么用什么)。
注意:当属性是一个数组,但是如果数组中只有一个元素,则使用该注解的时候,属性值的大括号可以省略。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17//@WebServlet(urlPatterns = {"/welcome1", "/welcome2"})
// 注意:当注解的属性是一个数组,并且数组中只有一个元素,大括号可以省略。
//@WebServlet(urlPatterns = "/welcome")
// 这个value属性和urlPatterns属性一致,都是用来指定Servlet的映射路径的。
//@WebServlet(value = {"/welcome1", "/welcome2"})
// 如果注解的属性名是value的话,属性名也是可以省略的。
//@WebServlet(value = "/welcome1")
//@WebServlet({"/wel", "/abc", "/def"})
public class WelcomeServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("欢迎学习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
39
40package com.f.javaweb.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
/**
* @author fzy
* @date 2023/12/6 11:55
*/
public class HelloServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String servletName = this.getServletName();
out.print("Servlet名称为: " + servletName + "<br/>");
String servletPath = request.getServletPath();
out.print("ServletPath为: " + servletPath + "<br/>");
Enumeration<String> initParameterNames = this.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
String name = initParameterNames.nextElement();
String value = this.getInitParameter(name);
out.print(name + " = " + value + "<br/>");
}
}
}
3.2 通过反射获取注解
1 | package com.f.javaweb.annotation; |
3.3 使用模板方法设计模式解决类爆炸
上面的注解解决了配置文件的问题。但是现在的 oa 项目仍然存在一个比较臃肿的问题。
- 一个单表的 CRUD,就写了 6 个 Servlet。如果一个复杂的业务系统,这种开发方式,显然会导致类爆炸(类的数量太大)。
- 怎么解决这个类爆炸问题?可以使用模板方法设计模式。
怎么解决类爆炸问题?
- 以前的设计是一个请求对应一个 Servlet 类,1000 个请求就会对应 1000 个 Servlet 类,导致类爆炸。
- 可以这样做:一个业务对应一个 Servlet 类,一个请求对应 Servlet 类中的一个方法。例如处理部门相关业务的对应一个 DeptServlet、处理用户相关业务的对应一个 UserServlet、处理银行卡卡片业务对应一个 CardServlet。
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
68package com.bjpowernode.oa.web.action;
import com.bjpowernode.oa.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
// 模板类
// 模糊匹配
// 只要请求路径是以"/dept"开始的,就都走这个Servlet。
//@WebServlet("/dept/*")
public class DeptServlet extends HttpServlet {
// 模板方法
// 重写service方法(并没有重写doGet或者doPost,因为既有GET请求,也有POST请求)
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取servlet path
String servletPath = request.getServletPath();
if("/dept/list".equals(servletPath)){
doList(request, response);
} else if("/dept/save".equals(servletPath)){
doSave(request, response);
} else if("/dept/edit".equals(servletPath)){
doEdit(request, response);
} else if("/dept/detail".equals(servletPath)){
doDetail(request, response);
} else if("/dept/delete".equals(servletPath)){
doDel(request, response);
} else if("/dept/modify".equals(servletPath)){
doModify(request, response);
}
}
private void doList(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
private void doSave(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
private void doEdit(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
private void doDetail(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
private void doDel(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
private void doModify(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}