最近在研究DispatcherServlet源码,在看getHandler方法时,想着把三个常用的HandlerMapping都自己配置一下看看,在配置SimpleUrlHandlerMapping遇到了一些问题,因为这个SimpleUrlHandlerMapping好像比较老了,网上查到的资料都是基于web.xml配置的,我搭的测试框架springboot的,实在不想配置web.xml文件,就试着搞一下基于注解配置SimpleUrlHandlerMapping。ok,废话说了一堆,现在开始切入正题:
先来看一下web.xml的配置文件
<bean id="loginUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<!-- 第一种方法 -->
<property name="mappings">
<props>
<prop key="/base/login.htm">loginController</prop>
<prop key="/base/login.htm?method=doLogin">loginController</prop>
</props>
</property>
<!-- 第二种方法 -->
<property name="urlMap">
<map>
<entry key="/base/login.htm" value-ref="loginController"/>
</map>
</property>
<!-- 第三种方法 -->
<property name="mappings">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location">
<value>urlMap.properties</value> <!-- 此时urlMap.properties文件应放在WebRoot目录下! -->
</property>
</bean>
</property>
</bean>
<!--第四种-->
<bean id="rechargeNotifyParamResolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/app/gateway/recharge/ccb/notify.htm">index</prop>
</props>
</property>
</bean>
<bean id="rechargeNotifyController" class="com.ciispay.site.controller.gateway.RechargeNotifyController" parent="baseController">
<property name="methodNameResolver">
<ref bean="rechargeNotifyParamResolver" />
</property>
<property name= "rechargeAppService" ref= "rechargeAppService"/>
</bean>
<!--在父类org.springframework.web.servlet.mvc.multiaction.MultiActionController中有个set方法-->
public final void setMethodNameResolver(MethodNameResolver methodNameResolver) {
this.methodNameResolver = methodNameResolver;
}
可以看到,xml中也就是配置了一个bean,所以在java配置文件中也声明一个Bean就行了,源码:
package com.example.demo;
import com.example.demo.HandlerMappingTest.TestController2;
import com.example.demo.test_bean.TestBeanLife;
import com.example.demo.test_service.TestController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Administrator on 2019-08-15.
*/
@Configuration
public class MasterConfig {
@Autowired
private TestController2 testController2;
@Bean
public SimpleUrlHandlerMapping simpleUrlHandlerMapping(){
SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
Map map = new HashMap();
map.put("/abcde", testController2);//设置映射路径
simpleUrlHandlerMapping.setUrlMap(map);
simpleUrlHandlerMapping.setOrder(1);//重要,设置优先级
return simpleUrlHandlerMapping;
}
}
这里比较关键的地方是simpleUrlHandlerMapping.setOrder(1);一开始我设置完之后不起作用,打断点发现我自己的这个SimpleURLHandlerMapping的Bean位置比较靠后,在上面有一个系统的HandlerMapping,里面匹配了/**这个路径,也就是说后面所有路径都会被这个映射覆盖掉,如下图所示。自己写的那个HandlerMappingMapping默认的order值大于2147483646,就会被覆盖掉,所以要做的就是把order修改一下改成小于2147483646,这里我设置了order为1,这样就会先走我们自己写的HandlerMapping了。
最后是Handler的源码,就是一个简单的Controller
@Component
public class TestController2 implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView("index");
System.out.println("TestController!!!");
return modelAndView;
}
}