栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

学习记录02——使用原生servlet处理请求时出现的大量servlet

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

学习记录02——使用原生servlet处理请求时出现的大量servlet

最近在复习servlet,发现用原生servlet处理请求时,一个servlet只能处理一个请求,有多个业务时只能写很多个servlet,虽然springmvc等框架都可以解决这个问题,而且实际开发也不会有人用原生servlet处理请求,但是还是想尝试自己写一个简单的工具解决这一麻烦。先回顾下原生servlet处理一个请求:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("loginServlet");
    }
}

然而,一个Controller会有很多业务,如userController里就有login、register、loginByWX(微信扫码登陆)、checkEmail(查看邮箱是否可用)、checkUsername(查看用户名是否可用)等,加上其他controller的话servlet就要写上百个,显然是不可行的,所以我想能不能通过规范请求的url,让我后端知道该请求应该去到哪里,比如说/user/login.do就是要去userController这个类中去调用login()方法,于是我写了一个类,就叫DispatcherServlet(分发器),让他在service方法中截取url获得两个东西:我要调用哪个方法和这个方法在哪个类里:

@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet {
 @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //为所有

@WebServlet("*.do")
public class DispatcherServlet extends HttpServlet {

    private static Map requestMapping = new HashMap<>();

    //以下静态代码块仅运行一次,在此类被加载时(第一次收到*.do请求时),根据applicationContext.xml的配置初始化uri和controller的映射关系
    static {
        try {
            InputStream is = DispatcherServlet.class.getClassLoader().getResourceAsStream("applicationContext.xml");
            //解析xml文件
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document dom = documentBuilder.parse(is);
            //或者中的内容拿出来,封装成com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl对象
            NodeList bean = dom.getElementsByTagName("bean");

            for (int i = 0; i < bean.getLength(); i++) {
                Node node = bean.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE){
                    Element element = (Element) node;
                    String id = element.getAttribute("id");
                    String className = element.getAttribute("class");
                    Object o = Class.forName(className).getDeclaredConstructor().newInstance();
                    requestMapping.put(id,o);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


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

        //为所有/*.do的请求设置编码集
        req.setCharacterEncoding("utf8");

        String uri = req.getRequestURI();
        //uri统一格式为:/controller/operation.do,拿到要执行的方法名
        int startIndex = uri.lastIndexOf("/")+1;
        int endIndex = uri.indexOf(".");
        //拿到要调用的方法名
        String operation = uri.substring(startIndex,endIndex);

        //拿到controller的名字
        String beanName = uri.substring(uri.indexOf("/")+1,uri.lastIndexOf("/"));

        //在加载此类时已根据在applicationContext.xml中配置的信息将所有controller创建实例,现在根据uri,找到容器中对应的controller实例
        Object controllerBean = requestMapping.get(beanName);
        //拿到实例后,根据uri找到需要调用的方法名,通过反射找到此方法并调用
        try {
            Method methodToInvoke = controllerBean.getClass().getDeclaredMethod(operation, HttpServletRequest.class, HttpServletResponse.class);
            methodToInvoke.setAccessible(true);
            methodToInvoke.invoke(controllerBean,req,resp);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

算是一个乞丐版SpringMVC吧

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/949281.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号