利用反射实现一个servlet处理多个请求

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

在学习servlet时会面临一个问题,一个servlet文件只能处理一个请求,针对一个用户的CURD操作,就需要创建许多servlet,看着项目文件目录树,感觉不是很清爽,所以想让一个servlet可以处理多个请求。

当然实现这个需求的方式很多,我讲解的是利用反射来实现。

先上代码

  • 使用反射的类

    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    
    public class ForumBaseServlet extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            StringBuffer url = req.getRequestURL();
            int i = url.lastIndexOf("/");
            String methodName = url.substring(i + 1);
            System.out.println(methodName);
            Class<? extends ForumBaseServlet> aClass = this.getClass();
    
            try {
                Method method = aClass.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
                method.invoke(this,req,resp);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    
  • 实现CRUD方法的类

    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.zgx.servlet_day05.entity.ForumUser;
    import com.zgx.servlet_day05.entity.Message;
    import com.zgx.servlet_day05.entity.User;
    import com.zgx.servlet_day05.service.impl.ForumUserServiceImpl;
    import com.zgx.servlet_day05.service.impl.UserServiceImpl;
    import com.zgx.servlet_day05.utils.MsgUtils;
    
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.util.ArrayList;
    
    /**
     * @Description:
     * @ClassName:Servlet02
     * @Author:。。。。
     * @CreateDate:2022-08-11 13:33:47
     **/
    @WebServlet(name = "ForumBaseServlet", value = "/forumuser/*")
    public class ForumServlet extends ForumBaseServlet{
    
        public void queryAll(HttpServletRequest request, HttpServletResponse response) throws IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            //接受参数
            int limit = Integer.parseInt(request.getParameter("limit"));
            int page = Integer.parseInt(request.getParameter("page"));
            String username = request.getParameter("username");
            String name = request.getParameter("name");
            int startIndex = page * limit - limit;
            System.out.println("page=" + page + ",limit=" + limit + ",index=" + startIndex);
            ForumUserServiceImpl service = new ForumUserServiceImpl();
            //查询总数
            ArrayList<ForumUser> users1 = service.queryAll();
            if(username == null && name ==null){
                ArrayList<ForumUser> users2 = service.queryAllLimit(startIndex, limit);
                String msg = MsgUtils.getTabMsg(0, users2.size() > 0 ? "查询成功" : "查询失败", users1.size(), users2);
                response.getWriter().write(msg);
            }else {
                ForumUser forumUser = new ForumUser();
                forumUser.setUser_name(username);
                forumUser.setName(name);
                ArrayList<ForumUser> users = service.queryAllLike(startIndex,limit,forumUser);
                String msg = MsgUtils.getTabMsg(0, users.size() > 0 ? "查询成功" : "查询失败", users.size(), users);
                response.getWriter().write(msg);
            }
        }
    }
    
    

分析

  • 继承关系
    在这里插入图片描述

  • 原理:因为ForumServlet继承了ForumBaseServlet并配置了映射到该类(ForumServlet),而ForumBaseServlet继承HttpServlet并重写了其中的service()

    那么请求就会先到达ForumServlet类,寻找可以处理请求的方法,如doGet()/doPost()方法,而service()不分请求方式,而当前类没有找到对应方法,但父类中有,就调用父类中的service()

    在父类ForumBaseServlet中先处理URL地址,获取方法名(所以前端传递的URL地址中要包含方法名,如user/queryAll),通过this.getClass()获取反射对象,再通过URL地址中获得的方法名,得到一个Method对象,通过invoke(this,方法参数1,方法参数2)调用方法。

  • this解释:在ForumBaseServlet中使用到了this,代表的含义是谁调用该方法,this就该表谁。因为是在ForumServlet中配置的映射关系,所以请求先到它,然后再调用父类的service(),因此this代表的就是子类ForumServlet
    在这里插入图片描述

注意:配置映射关系的时候,最后面记得是/*,比如/user/*,处理所有有关user的请求。

总结:

该方法对比传统通过传参(传递方法名),每次都要获取对应参数,然后判断传递过来的是哪个方法对应的字符串。

而反射形式只需要写一个继承HttpServlet并重写service(),在里面写通过反射调用方法的代码,就不用管了,只需要在继承该类的子类中写各种CRUD方法就行了。

当然在没有使用框架的阶段可以使用,使用了框架就不用这么麻烦了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值