注解的处理器映射器和注解适配器
首先我们来看一下DispatcherServlet默认加载的配置文件信息。
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
//默认配置的处理器映射器,一个是按照bean的name作为url查找,一个是注解
//默认使用的注解处理器映射器已经过时了。默认使用的是SpringMVC3.1之前的。
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
//默认配置了两个适配器,一个是要实现Controller接口的适配器,一个是要实现HttpRequestHandler接口的适配器。当然还有注解类。
//默认使用的注解适配器已经过时了,默认使用的是SpringMVC3.1之前的。
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
注解处理器映射器
在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解映射器。
在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解映射器。
注解处理器适配器
在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解适配器。
在spring3.1之后使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解适配器。
配置注解映射器和注解适配器
在SpringMVC核心配置文件(springmvc.xml)中配置
<!-- 注解映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
<!-- 注解适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
另外一种配置方法:
<!-- 使用 mvc:annotation-driven 代替上边注解映射器和注解适配器配置
mvc:annotation-driven 默认加载很多的参数绑定方法,
比如json转换解析器就默认加载了,如果使用 mvc:annotation-driven不用配置上边的RequestMappingHandlerMapping和RequestMappingHandlerAdapter
实际开发时使用 mvc:annotation-driven
-->
<mvc:annotation-driven></mvc:annotation-driven>
开发注解Handler
使用注解的映射器和注解的适配器。(注解的映射器和注解的适配器必须配对使用)
//这里使用Controller标识它是一个控制器
@Controller
public class ItemsListControllerByAnnotation {
/**
* @RequestMapping 实现对showItemsListByAnnotation方法和url进行映射,一个方法对应一个url
* 一般建议将url和方法写成一样
* 如果想要/showItemsListByAnnotation进行访问,你必须把Servlet的url-pattern值设置为"/",并且@RequestMapping的值为"/showItemsListByAnnotation"
* @return
* @throws Exception
*/
@RequestMapping("/showItemsListByAnnotation.action")
public ModelAndView showItemsListByAnnotation() throws Exception{
/*
* 调用service查找数据库,查询商品列表,这里使用静态数据模拟。
*/
List<Item> items=new ArrayList<Item>();
items.add(new Item("FireLang", 456.65, "技匠", null, new Date()));
//创建ModelAndView
ModelAndView modelAndView=new ModelAndView();
//相当于 request 的 setAttribut,在jsp页面通过itemsList获取数据。
modelAndView.addObject("itemsList", items);
//指定跳转视图
//为了安全起见(必须在我们的允许范围内访问视图),所以我们把视图放在了WEB-INF目录下。
modelAndView.setViewName("/WEB-INF/content/itemsList.jsp");
return modelAndView;
}
}
/*
* 在Handler里面 @RequestMapping 不仅可以写在方法上面也可以写在类上面。这样就是在访问类里面的每个
* 方法url时,都必须加上类上@RequestMapping的value定义的前缀。通常类中的@RequestMapping也要加"/",如"/user"
*/
如果想要限定请求方式来访问Handler可以这样写注解:
//这里使用Controller标识它是一个控制器
@Controller
public class ItemsListControllerByAnnotation {
/**
* RequestMapping 实现对showItemsListByAnnotation方法和url进行映射,一个方法对应一个url
* 一般建议将url和方法写成一样
* @return
* @throws Exception
*/
@RequestMapping(value="/showItemsListByAnnotation.action",method={RequestMethod.POST}) //看这里!!!!!!!!!!!!!!!!!!!
public ModelAndView showItemsListByAnnotation() throws Exception{
/*
* 调用service查找数据库,查询商品列表,这里使用静态数据模拟。
*/
List<Item> items=new ArrayList<Item>();
items.add(new Item("FireLang", 456.65, "技匠", null, new Date()));
//创建ModelAndView
ModelAndView modelAndView=new ModelAndView();
//相当于 request 的 setAttribut,在jsp页面通过itemsList获取数据。
modelAndView.addObject("itemsList", items);
//指定跳转视图
//为了安全起见(必须在我们的允许范围内访问视图),所以我们把视图放在了WEB-INF目录下。
modelAndView.setViewName("/WEB-INF/content/itemsList.jsp");
return modelAndView;
}
}
如果你是直接转发返回一个页面或者转发一个url路径,你可以这样写:
@RequestMapping(value="/showItemsListByAnnotationInsert.action",method={RequestMethod.GET})
public String showItemsListByAnnotationInsert() throws Exception{
/*
* 返回一个视图的路径,通过视图解析器解析该字符串成一个视图对象。也就是说该路径就是ModelAndView中的View,所以你可以通过"forward:"或者"redirect:"指定是返回页面方式是转发还是重定向。
*/
return "/WEB-INF/content/itemsList.jsp";
}
转发一个url路径:
@RequestMapping(value="/showItemsListByAnnotationInsert.action",method={RequestMethod.GET})
public String showItemsListByAnnotationInsert() throws Exception{
/*
* 返回一个视图的路径,通过视图解析器解析该字符串成一个视图对象。也就是说该路径就是ModelAndView中的View,所以你可以通过"forward:"或者"redirect:"指定是返回页面方式是转发还是重定向。
*/
return "/showItemsListByAnnotation.action";
}
另外说一下,在SpringMVC核心配置文件中的url通配符,在这里也是管用的:
@RequestMapping(value="/showItemsListByAnnotationUpdate*.action",method={RequestMethod.GET})//这里有两种通配符,一种是*,用来匹配>=0个字符,一个是?用来匹配一个字符,注意这一个字符是必须匹配一个!!!
public String showItemsListByAnnotationUpdate() throws Exception{
/*
* 返回一个视图的路径,通过视图解析器解析该字符串成一个视图对象。也就是说该路径就是ModelAndView中的View
*/
return "/showItemsListByAnnotation.action";
}
/*
* 下面来几个示例:
* langx*.action是拦截 以langx为前缀的.action请求!!!
* *.action是拦截所有的.action请求,如果在xml中进行配置,你需要把该配置放在处理器映射器的第一位。
* user/*/*.action 是拦截所有的 user/的请求,但是有个规则:你必须 user/这里的字符大于等于1个/*.action ,所以最多拦截一层user请求,而且也是必须拦截一层请求!!!
* user/**/*.action 是拦截一切的user路径请求,不论层级关系。如:user/sdfs/*.action或者user/sdfsd/sdfgfg/sdfdsfs/*.action都是可以的!!!
*/
在spring容器中加载Handler
<!-- 对于注解的Handler可以单个配置
实际开发中建议使用组件扫描
-->
<!-- <bean class="cn.domarvel.controller.ItemsListControllerByAnnotation"/> -->
<!-- 可以扫描Controller、Service、Component等注解
这里扫描Controller,首先指定JavaBean的包
-->
<context:component-scan base-package="cn.domarvel.controller"></context:component-scan>
注意:
通过注解来进行处理器的处理器映射和处理器适配的时候,必须通过@Controller注解来生成JavaBean对象。也就是说,我们通过@RequestMapping("/showItemsListByAnnotation.action")
配置了该处理器的处理器映射和处理器适配,我们就必须通过@Controller注解来生成JavaBean对象。
为什么必须是@Controller这个注解??而不是@Component,@Service等创建bean对象的注解??
答:因为注解是一个标记,标记懂吧!!而我们用注解时,Handler根本就没有实现任何接口,继承任何类,所以为什么用@Controller这个标记就很明白了,因为Spring只会找有@Controller这个标记的类作为Handler。然后通过注解的处理器映射器找到处理器,再通过注解的适配器执行该Handler!!