【问题标题】:Consuming Json in JAX-RS: Prohibiting null values在 JAX-RS 中使用 Json:禁止空值
【发布时间】:2020-05-07 09:27:50
【问题描述】:

我正在编写一个简单的 REST 服务,它需要一个包含 Json 的 POST。 该服务应该拒绝任何不包含它所期望的密钥的 Json。 我在 JBoss EAP 7.1 上使用 JAX-RS,但无法做到这一点。代码示例:

import javax.ejb.Stateless;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/")
@Stateless
@Produces("text/plain")
public class TestAccess
{
  @POST
  @Path("test/")
  @Consumes(MediaType.APPLICATION_JSON)
  public String consumeJson(TestClass c)
  {
    return c.toString();
  }

}
public class TestClass
{
  public String first;
  public String second;

  public String toString()
  {
    return (first + ", " + second);
  }
}

之前我写了consumeJson 期望得到JsonObject 并使用Jackson ObjectMapper 解析它。这样做会导致在接收 Json 缺失键时出错。我认为我现在这样做的方式是一种“更清洁”的方式,因为现在参数列表清楚地显示了 Json 应该描述什么样的对象。但是,我不想首先检查方法中的每个字段,也不想将isValid() 方法添加到以这种方式获得的每个对象。

示例 {"first" : "contentOfFirst"} 返回 "contentOfFirst, null" 而不是失败。

编辑:为了澄清,我尝试了这样的事情:

import javax.validation.constraints.NotNull;

public class TestClass
{
  @NotNull
  public String first;
  @NotNull
  public String second;

  public String toString()
  {
    return (first + ", " + second);
  }
}

这并没有改变结果,而不是失败(因为它应该),POST 仍然得到响应 "contentOfFirst, null"。我知道这些注释仍然需要一个验证器来验证它们。我(错误地?)以为 Jboss 提供了这样的验证器。

【问题讨论】:

    标签: java jboss jax-rs jboss7.x java-ee-8


    【解决方案1】:

    原来我错过了您需要另一个注释来执行检查:

      @POST
      @Path("test/")
      @Consumes(MediaType.APPLICATION_JSON)
      public String consumeJson(@Valid TestClass c)
      {
        return c.toString();
      }
    

    这就是 JBoss 实际执行检查所需的全部内容。

    需要注意的是,JBoss 不喜欢在同一个参数列表中使用@Valid 和泛型类(如List<PathSegment>)。

    【讨论】:

      【解决方案2】:

      现代 jackson 版本有 @JsonCreator 和 @JsonProperty 在反序列化期间进行一些验证,例如对于你的情况:

      public class TestClass
      {
          @JsonCreator
          TestClass(
                  @JsonProperty(value = "first", required = true) Integer first,
                  @JsonProperty(value = "second", required = true) Integer second) {
              this.first = first;
              this.second= second;
          }
          public String first;
          public String second;
      
          public String toString()
          {
              return (first + ", " + second);
          }
      }
      

      更强大的解决方案是使用Bean Validation

      【讨论】:

      • 正如我在原始帖子中所指出的,我知道像 @NotNull 这样的注释。然而,我没有成功利用这些。该框架似乎不尊重注释。
      • 我没有写任何关于 @NotNull 的文章,抱歉。它用于文档目的。有一个separate thread on this issue。请查看JsonCreator 的文档。或者创建失败的测试用例。
      猜你喜欢
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2020-10-27
      相关资源
      最近更新 更多