Spring Framework--SpringMVC(2)--Controller(2) --定义请求处理器方法

二、定义请求映射的处理器方法(Defining @RequestMapping handler method)

  SpringMVC控制器中的请求映射处理方法有着非常众多和灵活的方法签名,下面介绍这些方法支持的方法参数和返回值,除了BindingResult类型参数外,其他的参数的顺序都是任意的。

  1、支持的方法参数类型:

  (1) Servlet API中的请求和响应对象(request or response object),如:ServletRequest, HttpServletRequest

  (2) Servlet API中的会话对象(session object),如:HttpSession

  (3) org.springframework.web.context.request.WebRequest或者org.springframework.web.context.request.NativeWebRequest,可以访问一般的请求参数

  (4) java.util.Locale 访问请求的本地化信息

  (5) java.io.InputStream / java.io.Reader 访问请求的内容

  (6) java.io.OutputStream / java.io.Writer 用来生成响应的内容

  (7) java.security.Principal 包含当前认证的用户

  (8) @PathVariable注解的参数,用来访问URL模版中的参数

  (9) @MatrixVariable注解的参数,用来访问URL特定位置中键值对参数

  (9) @RequestParam注解的参数,用来访问特定的Servlet请求参数,请求参数会被转换到@RequestParam声明的参数类型上

  (10) @RequestHeader注解的参数,用来访问特定的Servlet请求头参数,请求头参数会被转换到@RequestHeader声明的参数类型上

  (11) @RequestBody注解的参数,用来访问特定的Servlet请求体,请求体会被HttpMessageConverter转换到声明的参数类型上

  (12) @RequestPart注解的参数,用来访问一个"multipart/form-data"请求部分的数据

  (13) java.util.Map/org.springframework.ui.Model /org.springframework.ui.ModelMap,用来丰富给View的隐式模型(implicit model)

  (14) org.springframework.web.servlet.mvc.support.RedirectAttributes,用来在重定向时定义一个精确的属性集并且添加flash属性(在重定向后可以使用的缓存在服务器端的临时属性)。RedirectAttributes用来代替隐式模型,如果方法返回一个"redirect:"前缀的视图名称或者一个RedirectView对象。

  (15) Command或者表单对象,用来把请求参数绑定到bean的属性(通过setter方法)或者直接绑定到字段(field)上。

  (16) org.springframework.validation.Errors/org.springframework.validation.BindingResult,用来访问上面讲到的Command或者表单对象的验证结果

  (17) org.springframework.web.bind.support.SessionStatus,

  (18) org.springframework.web.util.UriComponentsBuilder,

  2、支持的返回值类型

  (1) ModelAndView,

  (2) Model

  (3) Map

  (4) View

  (5) String

  (6) void

  (7) 如果方法使用了@ResponseBody注解,那么返回类型会被写入到响应的Http body中

  (7) HttpEntity<?> Or ResponseEntity<?>

  (8) Callable<?>

  (9) DeferredResult<?>

  (10) 其他任何类型的返回值,被当做模型的一个属性来暴露给视图,属性名是方法级别上@ModelAttribute注解指定的(没指定,默认为返回值所属类型的类名)

  3、使用@RequestParam把请求参数绑定到方法参数,使用了这个注解,默认是必须提供这个参数的,可以设置required属性为false来改变这一行为,如@RequestParam(value="id" required=false)

  4、使用@RequestBody注解,表示方法参数是和http request的body绑定的,如:  

@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
    writer.write(body);
}

  5、使用@ResponseBody注解,表示返回类型直接写入http response的body中,而不是放到model属性中,或者作为视图名称。如:

@RequestMapping(value = "/something", method = RequestMethod.PUT)
@ResponseBody
public String helloWorld() {
    return "Hello World";
}

  6、使用@RestController注解来实现一个REST API,这个注解是@Controller和@ResponseBody的组合,除此之外,这个注解可能在Spring以后的版本中添加新的特性

  7、使用HttpEntity,HttpEntity与@RequestBody和@ResponseBody类似,不过除了可以访问请求与响应体外,它还可以访问请求和响应头,ResponseEntity是HttpEntity的子类。如:

@RequestMapping("/something")
public ResponseEntity<String> handle(HttpEntity<byte[]> requestEntity) throws
UnsupportedEncodingException {
    String requestHeader = requestEntity.getHeaders().getFirst("MyRequestHeader"));
    byte[] requestBody = requestEntity.getBody();
    // do something with request header and body
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.set("MyResponseHeader", "MyValue");
    return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}

  8、在方法上使用@ModelAttribute注解,使用这个注解的方法的目的是在model上增加一个或者多个属性,方法参数类型和@RequestMapping一样,但是不能直接映射到请求。实际上,在一个控制器里的@ModelAttribute方法是在@RequestMapping方法调用前被调用的。添加一个和多个属性的例子:

// Add one attribute
// The return value of the method is added to the model under the name "account"
// You can customize the name via @ModelAttribute("myAccount")
@ModelAttribute
public Account addAccount(@RequestParam String number) {
    return accountManager.findAccount(number);
}
// Add multiple attributes
@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
    model.addAttribute(accountManager.findAccount(number));
    // add more ...
}

  一个控制器可有含任意多的@ModelAttribute方法,所以的这些方法在同一个控制器的@RequestMapping方法之前被调用。@ModelAttribute也可以用在@RequestMapping方法上,返回值表示的是一个model的属性,而不是一个视图的名称。

  9、在方法参数上使用@ModelAttribute注解,表示这个参数的值必须从一个model中获取,如果在model不存在,那么先必须实例化这个参数再设置到model的属性上,一旦设置好了,参数对象的字段值使用请求中所有名字匹配的参数值来填充,这就是SpringMVC中的数据绑定,一个很有用的机制,让我们不用挨个地去操作表单的字段。例子:

@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) { }

  上例中的pet实例从哪里来?有四种方式:

    a. 由于使用@SessionAttribute,已经在model中存在了,使用@SessionAttribute可以在不同的请求之间保存model的属性。

    b. 由于在同一个控制器中使用了@ModelAttribute方法,已经在model中存在了。

    c. 从一个URL模版和类型转换器可以获取到,如下例,如果注册一个可以把String转成Account对象的转换器,就不需要b中的@ModelAttribute方法了。

      @RequestMapping(value="/accounts/{account}", method = RequestMethod.PUT)
      public String save(@ModelAttribute("account") Account account) {}

    d. 使用默认的构造器实例化出来的。

  10、使用@SessionAttribute注解,在不同的请求之间把model属性存储到HttpSession里,这是个类级别的注解,如:  

@Controller
@RequestMapping("/editPet.do")
@SessionAttributes("pet")
public class EditPetForm {
// ...
}

  11、方法参数和类型转换

  从一个请求中抽取的基于字符的数据,包括请求参数,路径参数,请求头,cookie值等都需要转换到目标方法的参数类型或者字段。Spring可以自动转换到合适的类型,不过我们可以通过WebDataBinder来自定义这个转换的过程,或者通过FormattingConversionService注册Formatters也可以完成自定义转换过程。

  通过WebDataBinder,方式一:在@Controller类或者@ControllerAdvice类中使用@InitBinder注解,如:  

@Controller
public class MyFormController {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormat.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
    }
    // ...
}        

  方式二:实现WebBindingInitializer接口。

原文地址:https://www.cnblogs.com/winson/p/3671340.html