封装Servlet工具类

封装Servlet工具类

一.封装过程

1.1 封装前
1.1.1为何要封装Servlet
  • 在编写Servlet程序时我们发现,为了对应前端jsp不同的功能,我们需要相应的创建的多个Servlet:
    • 登录功能:LoginServlet
    • 注册功能:RegisterServlet
    • 增加功能:AddServlet
    • 注销功能:LogoutServlet
              .....
  • 如果如上创建多个Servlet,不仅导致整个项目Servlet过多,名称难起,代码重复过多,所以我们考虑对应一个整体模块使用一个Servlet,通过判断不同的功能跳转到不同方法中去实现
1.2 版本1:通过if判断方法实现
1.2.1代码实现
   
   
  1. package it.cn.store.user.web.servlet;
  2. import java.io.IOException;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.http.HttpServlet;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. /**
  8. * Servlet implementation class UserServlet
  9. */
  10. public class UserServlet extends HttpServlet {
  11. private static final long serialVersionUID = 1L;
  12. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  13. doPost(request, response);
  14. }
  15. public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  16. //接收数据,封装实体
  17. String methodName = request.getParameter("methodName");
  18. if("register".equalsIgnoreCase(methodName)){
  19. register(request,response);
  20. }else if ("login".equalsIgnoreCase(methodName)) {
  21. login(request,response);
  22. }else if ("logout".equalsIgnoreCase(methodName)) {
  23. logout(request,response);
  24. }else {
  25. System.out.println("未知错误,系统即将自爆!!!!!");
  26. }
  27. //调用Service对象,操作
  28. //数据回显
  29. }
  30. //注销
  31. public void logout(HttpServletRequest request, HttpServletResponse response) {
  32. System.out.println("执行注销操作,全体都有");
  33. }
  34. //登录
  35. public void login(HttpServletRequest request, HttpServletResponse response) {
  36. System.out.println("登录程序准备启动,一级准备");
  37. }
  38. //注册
  39. public void register(HttpServletRequest request, HttpServletResponse response) {
  40. System.out.println("注册程序开始启动,请准备好~~~~爆炸~~");
  41. }
  42. }

1.2.2思路分析
  1. 创建不同功能对应的不同方法
  2. 获取用户前端输入方法名称methodName
  3. 根据方法名进行if判断
  4. 测试结果
- - - - - - - - - - - - - - - - - - - - - - - - - - - 
1.2.3细节分析
  • 功能实现:
    • 通过if判断实现不同的mentodName调用不同的方法
  • 优缺点:
    • 优点:实现了一个Servlet中多个功能
    • 缺点:扩展性差:每次添加一个功能,就要一个if去对应
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1.3 版本2:通过反射调用实现
1.3.1代码实现
   
   
  1. package it.cn.store.user.web.servlet;
  2. import java.io.IOException;
  3. import java.lang.reflect.Method;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. /**
  9. 为了提高扩展性,通过反射调用
  10. */
  11. public class UserServletDemo1 extends HttpServlet {
  12. private static final long serialVersionUID = 1L;
  13. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  14. doPost(request, response);
  15. }
  16. public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  17. //接收数据,封装实体
  18. String methodName = request.getParameter("methodName");
  19. //1.获取当前类的全类名---获取这个类
  20. Class clazz = this.getClass();
  21. try {
  22. //2.反射获得方法
  23. Method method = clazz.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
  24. //3.反射调用
  25. method.invoke(this, request,response);
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. }
  29. //调用Service对象,操作
  30. //数据回显
  31. }
  32. //注销
  33. public void logout(HttpServletRequest request, HttpServletResponse response) {
  34. System.out.println("执行注销操作,全体都有");
  35. }
  36. //登录
  37. public void login(HttpServletRequest request, HttpServletResponse response) {
  38. System.out.println("登录程序准备启动,一级准备");
  39. }
  40. //注册
  41. public void register(HttpServletRequest request, HttpServletResponse response) {
  42. System.out.println("注册程序开始启动,请准备好~~~~爆炸~~");
  43. }
  44. }

1.3.2思路分析
  1. 根据不同功能创建不同方法
  2. 获取用户前端输入方法名称methodName
  3. 获取当前类的全类名
  4. 根据methodName获取反射
  5. 反射调用实现功能
  6. 测试调用

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
   
   
  1. package it.cn.store.user.utils;
  2. import java.io.IOException;
  3. import java.lang.reflect.Method;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. public class BasicServlet extends HttpServlet{
  9. private static final long serialVersionUID = 1L;
  10. /**
  11. * 重写HttpServlet中重载的Servlet方法
  12. */
  13. @Override
  14. protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. //接收数据,封装实体
  16. String methodName = request.getParameter("methodName");
  17. //1.获取当前类的全类名---获取这个类
  18. Class clazz = this.getClass();
  19. try {
  20. //2.反射获得方法
  21. Method method = clazz.getMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
  22. //3.反射调用
  23. String path = (String) method.invoke(this, request,response);
  24. //信息回显
  25. if(path!=null && !"".equals(path)){
  26. //程序员想要请求转发
  27. request.getRequestDispatcher(path).forward(request, response);
  28. return;
  29. }
  30. } catch (Exception e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. }
  • 原始Servlet extends BasicSerlvet
    
    
  1. package it.cn.store.user.web.servlet;
  2. import java.io.IOException;
  3. import java.lang.reflect.Method;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import it.cn.store.user.utils.BasicServlet;
  9. /**
  10. 为了提高扩展性,通过反射调用
  11. */
  12. public class UserServletDemo1 extends BasicServlet {
  13. private static final long serialVersionUID = 1L;
  14. public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  15. doPost(request, response);
  16. }
  17. public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  18. //接收数据,封装实体
  19. //调用Service对象,操作
  20. //数据回显
  21. }
  22. //注销
  23. public void logout(HttpServletRequest request, HttpServletResponse response) {
  24. System.out.println("执行注销操作,全体都有");
  25. }
  26. //登录
  27. public void login(HttpServletRequest request, HttpServletResponse response) {
  28. System.out.println("登录程序准备启动,一级准备");
  29. }
  30. //注册
  31. public void register(HttpServletRequest request, HttpServletResponse response) {
  32. System.out.println("注册程序开始启动,请准备好~~~~爆炸~~");
  33. }
  34. }

1.4.2思路分析
  • BasicServlet
    1.编写BasicServlet继承HttpServlet
   2. 重写HttpServlet中service重载方法 (在Servlet生命周期中Service()一直运行)
  • 为什么重写service重载方法:    
    • 因为重载方法已经将service中原本ServletRequest和ServletResponse参数转换成了HttpServletRequest和ServletResponse
  • 重写service不就不会判断父类中service对应的get和post请求了:
    • 已经不需要在意是get和post方法了
    3.在service中实现反射调用方法
    4.回显数据(莫忘return)

  • Servlet
    1.Servlet继承BasicServlet
    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
    5.在Myservlet中寻找methodName对应的功能方法并执行
    6.获取返回值并进行回显操作

1.4.4细节分析
  • 功能实现:
    • 通过抽取工具类重写service方法+反射实现功能选择
  • 优缺点:
    • 优点:
      • 抽取工具类,通用性和维护性提高
      • 通过反射调用,会根据传入的方法名自动调用响应的方法,提高扩展性
      • 在servlet中只要关注功能编写,结构太美!
    • 缺点:
      • 暂无
  • 编写注意事项:
    • 在BasicServlet中重写service()方法是根据servlet生命周期每次调用都会执行service()方法
    • 可以都不用写空参构造,系统会自动添加,这样就会寻找父类
      • 但是不能写了空参构造,不写super(),那就没法寻找父类了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值