【问题标题】:How to find out whether a ConstraintViolation is from a JSON property or from a URL parameter?如何确定 ConstraintViolation 是来自 JSON 属性还是来自 URL 参数?
【发布时间】:2018-10-18 08:05:33
【问题描述】:

我有一个代码可以从用户那里获取数据并验证它是否有效。

验证来自URL的数据和来自JSON的数据。

问题是在 URL 的情况下,路径字段包含arg0,它需要我从message 中获取:

@ValidId (message = "The field is invalid")
private Long field;

字段注释。

如果是JSON,我只需从path.substring(path.lastIndexOf('.') + 1) 获取字段。

protected String buildErrorMessage(ConstraintViolation<?> violation) {
    String path = violation.getPropertyPath().toString();
    String field = path.substring(path.lastIndexOf('.') + 1);
    //field = `arg0` in case of url
    //field = `field` in case of JSON
}

如果我面临 ConstraintViolation - 我怎样才能知道违规是来自JSON 还是GET


编辑

这是我调用 buildErrorMessage 的地方 -

public class ValidationExceptionMapper implements ExceptionMapper<ValidationException> {

    @Override
    public Response toResponse(ValidationException exception) {

        if (exception instanceof ConstraintViolationException) {

            final ConstraintViolationException constraint = (ConstraintViolationException) exception;

            for (final ConstraintViolation<?> violation : constraint.getConstraintViolations()) {
                String message = buildErrorMessage(violation); //HERE
            }
}

【问题讨论】:

  • 您可以先尝试从网络浏览器调用该 URL。在您开始在代码中使用它之前,请确保 JSON 是正确的。
  • 其实我说的是在普通跑步中发现。不测试。我想看看如何只用代码找出来。
  • 您能否分享更多代码并根据您使用的技术标记您的问题?是 Spring MVC 吗? JAX-RS?
  • 如 Cassio 建议的那样,如果您想回答您的问题,请添加更多详细信息和适当的重现步骤。
  • @CassioMazzochiMolin 完成。

标签: java json rest jax-rs


【解决方案1】:

GET 是指 TEXT,因为 GET 是您发送的 HTTP 请求类型,而 JSON/TEXT.... 是您发送到服务器的数据类型/格式。

你可以使用下面这段代码

 String contentType = request.getContentType();
          if (contentType != null && !contentType.toLowerCase(Locale.US).startsWith(MediaType.APPLICATION_JSON)) {
           //Request is JSON type
          }
    else {
    //Request is TEXT 
    }

它检查请求的 ContentType,是 JSON 还是 TEXT

【讨论】:

  • 我需要从 ConstraintViolation 中获取,而不是从请求中获取
【解决方案2】:

在实施ExceptionMapper 以检查ConstraintViolation 是否与在 URL 中发送的无效参数 或与无效属性相关时,以下步骤可能会有所帮助在 JSON 有效负载中发送

请记住,@QueryParam@PathParam@MatrixParam 等参数注释可以放在方法参数、资源类字段或资源类 bean 属性中。


我建议您查看我在GitHub 中对ConstraintViolationExceptionExceptionMapper 实现。

【讨论】:

  • 确实 - URL 有 PARAMETER 作为一种类型,JSON 有 PROPERTY
  • @Dvir 正如我在回答中提到的,请注意@QueryParam@PathParam@MatrixParam 等参数注释可以放在方法参数、资源类字段或资源类中bean 属性。
【解决方案3】:

如果你使用spring,你可以通过静态方法获取当前请求,并检查它的类型。

public static HttpServletRequest getCurrentHttpRequest(){
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    if (requestAttributes instanceof ServletRequestAttributes) {
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        return request;
    }
    logger.debug("Not called in the context of an HTTP request");
    return null;
}

 if(getCurrentHttpRequest().getMethod().toLowerCase()=='get'){
     // text
 }

【讨论】:

  • 它是如何回答问题的?
  • 在ValidationExceptionMapper中,获取CurrentHttpRequest,判断是否为http get方法。因为post o put会在body中收到json。
  • 一旦 OP 使用 JAX-RS 并假设应用程序部署到 servlet 容器,他们可以简单地使用 @ContextExceptionMapper 中注入 HttpServletRequest(参见 answer )。但这不是重点。重点是解析ConstraintViolation 以检查URL 中发送的参数中是否存在验证错误,或者JSON 有效负载中发送的属性中是否存在验证错误。详情请见我的answer
  • 解析ContraintViolation的可能实现是here
  • 是的,你是对的。如果 ContraintViolation 类型属于例外情况,则不需要额外信息。
猜你喜欢
  • 1970-01-01
  • 2012-06-18
  • 2013-11-06
  • 2011-11-03
  • 1970-01-01
  • 2013-09-14
  • 1970-01-01
  • 2013-08-06
  • 2010-11-02
相关资源
最近更新 更多