[华为云在线课程][SpringMVC入门][三][处理器映射器与处理器适配器][学习笔记]
【摘要】 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)