欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

BaseServlet的应用原理

程序员文章站 2022-05-08 13:16:07
...

BaseServlet的应用原理

BaseServlet可以根据method参数通过反射调用相应的方法,然后根据方法产生的结果判断转发或者重定向到相应页面。
结合web.xml 和 和测试用TestServlet说明继承BaseServlet后请求的处理。

http://localhost:8080/MyCrm/testServlet?method=queryUser
请求必须带有一个method的参数,如果是表单提交的话,可以增加一个input标签设置为隐藏的模式,并附带一个method参数。method的value值为继承了BaseServlet的Servlet中要调用的方法名。

 <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>servlet.TestServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/testServlet</url-pattern>
    </servlet-mapping>

请求被拦截会寻找一个servlet包下的TestServlet类,如下。

public class TestServlet extends BaseServlet {
    public String queryUser(HttpServletRequest request, HttpServletResponse response){
        String name = "东西";
        //存到request域
        request.setAttribute("name",name);
        return "/test.jsp";
    }
}

请求会被service方法处理,TestServlet没有次方法,但是他的父类BaseServlet重写了service方法所以会执行下面的service方法。让我们看看他怎么处理的。

public class BaseServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String methodName = request.getParameter("method");
        //获得method的value值,就是要执行的方法的名字,这里获得的值为queryUser。所以上面说需要method参数。
        Method method = null;
        try {
        //根据方法名,参数的class反射获得方法(Method类)
            method = this.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
        //如果没有这个方法就抛出RuntimeException。
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("您要调用的方法:" + methodName + "它不存在!");
        }

        try {
        //反射执行方法,这里执行名为queryUse的方法返回的result为“/test.jsp”
            String result = (String)method.invoke(this, request, response);
            //判断执行结果是否包含":",结合下面可以知道,继承BaseServlet处理请求的方法转发和重定向页面是有固定格式的。
            //转发为f:或者没有前缀+"/xxx.jsp"
            //重定向为r:+"/xxx.jsp"
            if (result != null && !result.trim().isEmpty()) {
                int index = result.indexOf(":");
               //如果没有":"就转发到相应页面     
                if (index == -1) {
                    request.getRequestDispatcher(result).forward(request, response);
                } else {
                    String start = result.substring(0, index);
                    String path = result.substring(index + 1);
                    //"f:"开头就转发到相应页面
                    if (start.equals("f")) {
                        request.getRequestDispatcher(path).forward(request, response);
                        //"r:"开头就重定向到相应页面
                    } else if (start.equals("r")) {
                        response.sendRedirect(request.getContextPath() + path);
                    }
                }
            }

        } catch (Exception var9) {
            throw new RuntimeException(var9);
        }
    }
}

经过上面的处理就会转发到test.jsp页面。

<html>
<head>
    <title>test</title>
</head>
<body>
        ${requestScope.name}
        <%--获得request域的name--%>
        <%--页面会显示TestServlet存的“东西”--%>
</body>
</html>