如何使用自定义参数注释返回自定义弹簧错误响应?

我刚开始spring,所以请原谅我的无知。 当给定的方法参数(“required”)为null时,我试图“返回”自定义响应。 从spring开始,目前的反应是:

{ "timestamp": 1477060294961, "status": 400, "error": "Bad Request", "exception": "org.springframework.web.bind.MissingServletRequestParameterException", "message": "Required String parameter 'bookname' is not present", "path": "/getbook" } 

我试图达到“返回”的程度:

 { "status": 400, "error": { // custom error body } } 

我认为这样做的好方法是使用自定义“参数注释”。 这也可以使代码更具可读性并存储有关此端点参数的有用信息。

我按照这里给出的示例,但我不确定在何处或如何返回自定义响应?

到目前为止我有注释:

 @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Component public @interface customParameter { String value() default ""; boolean required() default false; String defaultValue() default ValueConstants.DEFAULT_NONE; String customInfo() default "blar blar"; } 

“终点”:

  @RequestMapping(value = "/getbook", method = {RequestMethod.POST}) public ResponseEntity getBookInfo( @customParameter(value = "bookname", required = true, customInfo = "extremely valuable book") final String bookname ) { return new bookRequest(bookname).getResponse; } 

并有一个自定义解析器:

 public class CustomAnnotationResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterAnnotation(customParameter.class) != null; } @Override public Object resolveArgument(MethodParameter methodparameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { CustomParameter customParameter = methodparameter.getParameterAnnotation(CustomParameter.class); String parameter = webRequest.getParameter(CustomParameter.value()); // todo: do Validation here if (customParameter == null) { if (Parameter.required()) { String customInfo = customParameter.customInfo(); String body getBody(customInfo); new ResponseEntity(body, 400); // so the problem is here!! how do I return this response?? } } return webRequest.getParameter(customParameter.value()); } } 

我还使用webConfig“注册”了这个解析器:

 @EnableWebMvc @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addArgumentResolvers(List argumentResolvers) { argumentResolvers.add(new CustomAnnotationResolver()); } } 

任何有关此实现的帮助或任何其他如何做到这一点的建议都会很棒。 谢谢大家:)

我迟到了,这是一个简单的例子,说明如何捕捉朗姆酒错误并以简单的方式翻译响应。

TranslationController:

 @ControllerAdvice public class ExceptionTranslator { private final Logger log = LoggerFactory.getLogger(ExceptionTranslator .class); @ExceptionHandler(RuntimeException.class) public ResponseEntity processRuntimeException(HttpServletRequest req, RuntimeException ex) throws Exception { ErrorDTO errorDTO; ResponseStatus responseStatus = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class); if (responseStatus != null) { errorDTO = new ErrorDTO(req.getRequestURI(), responseStatus.value().toString(), ex.getMessage()); } else { errorDTO = new ErrorDTO(req.getRequestURI(), HttpStatus.INTERNAL_SERVER_ERROR.toString(), ex.getMessage()); } log.debug(errorDTO.toString()); return new ResponseEntity(errorDTO, HttpStatus.valueOf(Integer.valueOf(errorDTO.getCode()))); } } 

DTO类定义要显示的属性

 public class ErrorDTO implements Serializable { private static final long serialVersionUID = 1L; private final String uri; private final String code; private final String description; public ErrorDTO(String message) { this(null, message, null); } public ErrorDTO(String uri, String code, String description) { this.uri = uri; this.code = code; this.description = description; } public String getUri() { return uri; } public String getCode() { return code; } public String getDescription() { return description; } @Override public String toString() { return "ErrorDTO{" + "uri=" + uri + ", code=" + code + ", description=" + description + '}'; } } 

如果您需要自定义MissingServletRequestParameterException处理,我会将其添加到控制器或控制器建议中:

 @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public Map handleMissingParam(MissingServletRequestParameterException e) { Map result = new HashMap(); result.put("status", Integer.toString(400)); Map error = new HashMap(); error.put("param", e.getParameterName()); result.put("error", error); return result; } 

您当然可以用java对象替换Map的使用。 我个人建议你使用原始的error handling,除非你有一个真正的原因。

谢谢@growlingchaos,辉煌,这就是解决方案。

 @ControllerAdvice @RestController public class customExceptionAdvice { @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ResponseEntity handleConflict(BadRequestException e, HttpServletResponse response) throws IOException { return new ResponseEntity(e.getErrorBody(), HttpStatus.BAD_REQUEST); }