SpringMVC 官方文档的部分翻译

本文有选择地翻译了 Spring framework 官方文档第21章 SpringMVC.
参见21. Web MVC framework

0. 引论

待续...

1. 通过 @Controller 注解一个控制器

@Controller: 注解一个类,表明其作为控制器.Spring 并不会强制要求继承其他类或者引用Servlet API.当然有必要的话,你依然可以使用 Servlet API.

有时控制器需要被 AOP 代理修饰,例如 @Transactional.此时,建议用基于类(class-based)的代理,默认设置就是如此,但如果控制器实现一个不是由 Spring Context 回调的接口,你就要明确指定类级别的代理:
<tx:annotation-driven proxy-target-class="true"/>

2. 通过 @RequestMapping 映射请求

@RequestMapping :注解方法或者类,表明其用来映射 URL.方法级别的映射还可以通过设定属性来缩小范围,指定更具体的 URL.@RequestMapping 可拥有的属性有:

  • path String[]:指定 URL;
  • method RequestMethod[]:指定 HTTP 方法,RequestMethod.GET 或 .POST 等;
  • value String[] :在 Servlet 中等同于 path;
  • header String[] :指定 HTTP 首部,例如,header="jsessionid=123";
  • params String[] :指定 URL 参数,例如,param="id=1";
  • name String :指定方法或类的名称;
  • consumes String[]:指定消费级媒体类型(consumable media type),text/plain,application/*;
  • produces String[]:指定生产级媒体类型(producible media type)

从 Spring 3.1 开始,默认的映射处理器变为 RequestMappingHandlerMapping.它把控制器的方法作为唯一的映射终点,这些方法会取得类级别和方法级别的 @RequestMapping 信息,而之前的过程是类和方法分开处理.
一个例子:

@Controller
public class MappingController {
	
	// 访问 http://www.abc.com/mapping/path 会被映射到此处
	@RequestMapping(value = "/mapping/path")
	public @ResponseBody String byPath() {
		return "Mapped by Path";
	}
	
	// http://www.abc.com/mapping/path/asd
	@RequestMapping(value = "/mapping/path/*", method = RequestMethod.GET)
	public @ResponseBody String byPathPattern(HttpServletRequest request) {
		return "Mapped by pathpattern " + request.getRequestURI();
	}

	@RequestMapping(value = "/mapping/method", method = RequestMethod.GET)
	public @ResponseBody String byMethod() {
		return "Mapped by path and HTTPmethod";
	}

	// http://www.abc.com/mapping/parameter?foo=something
	@RequestMapping(value = "/mapping/parameter", params = "foo")
	public @ResponseBody String byParams() {
		return "Mapped by Params";
	}
	
	@RequestMapping(value = "/mapping/parameter", params = "!foo")
	public @ResponseBody String byNotParams() {
		return "Mapped by path and method ,not presence of query parameters";
	}
	
	@RequestMapping(value = "/mapping/header", method=RequestMethod.GET,headers="FooHeader=foo")
	public @ResponseBody String byHeaders(HttpServletRequest request) {
		return "Mapped by header's presence "+request.getHeader("FooHeader");
	}
	
	@RequestMapping(value = "/mapping/header", method=RequestMethod.GET,headers="!FooHeader")
	public @ResponseBody String byNotHeaders(HttpServletRequest request) {
		return "Mapped by header's absence ";
	}	
}

3. URI Template Patterns

一个 URI Template 定义了如何将 URI 参数化,例如:
http://www.example.com/user/{userId}
可以通过注解 @PathVariable 来取得 URI 中参数的值,当 URI 参数和方法参数名称不一致时,需指定@PathVariable 的 value.如: @PathVariable("ownerId")
如下,当访问 www.abc.com/owners/zhang 时,方法参数 ownerId 会被赋值为 'zhang'.

@RequestMapping(path="/owners/{ownerId}",method=RequestMethod.GET)
public String find(@PathVariable String ownerId,Model model){
    Owner owner = ownerService.find(ownerId);
    model.addAttribute("owner",owner);
    return "success";
}

还支持正则表达式,待续..

4. 定义 @RequestMapping 注解的方法

@RequestMapping 注解的方法支持的方法参数类型和返回值类型非常多.

支持的方法参数类型:

  • RequestResponse (Servlet API)

  • Session (Servlet API).注: Session 并不是线程安全的/当多个请求可以同步访问 session 时,考虑设置 RequestMappingHandlerAdapter 的 synchronizeOnSession = true;

  • org.springframework.web.context.request.WebRequest or org.springframework.web.context.reqeust.NativeWebRequest. 允许泛型化 Request 的参数访问以及 reqeust/session 属性访问,不必再捆绑到原生 Servlet.

  • java.util.Locale for the current request locale,在 MVC 中由 LocaleResolver/LocaleContextResolver 配置.

  • java.util.TimeZone(java6+)/java.time.ZoneId(java8)

  • java.io.OutputStream/java.io.writer 用来生成响应内容.This value is the raw OutputStream/Writer as exposed by the Servlet API.

  • org.springframework.http.HttpMethod 用于 HTTP 请求方法.

  • java.security.Principal

  • @PathVariable

  • @MatrixVariable

  • @RequestParam 可以获得 url 中的参数,例如:/find?id=123 中的 id

  • @RequestHeader

  • @RequestBody

  • @ReqeustPart

  • HttpEntity<?> 可以通过它访问 request 和 reponse 的 body/header 等.

  • java.util.Map or org.springframework.ui.Model or org.springframework.ui.ModelMap 保存属性,传递给视图层.

  • org.springframework.web.servlet.mvc.suppot.RedirectAttributes 用于保存重定向时需要的属性.

  • Command 或 表单对象. ...

  • org.springframework.validation.Errors / org.springframework.validation.BindingResult 代表了先前 command 或表单对象的验证结果.

  • org.springframework.web.bind.support.SessionStatus 用于标记表单处理完成的标识.它会触发 session 属性的清理.

  • org.springframework.web.util.UriComponentsBuilder

注:当方法参数有多个时, BingdingResult/Error 参数必须紧跟在模型对象之后.
注2:java.util.Optional 可作为方法参数,用于那些拥有 required 属性的注解(@RequestParam,@RequestHeader,etc).

支持的方法返回类型

返回 Sring 能满足大部分需求.
待续..

5. 使用 @ModelAttribute 注解方法

使用 @ModelAttribute 注解方法表明此方法要向 model 中添加属性.此方法会在 @RequestMapping 方法之前执行.一个例子:

@ModelAttribute
public Account add(@RequestParam String number){
    return accountService.find(number);
}
@ModelAttribute
public void populateModel(@RequestParam String number,Model model){
    model.addAttribute(accountService.find(number));
    model.addAttribute("something","something");
    //add more...
}

@ModelAttribute 还可以用在 @ControllerAdivce-annotated class.

@ModelAttribute 还可以用在 @RequestMapping 方法上,此时,返回值会被放进 model,视图名称通过约定(convention),就好像返回值是 void 的方法一样.

6. 在方法参数中使用 @ModelAttribute

被 @ModelAttribute 注解的方法参数表明参数应该从模型中取出.如果模型中不存在此对象,则首先实例化,然后添加到模型中,并且对象的实例域如果与请求参数匹配,则自动被赋值.这就是 SpringMVC 中的数据绑定.一个例子:
当访问 www.abc.com/test?name=piqiu 时,pro 会被添加到 model 中,且 name 属性会被自动赋值,可以在随后使用.

public class Product{
    private String name;
    //省略 get/set...
}
.....
@RequestMapping(value="/test")
public String test(@ModelAttribute Product pro){
    productService.update(pro);
    //操作 pro..
    return "success";
}

7. 通过 @InitBinder 定制数据绑定

待续..

posted @ 2016-01-21 22:53  CloudFlew  阅读(745)  评论(0编辑  收藏  举报