【发布时间】:2014-09-11 17:23:06
【问题描述】:
请参阅下面的更新。
我正在尝试验证传入以下 RESTful 端点的参数。
@Controller
@RequestMapping(GlobalConstants.SERVICE_BASE_URL)
public class AuctionsController {
...
@ResponseBody
@RequestMapping( produces = {"application/json", "application/xml"},
method = RequestMethod.GET,
value = "v001/test")
public CommissionsResponse getAuctionCommission( @RequestParam(required = true) Integer someInteger,
@RequestParam(required = false) Integer otherInteger,
@RequestParam(required = true) BigDecimal price,
@RequestParam(required = true) String name) {
MyResponse response = new MyResponse();
response.setSomeInteger(someInteger);
response.setOtherInteger(otherInteger);
response.setPrice(price);
response.setName(name);
return response;
}
}
讨论了here 如何使用 Spring 的 Web MVC 验证参数。他为此创建了一个处理程序,我将它放在一个 ExceptionHandlers 类中,以及一个错误 bean:
UPDATE-1::: 下面的方法采用 MethodArgumentNotValidException,它只在 bean 无效时才有效(也就是说,bean 将是控制器类中标有注解的参数@有效的)。所以这永远不会奏效。但是,在最终用户输入错误参数的情况下,我仍然希望能够处理 400。也就是说,例如,当用户为应该是 BigDecimal 的参数输入字符串时。
@ControllerAdvice
public class ExceptionHandlers {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorMessage handleException(MethodArgumentNotValidException ex) {
List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
List<ObjectError> globalErrors = ex.getBindingResult().getGlobalErrors();
List<String> errors = new ArrayList<>(fieldErrors.size() + globalErrors.size());
String error;
for (FieldError fieldError : fieldErrors) {
error = fieldError.getField() + ", " + fieldError.getDefaultMessage();
errors.add(error);
}
for (ObjectError objectError : globalErrors) {
error = objectError.getObjectName() + ", " + objectError.getDefaultMessage();
errors.add(error);
}
return new ErrorMessage(errors);
}
}
..还有错误 bean
@XmlRootElement
public class ErrorMessage {
private List<String> errors;
public ErrorMessage() {
}
public ErrorMessage(List<String> errors) {
this.errors = errors;
}
public ErrorMessage(String error) {
this(Collections.singletonList(error));
}
public ErrorMessage(String ... errors) {
this(Arrays.asList(errors));
}
public List<String> getErrors() {
return errors;
}
public void setErrors(List<String> errors) {
this.errors = errors;
}
}
我已经使用下面的方法来尝试捕获 400,这是在下面的测试中抛出的。在这里,我试图通过使用不正确的价格参数值来抛出 400。
@Test
public void testTheEndpoint() throws Exception {
String url = "v001/test?someInteger=21&otherInteger=456&price=NOT_A_BIG_DECIMAL&name=test";
log.info("Testing Endpoint::: " + url);
MvcResult result = mockMvc.perform(get(url))
.andReturn();
log.info("RESPONSE::: " + result.getResponse().getContentAsString());
}
但是,我使用它没有收到错误 xml 响应。相反,我的测试以 400 失败。有人介意告诉我我在这里做错了什么吗?谢谢!
【问题讨论】:
-
您没有向我们展示足够的代码来确定,但我怀疑您在定义错误处理方法的类上没有 @ControllerAdvice。
-
感谢您的评论。我已经更新了我的帖子以包含大部分课程。最初错误处理是在主控制器中完成的。我已经将它提取出来并放入一个带有 ControllerAdvice 注释的 ExceptionHandlers 类,但我仍然没有得到 json 或 xml 响应,只有 400。
-
你用的是什么版本的 Spring?
-
org.springframework:spring-webmvc:4.1.0.RELEASE
标签: java spring validation spring-mvc