Java Servlet开发的轻量级MVC框架最佳实践
在Servlet开发的工程实践中,为了减少过多的业务Servlet编写,会采用构建公共Servlet的方式,通过反射来搭建轻量级的MVC框架,从而加快应用开发。
关于Servlet开发的基础知识,请看:JavaWeb开发之详解Servlet及Servlet容器
前后端交互的基本形式
一般来说,前端提交数据请求有三种基本方式,分别是表单、链接和Ajax
1. 按钮
1 <form action="/BaseServlet/ServletDemo02?method=addStu" method="post">2 用户<input type="text" name="username"/><br/>
3 <button>提交</button>
4 </form>
2. 链接
<a href="/BaseServlet/ServletDemo02?method=delStu">删除学生</a><br/>
3. Ajax
1 <button onclick="fn()">按钮</button>2 <script>
3 function fn(){
4 $.post("/BaseServlet/ServletDemo02",{"method":"checkStu","user":"tom"},function(data){
5 alert(data);
6 });
7 }
在Servlet开发的语境中,它们的共同点都是:指定处理的Servlet类路径(在web.xml中指定)以及附带在请求中的“method”参数
通过调用request参数匹配业务处理逻辑
前端按照以上方法发起请求,Servlet容器就会把请求交给对应的Servlet处理,并且附带上形如 method=delStu 的参数,利用这个原理,就可以构建一个基础Servlet类,用来优化开发:
1 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {2 //获取客户端提交到服务端的method对应的值
3 String md=request.getParameter("method");
4 //定义变量,存放功能执行完毕之后要转发的路径
5 String path=null;
6
7 //通过判断md中不同的内容来决定本次功能
8 if("addStu".equals(md)){
9 path=addStu(request, response);
10 }else if("delStu".equals(md)){
11 path=delStu(request, response);
12 }else if("checkStu".equals(md)){
13 path=checkStu(request, response);
14 }else if("".equals(md)){
15
16 }
17 if(null!=path){
18 //服务端的请求转发
19 request.getRequestDispatcher(path).forward(request, response);
20 }
21 }
22
23
24 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
25 doGet(request, response);
26 }
27
28 protected String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
29 System.out.println("添加学生");
30 return "/test.html";
31
32 }
33 protected String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
34 System.out.println("删除学生");
35 return "/test.html";
36
37 }
38 protected String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
39 System.out.println("检查学生");
40 response.getWriter().println("DDDDDD");
41 return null;
42 }
以上的Servlet对请求进行了处理,通过获取index.html的请求,最后请求转发至目标页面,其核心思想是:
1. 提取request的method参数的值;
2. 定义变量,存储请求转发的路径;
3. 通过判断method参数中的值的内容,来决定调用哪个业务功能。
4. 完成业务功能后,使用请求转发处理
通过反射匹配业务处理逻辑
当业务量多的时候,以上实践仍是不够,此时比较好的方式就是采用反射。
1 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {2 doGet(request, response);
3 }
4
5 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
6 //获取客户端提交到服务端的method对应的值
7 String md=request.getParameter("method");
8 //定义变量,存放功能执行完毕之后要转发的路径
9 String path=null;
10 //获取到当前字节码对象(ServletDemo02.class在内存中对象)
11 Class<? extends ServletDemo02> clazz = this.getClass();
12 try {
13 //获取clazz上名称为md, 参数为HttpServletRequest和HttpServletResponse的方法
14 Method method=clazz.getMethod(md, HttpServletRequest.class,HttpServletResponse.class);
15 if(null!=method){
16 //调用找到的方法
17 path=(String)method.invoke(this, request,response);
18 }
19 if(null!=path){
20 //服务端的转发
21 request.getRequestDispatcher(path).forward(request, response);
22 }
23 } catch (Exception e) {
24 e.printStackTrace();
25 }
26
27 }
28
29 public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
30 System.out.println("添加学生");
31 return "/test.html";
32
33 }
34 public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
35 System.out.println("删除学生");
36 return "/test.html";
37
38 }
39 public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
40 System.out.println("检查学生");
41 response.getWriter().println("DDDDDD");
42 return null;
43 }
1. 提取request的method参数的值;
2. 定义变量,存储请求转发的路径;
3. 获取到当前Servlet对象在内存中的Class对象
4. 获取Class对象上名称为md, 参数为HttpServletRequest和HttpServletResponse的方法
5. 根据是否返回方法对象,调用业务功能并使用请求转发处理
Java HttpServlet的父类GenericServlet,就是通过这个方法来调取HttpServlet的doGet或doPost方法的。
最佳实践
在实践开发中,一般会搭建一个BaseServlet,继承了HttpServlet并重写其Service方法,通过反射来找到业务功能子类对应的业务方法。
1 public class BaseServlet extends HttpServlet {2 private static final long serialVersionUID = 12197442526341123L;
3
4 @Override
5 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
6 System.out.println("service.....");
7 //获取客户端提交到服务端的method对应的值
8 String md=request.getParameter("method");
9 //定义变量,存放功能执行完毕之后要转发的路径
10 String path=null;
11 //获取到当前字节码对象(ServletDemo02.class在内存中对象)
12 Class<? extends BaseServlet> clazz = this.getClass();
13 try {
14 //获取clazz上名称为md方法
15 Method method=clazz.getMethod(md, HttpServletRequest.class,HttpServletResponse.class);
16 if(null!=method){
17 //调用找到的方法
18 path=(String)method.invoke(this, request,response);
19 }
20 if(null!=path){
21 //服务端的转发
22 request.getRequestDispatcher(path).forward(request, response);
23 }
24 } catch (Exception e) {
25 e.printStackTrace();
26 }
27 }
28
29 }
而业务功能子类,则继承BaseServlet,专注于业务逻辑的开发
1 public class ServletDemo03 extends BaseServlet {2
3 private static final long serialVersionUID = 11248215356242123L;
4
5 public ServletDemo03() {
6 System.out.println("没有参数的构造函数");
7 }
8
9 public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
10 System.out.println("添加学生");
11 return "/test.html";
12
13 }
14 public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
15 System.out.println("删除学生");
16 return "/test.html";
17
18 }
19 public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
20 System.out.println("检查学生");
21 response.getWriter().println("DDDDDD");
22 return null;
23 }
24
25 }
以上是 Java Servlet开发的轻量级MVC框架最佳实践 的全部内容, 来源链接: utcz.com/z/391331.html