在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:
- 在
provided
范围中向javax.validation:validation-api
添加依赖javax.validation:validation-api
。 - 将
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 null
validation。
如果您使用的是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.Validator
validation对象。 以下是一些示例代码,演示了如何完成此操作(请参阅相关的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;