一个Servlet处理多个请求

510 阅读2分钟

使用一个Servlet来处理所有请求

问题

在开发 JavaWeb 应用中,编写 Servlet 是一个必不可少的环节,但是一般情况下都是一个 Servlet 处理一个特定请求。一旦编写的 Servlet 越来越多,那么管理 Servlet 就会越来越麻烦了。

所以应该如何减少 Servlet 的数量呢?只需要一个 Servlet 来分发请求,将请求交给不同的方法来进行处理。但是方法都堆在一个类中那么也是很难管理,所以每一个类代表一个模块,每个模块下都有特定的方法来处理不同的请求。

方案

那么解决方案就是使用一个 Servlet 来处理所有请求,将请求分发到对应的类中再执行指定方法。

实现

接下来就是方案的实现,应该如何将请求转发到指定的方法呢?类与方法,可以想到使用反射的方式来实现,而前端与后端的交流大部分都在 URI 中。所以只要在 URI 中获取到类与方法名称即可处理指定请求了。通过结合 Spring ,使用 IOC 容器来获取到相应的实例。

代码

@WebServlet(urlPatterns = "*.do",name = "MyDispatcherServlet")
public class MyDispatcherServlet extends HttpServlet {

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

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        ApplicationContext context = WebApplicationContextUtils
                .getWebApplicationContext(this.getServletContext());

        String requestURI = req.getRequestURI();
        requestURI = requestURI.substring(0, requestURI.indexOf(".do"));
        System.out.println(requestURI);
        ///myServlet/course/test.do"

        //将 URI 分解成一个数组
        //例如URI=/myServlet/course/test---->["","myServlet","course","test"]
        //split[0]与split[1]是固定的,split[2]代表着需要的实例,split[3]则是实例中要执行的方法
        String[] split = requestURI.split("/");


        //从 IOC 容器中获取实例
        Object bean = context.getBean(split[2]);
        //获取类对象
        Class<?> aClass = bean.getClass();
        try {
            //使用反射获取到类对象的指定方法
            Method method = aClass.getMethod(split[3], HttpServletRequest.class, HttpServletResponse.class);
            //执行实例中指定方法
            method.invoke(bean, req, resp);

        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

以上就就是只使用一个 Servlet 来处理请求的实现 demo 了