SpringMVC 处理器映射器
MVC是项目中较常使用的web框架,作为开发人员,习惯了编写Controller作为项目开始,写好了Controller和对应的方法,加上@RequestMapping注解,我们也就认为一切已经准备就绪,可以开始运行了,那是否我们曾想过MVC是如何根据请求路径找到对应的Controller和Controller中具体的Method呢?
HandlerMapping
1.SimpleUrlHandlerMapping
2.BeanNameUrlHandlerMapping
3.RequestMappingHandlerMapping
HandlerMapping就是处理请求path和具体handler映射关系的组件,我们将从最基础SimpleUrlHandlerMapping到目前MVC中默认优先使用使用的RequestMappingHandlerMapping来进行讲解,首先应该在web.xml中配置DispatcherServlet这个基础的servlet,每次DispatcherServlet会加载对应配置文件。
1.SimpleUrlHandlerMapping
bean 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="simpleController" class="com.jiuyue.springmvc.controller.SimUrlController"></bean>
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/simple">simpleController</prop>
</props>
</property>
</bean>
</beans>
Controller代码实现mvc.Controller接口
public class SimUrlController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
PrintWriter writer = response.getWriter();
writer.print("test simple");
return null;
}
}
运行结果
请求:http://localhost:8080/simple
浏览器输打印输出 test simple
2.BeanNameUrlHandlerMapping
bean 配置(/beanNameUrlController必须要带"/")
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="/beanNameUrlController" class="com.jiuyue.controller.BeanNameUrlController"></bean>
<bean id="beanNameUrlHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
</beans>
Controllerd代码实现mvc.Controller接口
public class BeanNameUrlController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
PrintWriter writer = response.getWriter();
writer.print("test beanNameUrl");
return null;
}
}
运行结果
请求:http://localhost:8080/beanNameUrlController
浏览器输打印输出 test test beanNameUrl
3.RequestMappingHandlerMapping
bean 配置
<bean id="controller" class="com.jiuyue.controller.RequestMappingController"></bean>
<bean id="requestMappingHandlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
Controller 代码,不需要像上面一样实现Controller接口,这里使用@Controller注解声明这是一个Controller,然后在sprinng.xml配置文件中将这个类注册成bean。
@Controller
public class RequestMappingController {
@RequestMapping(value = "/login")
@ResponseBody
public String login(){
return "test requestMapping";
}
}
运行结果
请求:http://localhost:8080/login
浏览器打印输出输出:test requestMapping
注意:一般现在我们将一些Controller类,Service类注册成bean,我们使用的是包扫描的方式,如下面注释的<context:component-scan base-package=""
<bean id="controller" class="com.jiuyue.controller.RequestMappingController"></bean>
<!--<context:component-scan base-package="com.jiuyue.controller"/>-->
<bean id="requestMappingHandlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
总结:
- SimpleUrlHandlerMapping 是根据其mappings属性中配置的key-value来定义映射关系的,根据请求path【作为映射关系中的key】,找到对应的Controller【此时只要找到Controller就可以了,不用到具体方法,因为自定义的Controller必须继承Controller接口,并实现handleRequest方法,最后也是执行handleRequest方法】
- BeanNameUrlHandlerMapping 是根据spring容器中配置的bean名称【注意bean的名称需要以'/'开头】和Controller来定义映射关系的, 根据请求路径path去查找beanName和path一致的bean【其中bean必须继承Controller并实现handleRequest方法】,然后调用handleRequest来处理请求。
- RequestMappingHandlerMapping 是依赖注解RequestMapping来实现path和Hander的映射关系的,具体是根据注解中的value值作为key,注解所在方法作为Handler设置映射关系,然后请求到达时则根据请求path去查找对应的Handler【具体Controller中的Method】。