简述:
在上一篇文章中,我们学会了如何搭建一个简单SpringMvc HelloWorld程序,这篇文章主要是介绍一些常用的控制器,适配器学习和作用。
一、HandlerMapping处理器映射器
HandlerMapping 给前端控制器返回一个HandlerExecutionChain 对象(包含一个Handler (后端控制器)对象、多个HandlerInterceptor 拦截器)对象。
1).BeanNameUrlHandlerMapping Bean别名路径映射器
BeanNameUrl,通过类的命名名称我们是否发现了些什么?对,没错,就是通过配置bean的时候,bean的name作为访问其对应Controller的路径。一般可以和SimpleControllerHandlerAdapter配合使用,你如果把上一篇文章里面的例子自己写了遍的话,就会发现我们是用他们两个实现的。(源码中,就是实现了其父类AbstractDetectingUrlHandlerMapping
的determineUrlsForHandler方法,在方法中根据Bean Name注册处理器)
springmvc-servlet.xml 一般可以这么配置使用它:
<span style="white-space:pre"> </span><!-- 通过 /helloworld.action 可以访问到具体处理方法 --> <bean name="/helloworld.action" class="com.billstudy.springmvc.controller.HelloWorldController"/>
2).SimpleUrlHandlerMapping 简单路径处理映射器
SimpleUrl,这个是比较有意思的映射器,就是将访问路径直接映射到具体Controller类的id,通过查看源码我们会发现其实类中有个Map,用来存放注入进去的路径和Bean的相关信息,然后通过其父类注册处理器处理相关请求,看看源码就能更好的理解了:
public class SimpleUrlHandlerMapping extends AbstractUrlHandlerMapping { // 内部用了个map作为存放访问路径和beand的映射 private final Map urlMap = new HashMap(); // 由于这里有这个方法,那么我们在配置文件中就可以通过mappings,注入我们的数据 public void setMappings(Properties mappings) { this.urlMap.putAll(mappings); } // 省略部分不相关方法....
</pre><pre name="code" class="java"> public void initApplicationContext() throws BeansException { super.initApplicationContext(); registerHandlers(this.urlMap); } protected void registerHandlers(Map urlMap) throws BeansException { if (urlMap.isEmpty()) { logger.warn("Neither 'urlMap' nor 'mappings' set on SimpleUrlHandlerMapping"); } else { Iterator it = urlMap.keySet().iterator(); while (it.hasNext()) { String url = (String) it.next(); Object handler = urlMap.get(url); // 如果不是斜杠起始,那么带上斜杠 if (!url.startsWith("/")) { url = "/" + url; } // 如果是字符串,那么处理掉空格,这个不错,小细节也值得我们学习, if (handler instanceof String) { handler = ((String) handler).trim(); } // 调用父类 AbstractUrlHandlerMapping方法,进行URL路径注册处理器 registerHandler(url, handler); } } } }
springmvc-servlet.xml一般可以这么配置使用:
<!—简单url映射,可以将项目的路径统一放到这里配置,比较方便,多个范围路径可以映射到通过一个Controller上,类似Map(key-value) --> <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props><!-- key:访问路径 value:bean的id --> <prop key="/hello1.action">hello_controller</prop> <prop key="/hello2.action">hello_controller</prop> </props> </property> </bean>
二、HandlerAdapter处理器适配器
HandlerAdapter会把后端控制器包装为一个适配器,支持多种类型的控制器开发,这里使用了适配器设计模式。
1).SimpleControllerHandlerAdapter简单控制器处理器适配器
简单控制器处理器适配器所有实现了org.springframework.web.servlet.mvc.Controller 接口的Bean作为Springmvc的后端控制器,分析源码我们可以更好地发现这一点。
public class SimpleControllerHandlerAdapter implements HandlerAdapter { // 判断目标类是否实现了Controller接口,为进一步执行handle方法做预判断 public boolean supports(Object handler) { return (handler instanceof Controller); } // 处理方法 public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 使用简单,粗暴的方式 直接向上转型后执行 我们实现类bean里面的handleRequest方法,也就是Controller里面唯一的待实现方法。 return ((Controller) handler).handleRequest(request, response); } }
一般在配置文件中,直接配置该类即可支持实现了Controller接口的类正常使用
2).HttpRequestHandlerAdapter
Http请求处理器适配器
HTTP请求处理器适配器将http请求封装成HttpServletResquest 和HttpServletResponse对象,和servlet接口类似。通过源码会发现这个和上面的SimpleController处理有点类似,上面是强转Controller,这里是强转HttpRequestHandler对象,所以我们想要使用这个适配器时,应该怎么做呢?你可能通过对比学习发现了,对,就是写个bean实现HttpRequestHandler这个接口就好了。
比较简单,有兴趣的同学自己先试着写一下,然后想进一步看看内部如何实现的话可以去读读该源码哦。
好了,今天这些就是内容了,主要就是以上映射器和适配器的介绍了。大彪在这里只是简单地列出了几个,其实springmvc给咱们提供了很多映射器和适配器,如果小伙伴有更多的时间想对这些更深入地学习,可以继续看看别的类实现,如下图:
推荐个学习框架小技巧,可以通过查看框架的api文档找到几个主要的类或者接口,然后弄懂大概整个的框架模型和基本架构(springmvc 组件架构去看看第一回),然后再通过这些主要的类,和接口去学习。其实像这种比较成熟的开源框架,类的命名和注释都是相当规范的,以及具体用的一些设计模式、代码哲学都是非常值得我们学习的。写几个小例子,跑跑,打个断点跟着框架走上几次,忒爽了。
这些有时候比啃书来的实际多了,当然作为IT人,技术图书也是必不可缺的,好拉。 下一篇打算写写,springmvc里面重点:注解的使用。
简单说明什么是映射器,适配器:
映射器:就是根据DispatcherServlet 拿过来的用户请求某部分路径去寻找处理器(就是我们写的具体的某个方法)和一些拦截器
适配器:具体执行处理器的对象,将ModelAndView返回给DispatcherServlet渲染视图用的
这里是 热爱生活,热爱技术,喜欢交友的大彪 .