在 JSON 对象中强制实施非空字段

2022-09-01 07:45:19

我们的 REST API 接收一些 JSON 对象输入,其中某些字段必须不为 null。这些可以是字符串/整数,甚至可能是其他一些类实例作为参考。

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

if (myObject.getSomeOtherObject() == null)
    throw new SomeException();

我们想要的是这样的:

class MyObject{
    @Required
    OtherObject someOtherObject;
    // ...
}

我们尝试了3件事:

1)升级到jackson 2.0.6并使用notification com.fasterxml.jackson.annotation.JsonProperty但是,这看起来不起作用。找到这些参考资料:http://jira.codehaus.org/browse/JACKSON-767

2)扩展JsonDeserializer以检查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<T> type = (Class<T>) 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;

3)编写我们自己的注释并尝试使用ResourceFilter进行检查,但似乎我无法从ContainerRequest中获取实际对象,即使我们可以,也不确定如何执行对空引用的深度检查@Requiredobject.otherObject.someObject.fieldNotNullable

private class Filter implements ResourceFilter, ContainerRequestFilter {
    private final ArrayList<String> requiredParameters;

    protected Filter() {
        requiredParameters = null;
    }

    protected Filter(ArrayList<String> 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<String, String> params = request.getQueryParameters();
            params.putAll(request.getFormParameters());
            StringBuffer missingParams = new StringBuffer();
            for (String reqParam : requiredParameters) {
                List<String> 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;
    }
}

答案 1

JAX-RS很好地将反序列化与验证分开,即JSON-B(或Jackson)在设计上没有强制值的机制,等等。相反,您可以使用BeanValidation来实现以下目的:non-null

  1. 将依赖项添加到作用域中。javax.validation:validation-apiprovided
  2. 将批注添加到字段中。javax.validation.constraints.NotNull

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


答案 2

@Required是注入豆子的Spring框架注释,所以我想说不要用它来达到这个目的。

你可以改用这个:

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

@NotNull String myString;

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