封装Servlet工具类
一.封装过程
1.1 封装前
1.1.1为何要封装Servlet
-
在编写Servlet程序时我们发现,为了对应前端jsp不同的功能,我们需要相应的创建的多个Servlet:
- 登录功能:LoginServlet
- 注册功能:RegisterServlet
- 增加功能:AddServlet
- 注销功能:LogoutServlet
.....
-
如果如上创建多个Servlet,不仅导致整个项目Servlet过多,名称难起,代码重复过多,所以我们考虑对应一个整体模块使用一个Servlet,通过判断不同的功能跳转到不同方法中去实现
- 在编写Servlet程序时我们发现,为了对应前端jsp不同的功能,我们需要相应的创建的多个Servlet:
- 登录功能:LoginServlet
- 注册功能:RegisterServlet
- 增加功能:AddServlet
- 注销功能:LogoutServlet
- 如果如上创建多个Servlet,不仅导致整个项目Servlet过多,名称难起,代码重复过多,所以我们考虑对应一个整体模块使用一个Servlet,通过判断不同的功能跳转到不同方法中去实现
1.2 版本1:通过if判断方法实现
1.2.1代码实现
package it.cn.store.user.web.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * Servlet implementation class UserServlet */public class UserServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //接收数据,封装实体 String methodName = request.getParameter("methodName"); if("register".equalsIgnoreCase(methodName)){ register(request,response); }else if ("login".equalsIgnoreCase(methodName)) { login(request,response); }else if ("logout".equalsIgnoreCase(methodName)) { logout(request,response); }else { System.out.println("未知错误,系统即将自爆!!!!!"); } //调用Service对象,操作 //数据回显 } //注销 public void logout(HttpServletRequest request, HttpServletResponse response) { System.out.println("执行注销操作,全体都有"); } //登录 public void login(HttpServletRequest request, HttpServletResponse response) { System.out.println("登录程序准备启动,一级准备"); } //注册 public void register(HttpServletRequest request, HttpServletResponse response) { System.out.println("注册程序开始启动,请准备好~~~~爆炸~~"); }}
package it.cn.store.user.web.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class UserServlet*/public class UserServlet extends HttpServlet {private static final long serialVersionUID = 1L;public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//接收数据,封装实体String methodName = request.getParameter("methodName");if("register".equalsIgnoreCase(methodName)){register(request,response);}else if ("login".equalsIgnoreCase(methodName)) {login(request,response);}else if ("logout".equalsIgnoreCase(methodName)) {logout(request,response);}else {System.out.println("未知错误,系统即将自爆!!!!!");}//调用Service对象,操作//数据回显}//注销public void logout(HttpServletRequest request, HttpServletResponse response) {System.out.println("执行注销操作,全体都有");}//登录public void login(HttpServletRequest request, HttpServletResponse response) {System.out.println("登录程序准备启动,一级准备");}//注册public void register(HttpServletRequest request, HttpServletResponse response) {System.out.println("注册程序开始启动,请准备好~~~~爆炸~~");}}
1.2.2思路分析
- 创建不同功能对应的不同方法
- 获取用户前端输入方法名称methodName
- 根据方法名进行if判断
- 测试结果
- - - - - - - - - - - - - - - - - - - - - - - - - - -
1.2.3细节分析
- 功能实现:
- 通过if判断实现不同的mentodName调用不同的方法
- 优缺点:
- 优点:实现了一个Servlet中多个功能
- 缺点:扩展性差:每次添加一个功能,就要一个if去对应
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1.3 版本2:通过反射调用实现
1.3.1代码实现
package it.cn.store.user.web.servlet;import java.io.IOException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/**为了提高扩展性,通过反射调用*/public class UserServletDemo1 extends HttpServlet {private static final long serialVersionUID = 1L;public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//接收数据,封装实体String methodName = request.getParameter("methodName");//1.获取当前类的全类名---获取这个类Class clazz = this.getClass();try {//2.反射获得方法Method method = clazz.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);//3.反射调用method.invoke(this, request,response);} catch (Exception e) {e.printStackTrace();}//调用Service对象,操作//数据回显}//注销public void logout(HttpServletRequest request, HttpServletResponse response) {System.out.println("执行注销操作,全体都有");}//登录public void login(HttpServletRequest request, HttpServletResponse response) {System.out.println("登录程序准备启动,一级准备");}//注册public void register(HttpServletRequest request, HttpServletResponse response) {System.out.println("注册程序开始启动,请准备好~~~~爆炸~~");}}
1.3.2思路分析
- 根据不同功能创建不同方法
- 获取用户前端输入方法名称methodName
- 获取当前类的全类名
- 根据methodName获取反射
- 反射调用实现功能
- 测试调用
1.3.3细节分析
- 功能实现:
- 通过反射的方式实现功能选择
- 优缺点:
- 优点:通过反射调用,会根据传入的方法名自动调用响应的方法,提高扩展性
- 缺点:
- 反射等内容还是存放在Servlet中,对于整个Servlet体系没有通用性
- 要进行回显等操作,还会存在return遗漏等问题,程序设计不够优化
- 编写注意事项:
- 通过反射获得方法中,两个参数:
- 第一个:methodName,传入需要调用的方法名(举例:login)
- 第二个:paramClass,传入参数类型的.class形式(举例:HttpServletRequest.class)
- 反射调用方法:
- 第一个:方法所在对象:本例中:this,代表当前类
- 第二个:与反射定义方法中class类对应的对象
- 反射调用中规定:
- clazz.getMethod() //仅获得被public修饰方法
- clazz.getDeclaredMethods() //可以反射获得所有权限修饰符的方法(public protected default private)
- 通过反射获得方法中,两个参数:
1.4 版本3:通过抽取工具类实现
1.4.1代码实现
- 工具类:BasicServlet
package it.cn.store.user.utils;import java.io.IOException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class BasicServlet extends HttpServlet{private static final long serialVersionUID = 1L;/*** 重写HttpServlet中重载的Servlet方法*/@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//接收数据,封装实体String methodName = request.getParameter("methodName");//1.获取当前类的全类名---获取这个类Class clazz = this.getClass();try {//2.反射获得方法Method method = clazz.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);//3.反射调用String path = (String) method.invoke(this, request,response);//信息回显if(path!=null && !"".equals(path)){//程序员想要请求转发request.getRequestDispatcher(path).forward(request, response);return;}} catch (Exception e) {e.printStackTrace();}}}
- 原始Servlet extends BasicSerlvet
package it.cn.store.user.web.servlet;import java.io.IOException;import java.lang.reflect.Method;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import it.cn.store.user.utils.BasicServlet;/**为了提高扩展性,通过反射调用*/public class UserServletDemo1 extends BasicServlet {private static final long serialVersionUID = 1L;public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//接收数据,封装实体//调用Service对象,操作//数据回显}//注销public void logout(HttpServletRequest request, HttpServletResponse response) {System.out.println("执行注销操作,全体都有");}//登录public void login(HttpServletRequest request, HttpServletResponse response) {System.out.println("登录程序准备启动,一级准备");}//注册public void register(HttpServletRequest request, HttpServletResponse response) {System.out.println("注册程序开始启动,请准备好~~~~爆炸~~");}}
1.4.2思路分析
- BasicServlet
1.编写BasicServlet继承HttpServlet
2.重写HttpServlet中service重载方法(在Servlet生命周期中Service()一直运行)
- 为什么重写service重载方法:
- 因为重载方法已经将service中原本ServletRequest和ServletResponse参数转换成了HttpServletRequest和ServletResponse
- 重写service不就不会判断父类中service对应的get和post请求了:
- 已经不需要在意是get和post方法了
4.回显数据(莫忘return)
- Servlet
2.加入空参构造(也可以不写,系统默认添加)
2.在Servlet只要关注(编写)功能即可
1.4.3实现过程
1.浏览器输入网址,向服务器发出请求
2.服务器接收请求,进行url-pattern匹配,先匹配Filter,再匹配servlet
3.匹配到相应的MyServlet,调用MyServlet中service方法
- 发现原始Servlet中没有执行service()方法,去父类中找
- 在BasicServlet没有执行service()方法,还是要去父类中找(有重写,但是没有执行)
- 父类HttpServlet 中的service方法执行,把request和response对象进行强转,调用重载的service方法。this.service(request,response)
- 由于调用Mysevlet中service方法,所以该this代表Myservlet,所以要找Myservlet中是否重写servcie方法,发现Myservlet中没重写,去父类中找
- 发现BasicServlet中重写了,就执行其中代码
4.执行service()中反射部分,invoke(this,request,response)对应功能方法methodName
- 理解invoke中this,由于我们调用时候Myservlet所以该this代表就是Myservlet
6.获取返回值并进行回显操作
1.4.4细节分析
- 功能实现:
- 通过抽取工具类重写service方法+反射实现功能选择
- 优缺点:
- 优点:
- 抽取工具类,通用性和维护性提高
- 通过反射调用,会根据传入的方法名自动调用响应的方法,提高扩展性
- 在servlet中只要关注功能编写,结构太美!
- 缺点:
- 暂无
- 优点:
- 编写注意事项:
- 在BasicServlet中重写service()方法是根据servlet生命周期每次调用都会执行service()方法
- 可以都不用写空参构造,系统会自动添加,这样就会寻找父类
- 但是不能写了空参构造,不写super(),那就没法寻找父类了
616

被折叠的 条评论
为什么被折叠?



