【Javaweb】通用Servlet类的创建

修改时间:2021年2月2日
作者:pp_x
邮箱:[email protected]

通用Servlet类

为什么要创建通用Servlet类

  • 由于有些项目模块功能过多,如果一个功能一个Servlet类来进行实现的话,需要的Servlet类过多,会占用服务器资源,服务器运行的会相对较慢,所以我们可以设置一个通用的Servlet类来优化

创建Servlet的通用类

  • 我们可以使一个模块对应一个Servlet类,前端请求的时候携带请求类型参数,Servlet类中用doget或者dopost进行接收来调用具体的实现方法
  • index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
    <%--  一个模块对应一个Servlet  --%>
    <a href="${pageContext.request.contextPath}/test?methodName=addCourse">新建课程</a>
    <a href="${pageContext.request.contextPath}/test?methodName=findByName">根据课程名查询</a>
    <a href="${pageContext.request.contextPath}/test?methodName=findByStatus">根据状态查询</a>
  </body>
</html>
  • TestServlet类
/**
 *  模拟课程模块 ,模块中有很多功能
 * */
@WebServlet("/test")
public class TestServlet extends HttpServlet {
    
    

    /**
     *  doGet()方法作为调度器 控制器,根据请求的功能不同,调用对应的方法
     *
     * */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

        //1.获取参数
        //获取要调用的方法名
        String methodName = req.getParameter("methodName");

        //2.业务处理
        //判断 执行对应的方法
        if("addCourse".equals(methodName)){
    
    
            addCourse(req,resp);

        }else if("findByStatus".equals(methodName)){
    
    
            findByName(req,resp);

        }else if("findByStatus".equals(methodName)){
    
    
            findByStatus(req,resp);

        }else{
    
    
            System.out.println("访问的功能不存在!");
        }

    }

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


    /**
     *  2.模块对应的功能部分
     * */
    public void addCourse(HttpServletRequest req, HttpServletResponse resp){
    
    
        System.out.println("新建课程");
    }

    public void findByStatus(HttpServletRequest req, HttpServletResponse resp){
    
    
        System.out.println("根据状态查询");
    }

    public void findByName(HttpServletRequest req, HttpServletResponse resp){
    
    
        System.out.println("根据课程名称查询");
    }

}

进一步优化Servlet类

  • 判断请求类型来调用具体方法的部分代码可扩展性相对较差,如果方法过多,就需要更多的判断语句,所以我们使用反射的方式去对该部分代码进行优化
  • 优化前
if("addCourse".equals(methodName)){
    
    
            addCourse(req,resp);

        }else if("findByStatus".equals(methodName)){
    
    
            findByName(req,resp);

        }else if("findByStatus".equals(methodName)){
    
    
            findByStatus(req,resp);

        }else{
    
    
            System.out.println("访问的功能不存在!");
        }
  • 反射优化步骤:
    1. 先获取请求携带的请求类型参数
    2. 获取指定类的字节码对象
    3. 根据请求携带的方法参数值,在通过字节码对象(class)获取指定的方法
    4. 执行指定的方法
  • 优化后
        try {
    
    
            //1.获取参数
            //获取要调用的方法名
            String methodName = req.getParameter("methodName");

            //2.业务处理
            if(methodName != null){
    
    
                //通过反射优化代码,提升代码的可维护性
                //1.获取字节码对象  this = TestServlet对象
                Class c = this.getClass();

                //2.根据传入的方法名, 获取对应方法对象,执行方法即可
                Method method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

                //3.调用Method对象的 invoke()方法,执行对应的功能
                method.invoke(this,req,resp);
            }
        } catch (Exception e) {
    
    
            System.out.println("请求的功能不存在! !");
            e.printStackTrace();
        }

抽取相同代码再进行优化

  • 虽然使用反射的方法来优化了判断类型部分的代码量,但是对于doPost和doGet部分,每一个模块的Servlet类都要进行重写,所以我们可以将doget和dopost方法重写后的代码进行提取,放入一个类中作为base类(此类继承HttpServlet类),后续的模块功能方法的Servlet类继承base类(相当于也是HttpServlet类的子类,也可以使用其方法)
  • baseServlet类
public class BaseServlet extends HttpServlet {
    
    

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    

        try {
    
    
            //1.获取参数
            //获取要调用的方法名
            String methodName = req.getParameter("methodName");

            //2.业务处理
            if(methodName != null){
    
    
                //通过反射优化代码,提升代码的可维护性
                //1.获取字节码对象  this = TestServlet对象
                Class c = this.getClass();//如果子类继承base类,那么反射的使具体的子类

                //2.根据传入的方法名, 获取对应方法对象,执行方法即可
                Method method = c.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);

                //3.调用Method对象的 invoke()方法,执行对应的功能
                method.invoke(this,req,resp);
            }
        } catch (Exception e) {
    
    
            System.out.println("请求的功能不存在! !");
            e.printStackTrace();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req,resp);
    }
}
  • 进行提取后的TestServlet类
@WebServlet("/test")
public class TestServlet extends BaseServlet {
    
    

    /**
     *  在模块对应的Servlet中只保留 业务相关代码
     *  当有请求访问到 TestServlet时, 发现没有doGet和doPost方法,就回去父类中找,从而执行BaseServlet中的
     *  doGet方法
     * */
    public void addCourse(HttpServletRequest req, HttpServletResponse resp){
    
    
        System.out.println("新建课程");
    }

    public void findByStatus(HttpServletRequest req, HttpServletResponse resp){
    
    
        System.out.println("根据状态查询");
    }

    public void findByName(HttpServletRequest req, HttpServletResponse resp){
    
    
        System.out.println("根据课程名称查询");
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_46303867/article/details/113698907