在JSON对象中强制执行非空字段

我们的REST API接收一些JSON对象输入,其中某些字段必须不为null。 这些可以是String / Integer,也可以是其他类实例作为引用。

我们试图找到一种方法来强制这些字段不为空,而不是在api中进行空检查的正确方法。 当前:


     if(myObject.getSomeOtherObject()== null)
    抛出新的SomeException();

我们想拥有的是:


     class MyObject {
     @需要
     OtherObject someOtherObject;
     ...
     }

我们尝试了3件事:

  • 升级到jackson 2.0.6并使用注释com.fasterxml.jackson.annotation.JsonProperty但是,这看起来不起作用。 找到了这些参考文献: http : //jira.codehaus.org/browse/JACKSON-767

  • 扩展JsonDeserializer以检查null但问题是它甚至没有在null输入上执行。


     public class NotNullDeserializer  extends JsonDeserializer  {

         @覆盖
         public T反序列化(JsonParser jsonparser,DeserializationContext deserializationcontext)抛出IOException,JsonProcessingException {

             ParameterizedType superClass =(ParameterizedType)getClass()。getGenericSuperclass();
            类类型=(类)superClass.getActualTypeArguments()[0];

             T t = jsonparser.readValueAs(type);

             if(t == null){
                 String classNameField = type.getName();
                 String field = jsonparser.getCurrentName();
                抛出新的WrongInputException(“字段'”+字段+“'类型'”+ classNameField +“'不应该为空。”);
             }

            返回;
         }

     }

    公共类NotNullAddressDeserializer扩展NotNullDeserializer 
{ } @JsonDeserialize(使用= NotNullAddressDeserializer.class) 写给;
  • 编写我们自己的@Required注释并尝试使用ResourceFilter进行检查,但似乎我无法从ContainerRequest获取实际对象,即使我们可以,也不确定如何在object.otherObject.someObject.fieldNotNullable中执行对空引用的深度检查

     private class Filter实现ResourceFilter,ContainerRequestFilter {

         private final ArrayList requiredParameters;

         protected Filter(){
             requiredParameters = null;
         }

         protected Filter(ArrayList requiredParameters){
             this.requiredParameters = requiredParameters;
         }

         @覆盖
         public ContainerRequestFilter getRequestFilter(){
            归还这个;
         }

         @覆盖
         public ContainerResponseFilter getResponseFilter(){
             return null;
         }


         @覆盖
         public ContainerRequestfilter(ContainerRequest请求){
             if(requiredParameters!= null && requiredParameters.size()> 0){
                 MultivaluedMap params = request.getQueryParameters();
                 params.putAll(request.getFormParameters());
                 StringBuffer missingParams = new StringBuffer();
                 for(String reqParam:requiredParameters){
                    列表paramValues = params.get(reqParam);
                     if(paramValues == null || paramValues!= null && paramValues.size()== 0)
                         missingParams.append(reqParam +“,”);
                 }
                 if(missingParams.length()> 0)
                    抛出新的WrongInputException(“缺少必需的参数:”+ missingParams);
             }
            退货要求;
         }
     }

任何帮助和见解表示赞赏。

JAX-RS很好地将反序列化与validation分开,即Jackson没有设计任何机制来强制值为non-null等等。相反,您可以使用BeanValidation:

  1. provided范围中向javax.validation:validation-api添加依赖javax.validation:validation-api
  2. javax.validation.constraints.NotNull注释添加到您的字段中。

有关详细信息,请转到此处 。

您可以使用JSON-SCHEMA,因为您可以使用它来表达JSON字段的许多约束: http : //json-schema.org/

然后,您可以使用@NotNull JSR 303注释从模式生成Java类,并在对象上使用beanvalidation。 它本身与jackson合作,所以你不应该有任何问题。

例如,您可以使用maven插件执行此操作: http : //wiki.jsonschema2pojo.googlecode.com/git/site/0.3.7/generate-mojo.html

@Required是注入bean的Spring框架注释,所以我要说不要将它用于此目的。

您可以使用此代码:

http://robaustin.wikidot.com/annotations-and-notnull

@NotNull String myString;

有关运行时检查,请尝试http://code.google.com/p/notnullcheckweaver/

您可以结合使用Jackson JSON库和javax.validation以及Hibernatevalidation程序包来强制执行not nullvalidation。

如果您使用的是Maven,那么您可以使用以下依赖项:

   com.fasterxml.jackson.core jackson-core ${jackson-version}   com.fasterxml.jackson.core jackson-annotations ${jackson-version}   com.fasterxml.jackson.core jackson-databind ${jackson-version}    javax.validation validation-api 2.0.1.Final   org.hibernate.validator hibernate-validator ${hibernate-validator.version}   org.hibernate.validator hibernate-validator-annotation-processor ${hibernate-validator.version}   javax.el javax.el-api 3.0.0   org.glassfish.web javax.el 2.2.6   

然后你的代码必须将一些JSON转换为带注释的对象,你需要使用javax.validation.Validatorvalidation对象。 以下是一些示例代码,演示了如何完成此操作(请参阅相关的validate方法):

 public class ShareLocationService { private ObjectMapper mapper = new ObjectMapper(); private ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); // Materialize the Java object which contains the validation annotations public ShareLocation readFrom(String json) throws IOException { return mapper.readerFor(ShareLocation.class).readValue(json); } // validate and collect the set of validations public Set validate(String json) throws IOException { ShareLocation shareMyLocation = readFrom(json); Validator validator = factory.getValidator(); Set> violations = validator.validate(shareMyLocation); return violations.stream().map(Object::toString).collect(Collectors.toSet()); } } 

以下是使用validation注释的示例类:

 public class ShareLocation { @JsonProperty("Source") @NotNull private String source; @JsonProperty("CompanyCode") private String companyCode; @JsonProperty("FirstName") private String firstName; @JsonProperty("LastName") private String lastName; @JsonProperty("Email") private String email; @JsonProperty("MobileNumber") private String mobileNumber; @JsonProperty("Latitude") @NotNull private Double latitude; @JsonProperty("Longitude") @NotNull private Double longitude; @JsonProperty("LocationDateTime") @NotNull private String locationDateTime;