我们的REST API接收一些JSON对象输入,其中某些字段必须不为null . 那些可以是String / Integer,也可以是其他类实例作为引用 .
我们试图找到一种方法来强制这些字段不为空,而不是在api中进行空检查的正确方法 . 当前:
if (myObject.getSomeOtherObject() == null)
throw new SomeException();
我们想拥有的是:
class MyObject{
@Required
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<T> extends JsonDeserializer<T> {
@Override
public T deserialize(JsonParser jsonparser, DeserializationContext deserializationcontext) throws IOException, JsonProcessingException {
ParameterizedType superClass = (ParameterizedType) getClass().getGenericSuperclass();
Class type = (Class) superClass.getActualTypeArguments()[0];
T t = jsonparser.readValueAs(type);
if (t == null){
String classNameField = type.getName();
String field = jsonparser.getCurrentName();
throw new WrongInputException("The field '"+field+"' of type '"+classNameField+"' should not be null.");
}
return t;
}
}
public class NotNullAddressDeserializer extends NotNullDeserializer<Address> {
}
@JsonDeserialize(using=NotNullAddressDeserializer.class)
Address to;
- 编写我们自己的@Required注释并尝试使用ResourceFilter进行检查,但似乎我无法从ContainerRequest获取实际对象,即使我们可以,也不确定如何在object.otherObject.someObject.fieldNotNullable中执行对空引用的深度检查
private class Filter implements ResourceFilter, ContainerRequestFilter {
private final ArrayList requiredParameters;
protected Filter() {
requiredParameters = null;
}
protected Filter(ArrayList requiredParameters) {
this.requiredParameters = requiredParameters;
}
@Override
public ContainerRequestFilter getRequestFilter() {
return this;
}
@Override
public ContainerResponseFilter getResponseFilter() {
return null;
}
@Override
public ContainerRequest filter(ContainerRequest request) {
if (requiredParameters != null && requiredParameters.size() > 0) {
MultivaluedMap params = request.getQueryParameters();
params.putAll(request.getFormParameters());
StringBuffer missingParams = new StringBuffer();
for (String reqParam : requiredParameters) {
List paramValues = params.get(reqParam);
if (paramValues == null || paramValues != null && paramValues.size() == 0)
missingParams.append(reqParam + ",");
}
if (missingParams.length() > 0)
throw new WrongInputException("Required parameters are missing: " + missingParams);
}
return request;
}
}
任何帮助和见解表示赞赏 .
4 回答
JAX-RS很好地区分了验证中的反序列化,即Jackson在设计上没有任何机制来强制值为
non-null
等 . 相反,您可以使用BeanValidation:在
provided
范围内向javax.validation:validation-api
添加依赖项 .将
javax.validation.constraints.NotNull
注释添加到您的字段中 .有关详细信息,请转到here .
你可以使用JSON-SCHEMA,因为你可以用JSON字段表达许多约束:http://json-schema.org/
然后,您可以使用@NotNull JSR 303注释从模式生成java类,并在对象上使用bean验证 . 它本身与 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
以及Hibernate验证程序包来强制执行not null
验证 .如果您使用Maven,那么您可以使用以下依赖项:
然后你的代码必须将一些JSON转换为带注释的对象,你需要使用
javax.validation.Validator
来验证对象 . 下面是一些示例代码,演示如何完成此操作(请参阅相关的validate
方法):以下是使用验证注释的示例类: