Spring 2.5 引入了一种基于注解的编程模式,注解支持 Servlet MVC 和 Portlet MVC。控制器可以不必继承特定的基类或实现特定的接口。
@Controller 在 Spring MVC 中,控制器 Controller 负责处理由 DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个 Model,然后再把该 Model 返回给对应的 View 进行展示。
不使用注解的方式,需要在 Spring MVC 配置文件 springmvc-config.xml 中添加 Controller 类的 Bean 对象,如: <bean class="com.shiyanlou.springmvc.controller.UserController"/>
使用 @Controller 注解的类不再需要继承特定的基类或实现特定的接口,并且可以同时处理多个请求动作。 配置文件写法: 首先在头文件引入 spring-context。 启动包扫描功能,添加类似如下的代码:
<context:component-scan base-package="com.shiyanlou.springmvc.controller" />
base-package 是指定要扫描的包及其子包。
回顾上一节 Controller 类中的一些代码: /** * UserController 是一个基于注解的控制器 * 可以同时处理多个请求动作 */ @Controller public class UserController { /** * RequestMapping 用来映射一个请求和请求的方法 * value="/register" 表示请求由 register 方法进行处理 */ @RequestMapping(value="/register") public String Register(@ModelAttribute("form") User user, Model model) { // user:视图层传给控制层的表单对象;model:控制层返回给视图层的对象 // 在 model 中添加一个名为 "user" 的 user 对象 model.addAttribute("user", user); // 返回一个字符串 " success" 作为视图名称 return "success"; } }
可以看到,为 UserController 添加了 @Controller,说明它是一个基于注解的控制器。 Spring 会使用扫描机制查找所有基于注解的控制器类。
@RequestMapping @RequestMapping 注解用来处理请求地址映射,指示 Spring 用哪个类或方法来处理请求动作。 @RequestMapping 可用于类或方法上。 当 @RequestMapping 用于类上时,表示类中的所有响应方法都被映射到 value 属性所指示的路径下,如: @Controller @RequestMapping(value="/user") public class UserController { @RequestMapping(value="/register") public String Register() { return "register"; } }
在这里,相关路径均要加上 /user,Register() 映射的 URL 为: http://localhost:8080/SpringMVCTest/user/register
若未用 @RequestMapping(value="/user") 注解类,该方法映射的 URL 为: http://localhost:8080/SpringMVCTest/register 同样是上面的示例代码, @RequestMapping(value="/register") 映射一个请求和请求的方法,请求由 Register 方法进行处理。
@RequestMapping 常用属性
(1)value
指定请求的实际地址,即 value 属性将 URL 映射到方法上。
@Controller
public class UserController {
@RequestMapping(value="/register")
public String Register() {
return "register";
}
}
对应的 URL:
http://localhost:8080/SpringMVCTest/register
如果 @RequestMapping 只有唯一的属性,value 属性名可省略。
@RequestMapping(value="/register")
@RequestMapping("/register")
(2)method
指定请求的 method 类型,即该方法可以处理的 HTTP 请求方式,如 GET、POST 等。
@RequestMapping("/register",method=RequestMethod.POST)
注:如果未指定 method,则可以处理任意类型的 HTTP 请求。
(3)consumes
指定处理请求的提交内容类型(Content-Type),例如 application/json, text/html。
@RequestMapping("/register",method=RequestMethod.POST,consumes="application/json")
这里只处理 request Content-Type 为 application/json 的请求。
(4)produces
指定返回的内容类型,仅当 request 请求头中的(Accept)类型中包含该指定类型才返回。
@RequestMapping("/register",method=RequestMethod.POST,produces="application/json")
(5)params
指定 request 中必须包含某些参数值是,才让该方法处理。
@RequestMapping("/register",method=RequestMethod.POST,params="myParam=myValue")
这里只处理名为 "myParam",值为 "myValue" 的请求。
(6)headers
指定 request 中必须包含某些指定的 header 值,才能让该方法处理请求。
@RequestMapping("/register",method=RequestMethod.POST,headers="Referer=http://www.shiyanlou.com")
这里只处理 request 的 header 中包含了指定 "Referer" 请求头和对应值为 "http://www.shiyanlou.com" 的请求。
参数绑定
@RequestParam
@RequestParam 主要用于在 Spring MVC 后台控制层获取参数,类似一种是 request.getParameter("name")。
支持的属性:
name:指定请求头绑定的名称
value:name 的别名
required:通过 boolean 指定参数是否必须绑定
defaultValue:设置默认值
例如一个登陆请求的处理方法。
@RequestMapping(value="/login")
public ModelAndView login(@RequestParam("username") String username, @RequestParam("password") String password) {
return ...
}
请求如下:
http://localhost:8080/SpringMVCTest/login?username=tom&password=123456
上述代码会把 username 参数的值 "tom" 赋给 username 变量,把 password 参数的值 "123456" 赋给 password 变量。
@ResponseBody
@ResponseBody 用于将 Controller 方法返回的对象,通过适当的 HttpMessageConverter 转换为指定格式后,写入到 Response 对象的 body 数据区,如: @RequestMapping(value="/something", method=RequestMethod.PUT) public void doSomething(@RequestBody String body, Writer writer) throws IOException { writer.write(body); }
@PathVariable
@PathVariable 用来将请求 URL 中的模板变量映射到功能处理方法的参数上,如: @RequestMapping(value="/something/{userId}") public void doSomething(@PathVariable Integer userId){} 在这里假设请求的 URL 为 "http://localhost:8080/SpringMVCTest/something/1",则将 {userId} 为1绑定到 @PathVariable 注解的同名参数上。
@RequestHeader
@ModelAttribute
@ModelAttribute 将请求参数绑定到 Model 对象。@ModelAttribute 主要有两种使用方式,一种是注解在方法上,一种是注解在 Controller 方法参数上。
注:当 @ModelAttribute 注解在方法上时,该方法会在 Controller 每个方法执行前被执行。
举个登录的例子: @Controller public class ModelAttributeController { @ModelAttribute("user") public User userModel( @RequestParam("username") String username, @RequestParam("password") String password){ User user = new User(); user.setUsername(username); user.setPassword(password); return user; } @RequestMapping(value="/login") public String login(@ModelAttribute("user") User user{ return "success"; } } 在 userModel 方法上有注解 @ModelAttribute("user"),表示 userModel 方法会先于 login 方法调用。这里 model 属性名称是 value 只,由于只有一个属性所以省略了名称,即 "user",model 属性对象是方法的返回值。 在 login 方法的参数 User user 使用了 @ModelAttribute("user"),表示参数 user 的值是 userModel 方法中的 model 属性。