冗余servlet处理技巧以及servlet工具类封装

应用场景: 如果一个servlet对应一个功能,那么我们 要做一个 学生 的 增删改查 需要写 5 个 servlet来处理。可能只有几个功能却要写 几十个servlet。非常麻烦。

1、冗余servlet合并思路
  • 我们在前端请求的路径中加上想要请求的方法。例如: "/testServlet?method=addStu"
  • 我们在后台根据 传递过来的 method 来寻找对应的处理逻辑
  • method 传递过来的参数不同,我们处理逻辑也不同
示例
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class BaseServlet extends javax.servlet.http.HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取客户端提交到服务端的method对应的值
        String md=request.getParameter("method");
        //定义变量,存放功能执行完毕之后要转发的路径
        String path=null;

        //通过判断md中不同的内容来决定本次功能
        if("addStu".equals(md)){
            path=addStu(request, response);
        }else if("delStu".equals(md)){
            path=delStu(request, response);
        }else if("checkStu".equals(md)){
            path=checkStu(request, response);
        }else if("".equals(md)){

        }

        if(null!=path){
            //服务端的转发
            request.getRequestDispatcher(path).forward(request, response);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }

    public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("添加学生");
        return "/test.html";
    }
    public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("删除学生");
        return "/test.html";
    }
    public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("检查学生");
        response.getWriter().println("DDDDDD");
        return null;
    }
}


这样我们就在一个servlet中处理了 增加 删除 和 检查学生的逻辑

2、问题及改善(利用反射)

如果学生模块的方法特别多,有几十个,那么我们要写 几十个 if else 条件判断,代码重复,并且比较繁琐

解决思路
  • 获取前台传递的参数,得知要调用的方法
  • 利用反射获取该servlet类的对象
  • 检查该对象有没有这个方法
  • 有的话就调用,没有的话不调用
代码示例
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public class BaseServlet extends javax.servlet.http.HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取客户端提交到服务端的method对应的值
        String md=request.getParameter("method");
        //定义变量,存放功能执行完毕之后要转发的路径
        String path=null;

        //通过判断md中不同的内容来决定本次功能
       /* if("addStu".equals(md)){
            path=addStu(request, response);
        }else if("delStu".equals(md)){
            path=delStu(request, response);
        }else if("checkStu".equals(md)){
            path=checkStu(request, response);
        }else if("".equals(md)){

        }*/
        // 当前类的字节码对象(当前类在内存中的对象)
        Class clazz = this.getClass();
        // 获取clazz上的名称为 md 方法
        try {
            Method method = clazz.getMethod(md, HttpServletRequest.class, HttpServletResponse.class);
            if(null != method){
                path = (String)method.invoke(this, request, response);
            }
            if(null!=path){
                //服务端的转发
                request.getRequestDispatcher(path).forward(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }

    public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("添加学生");
        return "/test.html";
    }
    public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("删除学生");
        return "/test.html";
    }
    public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("检查学生");
        response.getWriter().println("DDDDDD");
        return null;
    }
}


代码说明:
判断的逻辑

  //通过判断md中不同的内容来决定本次功能
        if("addStu".equals(md)){
            path=addStu(request, response);
        }else if("delStu".equals(md)){
            path=delStu(request, response);
        }else if("checkStu".equals(md)){
            path=checkStu(request, response);
        }else if("".equals(md)){

        }

        if(null!=path){
            //服务端的转发
            request.getRequestDispatcher(path).forward(request, response);
        }

用简洁的反射代码替代

  // 当前类的字节码对象(当前类在内存中的对象)
        Class clazz = this.getClass();
        // 获取clazz上的名称为 md 方法
        try {
            Method method = clazz.getMethod(md, HttpServletRequest.class, HttpServletResponse.class);
            if(null != method){
                path = (String)method.invoke(this, request, response);
            }
            if(null!=path){
                //服务端的转发
                request.getRequestDispatcher(path).forward(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
3、多模块冗余优化

利用反射,我们可以应对某个servlet有很多方法的情况。但是如果我们有很多功能模块,几十个,几百个。那么我们的每一个servlet中都有如下这段代码。造成了代码冗余。

        //定义变量,存放功能执行完毕之后要转发的路径
        String path=null;

        // 当前类的字节码对象(当前类在内存中的对象)
        Class clazz = this.getClass();
        // 获取clazz上的名称为 md 方法
        try {
            Method method = clazz.getMethod(md, HttpServletRequest.class, HttpServletResponse.class);
            if(null != method){
                String invoke = (String)method.invoke(this, request, response);
            }
            if(null!=path){
                //服务端的转发
                request.getRequestDispatcher(path).forward(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

解决思路
  • 利用servlet的生命周期,我们把这段代码提取出来
  • servlet的生命周期为: init() service() destory()
  • 我们封装一个 父类 BaseServlet,在这个类中重写 service方法
  • 在service中把上面代码放进去
  • 并让以后所有的servlet类 继承该类即可
代码示例

BaseServlet.java (父类)

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public class BaseServlet extends javax.servlet.http.HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String md=request.getParameter("method");
        //定义变量,存放功能执行完毕之后要转发的路径
        String path=null;

        // 当前类的字节码对象(当前类在内存中的对象)
        Class clazz = this.getClass();
        // 获取clazz上的名称为 md 方法
        try {
            Method method = clazz.getMethod(md, HttpServletRequest.class, HttpServletResponse.class);
            if(null != method){
                String invoke = (String)method.invoke(this, request, response);
            }
            if(null!=path){
                //服务端的转发
                request.getRequestDispatcher(path).forward(request, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}


TestServlet.java (测试子类)

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public class TestServlet extends BaseServlet{

    public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("添加学生");
        return "/test.html";
    }
    public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("删除学生");
        return "/test.html";
    }
    public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("检查学生");
        response.getWriter().println("DDDDDD");
        return null;
    }

}

这样就把学生模块的功能分离出来了,以后每增加一个 功能模块 只需要 增加一个servlet 并继承 父类 BaseServlet即可。

欢迎留言讨论你的想法

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ITzhongzi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值