在Spring 2.5 以后,又为 Spring MVC 引入了注解驱动功能,使用过低版本 Spring MVC 的读者都知道:当创建一个 Controller 时,我们需要直接或间接地实现org.springframework.web.servlet.mvc.Controller 接口。一般情况下,我们是通过继承 SimpleFormController 或 MultiActionController 来定义自己的 Controller 的。在定义 Controller 后,一个重要的事件是在 Spring MVC 的配置文件中通过 HandlerMapping 定义请求和控制器的映射关系,以便将两者关联起来。而注解驱动就是无须让 Controller 继承任何接口,无需在 XML 配置文件中定义请求和 Controller 的映射关系,仅仅使用注解就可以让一个 POJO 具有 Controller 的绝大部分功能 —— Spring MVC 框架的易用性得到了进一步的增强.在框架灵活性、易用性和扩展性上,Spring MVC 已经全面超越了其它的 MVC 框架。
如何使用注解驱动呢?首先你要使用@Controller将POJO注解为成为一个控制器,再通过<context:component-scan/>扫描相应的包,具体的配置如下: <beans>
<!-- ①:对web包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 -->
<context:component-scan base-package="com.doujt.web"/>
<!-- ②:启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.
AnnotationMethodHandlerAdapter"/>
<!-- ③:对模型视图名称的解析,即在模型视图名称添加前后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
</beans>
ps:Spring 所有功能都在 Bean 的基础上演化而来,所以必须事先将 Controller 变成 Bean,这是通过在类中标注 @Controller 并在 配置文件中启用组件扫描机制来完成的,如 ① 所示。
在 ② 处,配置了一个 AnnotationMethodHandlerAdapter,它负责根据 Bean 中的 Spring MVC 注解对 Bean 进行加工处理,使这些 Bean 变成控制器并映射特定的 URL 请求。
而 ③ 处的工作是定义模型视图名称的解析规则,这里我们使用了 Spring 的特殊命名空间,即 p 命名空间,它将原先需要通过 <property> 元素配置的内容转化为 <bean> 属性配置,在一定程度上简化了 <bean> 的配置。
有了基础的配置服务之后就可以使用@RequestMapping 注解去将请求映射到具体的控制器上。
(一)@RequestMapping("/user"),将请求映射到/user.do的控制器上。
需要注意的是@RequestMapping在类定义处是相对于web应用的部署目录,而方法注解驱动是相对于类的本身目录,因此在类定义处未注解驱动,那么方法注解驱动的url是相对于web应用的部署目录。@RequestMapping不但支持标准的url,还支持ant风格(即?,**的字符)和带{xxx}占位符的url,例如下面的
/user/*/createUser : 匹配/user/aaa/createUser、/user/bbb/createUser
/user/**/createUser : 匹配/user/createUser、/user/bbb/aaa/createUser
/user/createUser?? : 匹配/user/createUseraa、/user/bbb/aaa/createUserbb
/user/{userId} : 匹配/user/123、/user/456
/user/**/{userId} : 匹配/user/aaa/bbb/123、/user/qwe/456
/user/{userName}/user/{userId}/detail :匹配/user/zhangsan/user/123/detail
说明:其中带占位符的url是Spring3.0新增的功能,目的是为SpringMVC向REST目标进发。带占位符的值可以通过@PathVariable获取
(二)通过请求头,请求方式和请求参数进行映射 @RequestMapping
除了可以使用请求方式url进行映射请求,还可以使用请求方法、请求头参数以及请求参数进行映射,如下:
//使用请求方法映射请求
@RequestMapping(value="/doUpdateUser.do",method=RequestMethod.GET,params="userId")
public String doUpdateUser(@PathVariable("userId") String userId){
System.out.println("使用请求方法映射");
System.out.println("userId==="+userId);
return "index";
}
(三)使用@RequestParam绑定请求参数值
java反射对象默认是不会记录方法入参的名称,因此需要在方法入参出使用@RequestParam注解获取传过来的数值@RequestParam有三个属性
value :参数名
required :是否为必须,默认为true,请求过程之中必须要有对应的参数名,如果没有就会出现异常
defaultValue : 默认参数名,默认为false
public String doInsertUser(@RequestParam("userAddress") String userAddress){
System.out.println("测试成功");
System.out.println("username:"+userName+",userAddress:"+userAddress);
return "index";
}
(四)使用@CookieValue绑定请求的Cookie值(用法与@RequestParm一样,拥有三个参数,唯一区别就是required为false,即使么有也不会报错)
public String doInsertUser(@CookieValue("user",required=false) String user,@RequestParam("userAddress") String userAddress){
System.out.println("测试成功");
System.out.println("username:"+userName+",userAddress:"+userAddress);
return "index";
}
(五)使用@RequestHeader绑定请求报文头的属性值
(六)使用命令/表单对象绑定请求参数值 命令/表单对象不需要实现任何借口,仅仅需要拥有一个POJO。SpirngMVC 会自动填充传过来的值,并且支持级联属性名,如user.userName,user.password.
(七)使用ServletAPI对象作为入参
public void handleServlet_1(HttpServletRequest request,HttpServletResponse response){
}
(八)使用IOI对象作为入参
public void handleServlet_1(OutputStream os){}
总结:注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作。如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名、类型等信息,如果关系表字段和 PO 属性名、类型都一致,您甚至无需编写任务属性映射信息——因为这些信息都可以通过 Java 反射机制获取。 注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,有助于增强程序的内聚性。而采用独立的 XML 配置文件,程序员在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率。