SpringMVC请求过程设计思路

在我们使用tomcat时, 通常会继承HttpServlet, 然后重写里面的doGet和doPost方法, 然后在web.xml配置请求路径与servlet处理类的映射

示例一:

public class AddItemServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ...
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
 <servlet>
    <description></description>
    <display-name>AddItemServlet</display-name>
    <servlet-name>AddItemServlet</servlet-name>
    <servlet-class>com.bookstore.web.servlet.AddItemServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>AddItemServlet</servlet-name>
    <url-pattern>/addItem</url-pattern>
  </servlet-mapping>

对于这种方式去处理请求, 每处理一个请求, 都需要编写对应的Servlet来处理;

请求路径示例:

添加商品,移除商品请求:

        http://localhost:8080/bookStore/addItem

        http://localhost:8080/bookStore/removeItem

登录, 注册请求:

        http://localhost:8080/bookStore/loginUser

        http://localhost:8080/bookStore/registerUser

逻辑如图:


但是, 这样有很大的局限性, 不利于扩展; 那么, 可以这样设计, 我们可以编写一个基础Servlet实现类, 继承HttpServlet, 重写service()方法, 在该方法中, 我们可以根据请求信息中需要请求的方法参数获取对应的处理方法, 然后利用反射执行即可;

实例二:

public class BaseServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
        //1.获取子类,创建子类或者调用子类的时候this代表的是子类对象
        Class clazz = this.getClass();
        //2.获取请求的方法
        String m = request.getParameter("method");
        if(m==null){
            m="index";
        }
        //3.获取方法对象
        Method method = clazz.getMethod(m, HttpServletRequest.class,HttpServletResponse.class);
        
        //4.让方法执行,返回值为请求转发的路径
        String s = (String) method.invoke(this, request,response);    //相当于 userservlet.add(request,response)
        
        //5.判断s是否为空
        if(s!=null){
            request.getRequestDispatcher(s).forward(request, response);
        }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        } 
        
    }
    //如果m为空,m被赋值为"index",所以为保证程序正常执行, 即clazz.getMethod(...)正常执行,需要index()方法存在.
    //在index方法中访问服务器/indexServlet查询所有首页需要的商品信息,并返回跳转路径:"/jsp/index.jsp"
    public String index(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        return null;
    }
}
public class AdminCategoryServlet extends BaseServlet {

    public String findAllCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ...
    }
    public String editCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ...
    }
    public String addCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ...
    }
}

这样, 对比示例一中的处理方式: 处理每一个请求都必须编写一个Servlet的实现类, 示例二有了一定的扩展性: 可以在一个Servlet实现类中处理多个请求信息, 只要我们在一个Servlet实现类中编写对应的处理方法即可;  

请求路径示例:

添加商品,移除商品请求:

        http://localhost:8080/bookStore/book?method=addItem

        http://localhost:8080/bookStore/book?method=removeItem

登录, 注册请求:

        http://localhost:8080/bookStore/user?method=login

        http://localhost:8080/bookStore/user?method=register

逻辑如图:

 


但是, 这样设计并也需要配置不同的Servlet映射, 比如商品信息请求和用户登录信息请求的GoodsServlet和UserServlet, 在开发过程中随时都有可能需要添加信息的请求信息, 这样硬编码灵活性很差, 但是优点是示例2把请求处理从类级别缩小到方法级别了,  

因此, 我们需要扬长避短, 对于需要硬编码的Servlet处理类, 我们可以编写一个UserController类来处理用户的登录信息; 一个GoodsController类来处理商品信息;  然后在一个Map集合中配置请求路径与对应处理方法的映射,  我们可以对示例二的BaseServlet进行改造, 在新的基础Servlet(DispatcherServlet)中, 根据请求信息解析到需要调用的处理类, 然后在Map集合中获取到该请求信息映射的处理方法, 然后通过反射去执行该处理器类中对应的处理方法对请求进行处理, 并根据处理方法返回的视图信息, 进行解析;

请求路径示例:

添加商品,移除商品请求:

        http://localhost:8080/bookStore/book/addItem

        http://localhost:8080/bookStore/book/removeItem

登录, 注册请求:

        http://localhost:8080/bookStore/user/login

        http://localhost:8080/bookStore/user/register

逻辑如图:

处理逻辑:

  1. 根据请求信息获取对应的处理方法
  2. 执行处理方法, 对请求进行处理
  3. 对处理方法执行完成后返回的视图信息进行解析

有没有发现这个过程很熟悉....

这就是SpringMVC的设计思想, 这也就是为什么SpringMVC中只定义了一个Servlet也可以处理大量不同的请求信息;

以上分析过程是我的个人理解, 如果有不对的地方, 欢迎指出, 共同进步!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值