【问题标题】:Spring Web Mvc REST ValidationSpring Web Mvc REST 验证
【发布时间】: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


【解决方案1】:

@ResponseStatus(HttpStatus.BAD_REQUEST) 会将状态码设置为 400。但是,.andExpect(status().isOk()) sn-p 会将状态码与 200 进行比较,这将导致测试失败并打印内容的行永远都达不到。

【讨论】:

  • 感谢您指出这一点。这是真的,我已经对这个问题进行了更正。但是,我需要某种响应,应该是 json 或 xml,我没有得到。响应是空的。
猜你喜欢
  • 2013-04-14
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 2013-03-05
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
相关资源
最近更新 更多