【问题标题】:Spring validation : Custom validate @RequestBody based on criteria @RequestParamSpring验证:自定义验证@RequestBody基于标准@RequestParam
【发布时间】:2019-10-14 06:00:02
【问题描述】:

我想用@Valid 注解验证请求体。 在该方法中有一个 @RequestParam 值。 如果这个@RequestParam 值“min”,我希望requestbody 中的一个字段是强制性的。可以用注解吗?

@RequestMapping(method = RequestMethod.POST, value = ProductionResponse.URL, produces = JWSMessageConverter.JWS_MEDIA_TYPE_VALUE)
@ResponseBody
public ResponseEntity<ProductionResponse> richiestaProduzione(@RequestParam("issuerType") String issuerType,
        @RequestParam("issuerCode") String issuerCode, @RequestParam("procedureId") String procedureId,
        @Valid @RequestBody ProductionRequestResource requestBody) {
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("POST " + ProductionResponse.URL);
  @Valid ProductionRequestResource fff = requestBody;
    requestBody.setProcedureResource(issuerType, issuerCode, procedureId);

    try {
        ProductionResponse response = produzioneService.richiestaProduzione(requestBody);
        return ResponseEntity.ok(response);
    } catch (Exception e) {
        LOGGER.error(e.getMessage(), e);
        return ResponseEntity.badRequest().body(ProductionResponse.ko(requestBody, e.getMessage(), requestBody.getNun()));
    }
}

如果 issuerType 等于“MIN”,我希望 ProductionRequestResource 中的字段 issuerMunicipalityCode 是强制性的。

【问题讨论】:

  • 你的问题有点误导,所以格式化了。
  • 您需要为您的场景实施自定义验证。您可以在stackoverflow.com/questions/25075683/… 找到解决方案
  • 是的,但是我如何访问请求中的字段 issuerType,并使用它来验证我的请求正文?
  • ProductionRequestResource pojo 对象中没有 issuerType 吗?如果没有,那么你需要在不使用spring验证框架的情况下进行验证。
  • 不,我在 productionrequestresource pojo 中没有问题类型。我需要一个关于如何在没有弹簧验证的情况下进行验证的建议。我需要使用消息资源进行国际化。

标签: spring validation


【解决方案1】:

为了进一步继续,这里是您可以实现自定义验证的方法。

添加验证以在 issueType 为 MIN 且市政代码为空/null 时引发异常。

@RequestMapping(method = RequestMethod.POST, value = ProductionResponse.URL, produces = JWSMessageConverter.JWS_MEDIA_TYPE_VALUE)
@ResponseBody
public ResponseEntity<ProductionResponse> richiestaProduzione(@RequestParam("issuerType") String issuerType,
        @RequestParam("issuerCode") String issuerCode, @RequestParam("procedureId") String procedureId,
        @RequestBody ProductionRequestResource requestBody) {
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("POST " + ProductionResponse.URL);

    if("MIN".equals(issuerType) && StringUtils.isEmpty(requestBody.getIssuerMunicipalityCode())) {
        throw new IllegalArgumentException("IssuerMuncipalityCode can't be null when IssuerType is MIN");
    }

    try {
        ProductionResponse response = produzioneService.richiestaProduzione(requestBody);
        return ResponseEntity.ok(response);
    } catch (Exception e) {
        LOGGER.error(e.getMessage(), e);
        return ResponseEntity.badRequest().body(ProductionResponse.ko(requestBody, e.getMessage(), requestBody.getNun()));
    }
}

实现异常处理程序以捕获异常并根据异常类型构建响应体。上面抛出的 InvalidArgumentSuppliedException 将被下面的异常处理程序捕获。异常处理程序是在单独的组件中处理异常的最佳实践。

@ControllerAdvice
public class ScnSchedulerExceptionHandler {

    @ExceptionHandler(InvalidArgumentSuppliedException.class)
    public final ResponseEntity<Object> handleInvalidArgException(Exception ex) {
        ErrorResponseDTO errorDTO = new ErrorResponseDTO();
        errorDTO.setMessage(ex.getMessage());
        return new ResponseEntity<>(errorDTO, HttpStatus.NOT_ACCEPTABLE);
    }

    @ExceptionHandler(Exception.class)
    public final ResponseEntity<Object> handleAllExceptions(Exception ex) {
        ErrorResponseDTO errorDTO = new ErrorResponseDTO();
        errorDTO.setMessage("Internal server error occurred.");
        return new ResponseEntity<>(errorDTO, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

在异常处理程序中,将错误消息包装在 pojo 对象中。

public class ErrorResponseDTO {

    private String errorMessage;

}

【讨论】:

  • 我编写了一个自定义验证器,并使用 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 获取 PathVariable 字段
猜你喜欢
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-07
  • 2022-01-23
  • 2013-08-18
  • 1970-01-01
  • 2017-03-13
相关资源
最近更新 更多