调用此接口,控制台输出日志如下:
after.......... before.......... afterArg.......... beforeArg.......... modelAttribute.......... beforeArg..........beforeArgValue {after=afterValue, before=beforeValue, afterArg=afterArgValue, beforeArg=beforeArgValue}可以印证排序规则和参数设置、获取的结果和前面的分析是一致的。
Errors或者BindingResult参数Errors其实是BindingResult的父接口,BindingResult主要用于回调JSR参数校验异常的属性项,如果JSR校验异常,一般会抛出MethodArgumentNotValidException异常,并且会返回400(Bad Request),见全局异常处理器DefaultHandlerExceptionResolver。Errors类型的参数处理器为ErrorsMethodArgumentResolver。举个例子:
@PostMapping(value = "/errors") public String errors(@RequestBody @Validated ErrorsModel errors, BindingResult bindingResult) { if (bindingResult.hasErrors()) { for (ObjectError objectError : bindingResult.getAllErrors()) { log.warn("name={},message={}", objectError.getObjectName(), objectError.getDefaultMessage()); } } return errors.toString(); } //ErrorsModel @Data @NoArgsConstructor public class ErrorsModel { @NotNull(message = "id must not be null!") private Integer id; @NotEmpty(message = "errors name must not be empty!") private String name; }调用接口控制台Warn日志如下:
name=errors,message=errors name must not be empty!一般情况下,不建议用这种方式处理JSR校验异常的属性项,因为会涉及到大量的重复的硬编码工作,建议:方式一直接继承ResponseEntityExceptionHandler覆盖对应的方法或者方式二同时使用@ExceptionHandler和@(Rest)ControllerAdvice注解进行异常处理。例如:
@RestControllerAdvice public class ApplicationRestControllerAdvice{ @ExceptionHandler(BusinessException.class) public Response handleBusinessException(BusinessException e, HttpServletRequest request){ // 这里处理异常和返回值 } } @Value参数控制器方法的参数可以是@Value注解修饰的参数,会从Environment实例中装配和转换属性值到对应的参数中(也就是参数的来源并不是请求体),参数处理器为ExpressionValueMethodArgumentResolver。举个例子:
@GetMapping(value = "/value") public String value(@Value(value = "${spring.application.name}") String name) { log.info("spring.application.name={}", name); return name; }spring.application.name属性一般在配置文件中指定,在加载配置文件属性的时候添加到全局的Environment中。
Map类型参数Map类型参数的范围相对比较广,对应一系列的参数处理器,注意区别使用了上面提到的部分注解的Map类型和完全不使用注解的Map类型参数,两者的处理方式不相同。下面列举几个相对典型的Map类型参数处理例子。
不使用任何注解的Map<String,Object>参数
这种情况下参数实际上直接回调ModelAndViewContainer中的ModelMap实例,参数处理器为MapMethodProcessor,往Map参数中添加的属性将会带到页面中。
使用@RequestParam注解的Map<String,Object>参数
这种情况下的参数处理器为RequestParamMapMethodArgumentResolver,使用的请求方式需要指定Content-Type为x-www-form-urlencoded,不能使用application/json的方式:
控制器代码为:
@PostMapping(value = "/map") public String mapArgs(@RequestParam Map<String, Object> map) { log.info("{}", map); return map.toString(); }使用@RequestHeader注解的Map<String,Object>参数
这种情况下的参数处理器为RequestHeaderMapMethodArgumentResolver,作用是获取请求的所有请求头的Key-Value。
使用@PathVariable注解的Map<String,Object>参数
这种情况下的参数处理器为PathVariableMapMethodArgumentResolver,作用是获取所有路径参数封装为Key-Value结构。
MultipartFile集合-批量文件上传批量文件上传的时候,我们一般需要接收一个MultipartFile集合,可以有两种选择:
使用MultipartHttpServletRequest参数,直接调用getFiles方法获取MultipartFile列表。
使用@RequestParam注解修饰MultipartFile列表,参数处理器是RequestParamMethodArgumentResolver,其实就是第1种方式的封装而已。
控制器方法代码如下:
@PostMapping(value = "/parts") public String partArgs(@RequestParam(name = "file") List<MultipartFile> parts) { log.info("{}", parts); return parts.toString(); } 日期类型参数处理