[华为云在线课程][SpringMVC入门][三][处理器映射器与处理器适配器][学习笔记]

举报
John2021 发表于 2022/07/17 22:42:02 2022/07/17
【摘要】 1.处理器映射器与处理器适配器 1.1.HandlerMappingHandlerMapping,处理器映射器,在SpringMVC中,系统提供了很多HandlerMappingHandlerMapping是负责根据request请求找到对应的Handler处理器及Interceptor拦截器,将它们封装在HandlerExecutionChain对象中返回给前端控制器。BeanNameU...

1.处理器映射器与处理器适配器

1.1.HandlerMapping

HandlerMapping,处理器映射器,在SpringMVC中,系统提供了很多HandlerMapping

HandlerMapping是负责根据request请求找到对应的Handler处理器及Interceptor拦截器,将它们封装在HandlerExecutionChain对象中返回给前端控制器。

  • BeanNameUrlHandlerMapping
    BeanNameUrl处理器映射器,根据请求的url与Spring容器中定义的bean的name进行匹配,从而从Spring容器中找到bean实例,就是说,请求的url地址就是处理器Bean的名字。
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" id="handlerMapping">
    <property name="beanName" value="/hello"/>
</bean>
  • SimpleUrlHandlerMapping
    SimpleUrlHandlerMapping是BeanNameUrlHandlerMapping的增强版本,可以将url和处理器bean的id进行统一映射配置
<!--首先配置一个MyController的实例-->
<bean class="org.example.controller.MyController" name="myController"/>
<bean class="org.example.controller.MyController2" name="myController2"/>
<!--配置处理器映射器,将前端请求和后端接口关联起来-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" id="handlerMapping">
    <property name="mappings">
        <props>
            <prop key="/hello">myController</prop>
            <prop key="/hello2">myController2</prop>
        </props>
    </property>
</bean>

注意,在props中,可以配置多个请求路径和处理器实例的映射关系。

1.2.HandlerAdapter

HandlerAdapter即处理器适配器。它会根据适配器接口对后端控制器进行适配,适配后即可对处理器进行执行,通过拓展处理器适配器可以执行多种类型的处理器,这里使用了适配器设计模式。
在SpringMVC中,HandlerAdapter也有诸多实现类:

  • SimpleControllerHandlerAdapter
    简单控制器处理器适配器,所有实现org.springframework.web.servlet.mvc.Controller接口的bean通过此适配器进行适配、执行,也就是说我们开发的接口是通过实现Controller接口来完成的(不是通过注解开发的接口),那么HandlerAdapter必须是SimpleControllerHandlerAdapter。
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" id="handlerAdapter"/>
  • HttpRequestHandlerAdapter
    HttpRequestHandlerAdapter即http请求处理器适配器,所有实现了org.springframework.web.HttpRequestHandler接口的bean通过此适配器进行匹配执行。
package org.example.controller;


import org.springframework.web.HttpRequestHandler;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@org.springframework.stereotype.Controller("/hello2")
public class MyController2 implements HttpRequestHandler {

    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("-----MyController2-----");
    }
}
<!--配置处理器映射器,将前端请求和后端接口关联起来-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" id="handlerMapping">
    <property name="mappings">
        <props>
            <prop key="/hello2">myController2</prop>
        </props>
    </property>
</bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" id="handlerAdapter"/>

1.3.最佳实践

  • 组件自动扫描
    web开发中,基本不再通过XML或者Java配置来创建一个Bean的实例,而是直接通过组件扫描来实现Bean的配置,如果要扫描多个包,多个包之间用,隔开即可:
<context:component-scan base-package="org.example"/>
  • HandlerMapping
    正常情况下,我们在项目中使用的是RequestMappingHandlerMapping,这个是根据处理器中的注解来匹配请求(即@RequestMapping注解中的url属性)。因为在上面我们都是通过实现类来开发接口的,相当于还是一个类一个接口,所以可以通过RequestMappingHandlerMapping来做处理器映射器,这样我们可以在一个类中开发出多个接口。
  • HandlerAdapter
    对于上面提到的通过@RequestMapping注解所定义出来的接口方法,这些方法的调用都要通过RequestMappingHandlerAdapter这个适配器来实现。
    比如我们开发一个接口:
package org.example.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class MyController3 {
    @RequestMapping("/hello3")
    public ModelAndView hello() {
        return new ModelAndView("hello3");
    }
}

要访问到这个接口需要用到RequestMappingHandlerMapping才能定位都需要执行的方法。需要RequestMappingHandlerAdapter才能执行定位到的方法,修改SpringMVC配置文件:

<context:component-scan base-package="org.example"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>

启动项目后,就可以访问/hello3接口并看到相应的页面了。

  • 继续优化
    在实际开发中,常用的RequestMappingHandlerMapping和RequestMappingHandlerAdapter有一个简写:
<mvc:annotation-driven/>

这个配置可以代替RequestMappingHandlerMapping和RequestMappingHandlerAdapter两行配置。下面的xml就是在实际开发中的最终配置。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <context:component-scan base-package="org.example.controller"/>
    <mvc:annotation-driven/>
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="viewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。