wake-up-neo.net

Erzwingen Sie ein nicht-null-Feld in einem JSON-Objekt

Unsere REST - API empfängt einige JSON-Objekteingaben, bei denen einige Felder nicht null sein müssen. Dies kann entweder String/Integer oder sogar eine andere Klasseninstanz als Referenz sein.

Wir versuchen, einen Weg zu finden, um zu erzwingen, dass diese Felder nicht null sind, anstatt den entsprechenden Weg für eine Nullprüfung in der API.

 if (myObject.getSomeOtherObject () == null) 
 wirft neue SomeException (); 

Was wir haben wollen, ist so etwas wie:

 Klasse MyObject {
 @Erforderlich
 OtherObject someOtherObject; 
 ...
 } 

Wir haben 3 Dinge ausprobiert:

  • Aktualisieren Sie auf jackson 2.0.6 und verwenden Sie die Annotation Com.fasterxml.jackson.annotation.JsonProperty Dies funktioniert jedoch nicht. Diese Referenzen gefunden: http://jira.codehaus.org/browse/JACKSON-767

  • Erweiterung von JsonDeserializer zur Überprüfung von NULL, aber das Problem ist, dass es nicht einmal für die Nulleingabe ausgeführt wird.

 Die öffentliche Klasse NotNullDeserializer <T> erweitert JsonDeserializer <T> {

 @Override 
 public T deserialize (JsonParser jsonparser, DeserializationContext Deserializationcontext) löst IOException, JsonProcessingException {
.__ aus. ParameterizedType superClass = (ParameterizedType) getClass (). GetGenericSuperclass (); 
 Klassentyp = (Klasse) superClass.getActualTypeArguments () [0]; 

 T t = jsonparser.readValueAs (Typ); 

 if (t == null) {
 String classNameField = type.getName (); 
 String field = jsonparser.getCurrentName (); 
 Neue WrongInputException werfen ("Das Feld '" + field + "' vom Typ '" + classNameField + "' sollte nicht null sein."); 
 } 

 Rückgabe t; 
 } 

 } 

 Die öffentliche Klasse NotNullAddressDeserializer erweitert NotNullDeserializer <Adresse> {

 } 

 @JsonDeserialize (using = NotNullAddressDeserializer.class) 
 Richten an;

  • Wir schreiben unsere eigene @Required-Annotation und versuchen, mit ResourceFilter zu prüfen, aber es scheint, dass ich das eigentliche Objekt nicht von ContainerRequest abrufen kann. Selbst wenn wir könnten, sind wir uns nicht sicher, wie eine gründliche Überprüfung der Null-Referenz in object.otherObject.someObject.fieldNotNullable ausgeführt werden kann
 private class Filter implementiert ResourceFilter, ContainerRequestFilter {

 private final ArrayList requiredParameters; 

 Geschützter Filter () {
 requiredParameters = null; 
 } 

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

 @Override 
 public ContainerRequestFilter getRequestFilter () {
 zurückgeben; 
 } 

 @Override 
 public ContainerResponseFilter getResponseFilter () {
 Rückgabe null; 
 } 


 @Override 
 public ContainerRequest-Filter (ContainerRequest-Anforderung) {
 if (requiredParameters! = null && requiredParameters.size ()> 0) {
 MultivaluedMap params = request.getQueryParameters (); 
 params.putAll (request.getFormParameters ()); 
 StringBuffer missingParams = new StringBuffer (); 
 for (String reqParam: requiredParameters) {
 Liste paramValues ​​= params.get (reqParam); 
 if (paramValues ​​== null || paramValues! = null && paramValues.size () == 0) 
 missingParams.append (reqParam + ","); 
 } 
 if (missingParams.length ()> 0) 
 werfen Sie eine neue WrongInputException aus ("Erforderliche Parameter fehlen:" + missingParams); 
 } 
 Rückgabeanforderung; 
 } 
 } 


.__ Jede Hilfe und Einsichten geschätzt.

19
urir

JAX-RS trennt die Deserialisierung recht gut von der Validierung, d. H. Jackson hat by design keinen Mechanismus, um Werte als non-null zu erzwingen, usw. Stattdessen können Sie die BeanValidation dafür verwenden:

  1. Fügen Sie javax.validation:validation-api in provided eine Abhängigkeit hinzu.
  2. Fügen Sie Ihrem Feld die Annotation javax.validation.constraints.NotNull hinzu.

Für weitere Informationen gehen Sie zu hier .

23
rü-

Sie können JSON-SCHEMA verwenden, da Sie damit viele Einschränkungen für JSON-Felder ausdrücken können: http://json-schema.org/

Anschließend können Sie aus dem Schema Ihre Java-Klassen mit @NotNull JSR 303-Annotationen generieren und die Bean-Validierung für Ihr Objekt verwenden. Es funktioniert nativ mit Jackson, also sollten Sie keine Probleme haben.

So können Sie beispielsweise das Plugin maven verwenden: http://wiki.jsonschema2pojo.googlecode.com/git/site/0.3.7/generate-mojo.html

2
zenbeni

@Required ist eine Spring-Framework-Anmerkung für injizierte Beans. Ich würde also sagen, dass Sie sie nicht für diesen Zweck verwenden sollten.

Sie können dieses stattdessen verwenden:

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

@NotNull String myString;

Versuchen Sie zur Laufzeitüberprüfung http://code.google.com/p/notnullcheckweaver/

1
Adam Adamaszek

Sie können die not null-Überprüfung mithilfe einer Kombination der Jackson JSON-Bibliothek und des javax.validation zusammen mit dem Hibernate-Validiererpaket erzwingen. 

Wenn Sie Maven verwenden, können Sie folgende Abhängigkeiten verwenden:

<dependencies>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson-version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>2.0.1.Final</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>${hibernate-validator.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator-annotation-processor</artifactId>
        <version>${hibernate-validator.version}</version>
    </dependency>

    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>3.0.0</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>javax.el</artifactId>
        <version>2.2.6</version>
    </dependency>

</dependencies>

Dann muss Ihr Code einige JSON-Dateien in Ihr mit Anmerkungen versehenes Objekt konvertieren, und Sie müssen das Objekt mit javax.validation.Validator überprüfen. Hier ist ein Beispielcode, der zeigt, wie dies möglich ist (siehe die entsprechende validate-Methode):

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<String> validate(String json) throws IOException {
        ShareLocation shareMyLocation = readFrom(json);
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<ShareLocation>> violations = validator.validate(shareMyLocation);
        return violations.stream().map(Object::toString).collect(Collectors.toSet());
    }
}

Hier ist eine Beispielklasse, die die Validierungsanmerkungen verwendet:

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;
0
gil.fernandes