2016-12-21 12 views
1

Problemkann nicht leere Zeichenfolge auf null über Jackson2ObjectMapperBuilder DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT

Ich versuche zu haben Jackson gesetzt jede Empty String zu null dies innerhalb einer Spring-boot Anwendung bekommen. Wir haben unserem POJO eine Validierung hinzugefügt, um zu überprüfen, ob der Wert zwischen 1 und 255 IFF liegt, der Wert wird gesetzt.

@Size(min = 1, max = 255) 
@Column(length = 255) 
private String businessTitle; 

Das Problem ist, dass, wenn ein Empty String die Validierung übergeben wird es mit einer javax.validation.ConstraintViolationException Ausnahme fehl, weil es die leere Zeichenkette überprüft.

Ich habe versucht, DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT auf dem Jackson2ObjectMapperBuilder so einzurichten, dass es diese leeren Zeichenfolgen als null festlegen würde und die Überprüfung nicht fehlschlagen würde. Dies geschieht jedoch nicht, es wird weiterhin die Empty String in die save() für das Objekt übergeben.

Frage

Was nicht in Ordnung ist oder muss die Empty String richtig null gesetzt haben eingestellt werden, wenn die Ojbject zu speichern?

-Code

Objekt

@Size(min = 1, max = 255) 
@Column(length = 255) 
private String businessTitle; 

JacksonConfiguration

@Configuration 
public class JacksonConfiguration { 


    @Bean 
    public Jackson2ObjectMapperBuilder filteringObjectMapperBuilder() { 
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder(); 
    builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); 
    builder.featuresToEnable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); 

    return builder; 
    } 
} 

Exception

Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com..model.User] during update time for groups [javax.validation.groups.Default, ] 
List of constraint violations:[ 
     ConstraintViolationImpl{interpolatedMessage='size must be between 1 and 255', propertyPath=businessTitle, rootBeanClass=class com..model.User, messageTemplate='{javax.validation.constraints.Size.message}'} 
] 
     at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138) 
     at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(BeanValidationEventListener.java:86) 
     at org.hibernate.action.internal.EntityUpdateAction.preUpdate(EntityUpdateAction.java:244) 
     at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:118) 
     at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582) 
     at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456) 
     at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) 
     at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) 
     at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282) 
     at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:465) 
     at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2963) 
     at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2339) 
     at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:485) 
     at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:147) 
     at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38) 
     at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:231) 
     at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:65) 
     at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:61) 
     ... 127 common frames omitted 
+0

Haben Sie das gelesen? http://stackoverflow.com/questions/22688713/jackson-objectmapper-deserializationconfig-feature-accept-empty-string-as-null-o – Adam

Antwort

0

Eigentlich gibt es eine bessere Lösung, als sie auf jedes Attribut zu setzen. Erstellen Sie einen benutzerdefinierten Deserializer, EmptyToNullStringDeserializer, um '' in null zu ändern. Dies basiert auf einer Mitarbeiterlösung.

builder 
    .deserializerByType(String.class, new EmptyToNullStringDeserializer()); 
2

DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT wird Ihnen nicht helfen, weil es „deserialise leeren String JSON-Wert als null für Objektfeld“ bedeutet, und leider Ihre String Felder sind Skalare nicht JSON-Objekte. Ich denke, es gibt keinen bequemen Weg, um Verhalten zu bekommen, das Sie wollen. Es ist möglich, das Deserialisierungsverhalten für alle Felder mit dem Typ String zu überschreiben, aber Sie möchten es möglicherweise nicht. Sie können auch benutzerdefinierte deserialzer definieren, aber Sie werden jedes Feld wie folgt zu annotieren müssen:

@JsonDeserialize(using = MyStringDeseralizer.class) 
private String businessTitle; 

wo class MyStringDeseralizer extends JsonDeserializer<String> und implementieren Umwandlungslogik Sie benötigen.

+0

Vielen Dank. Ich habe irgendwo gelesen, dass ich in einigen anderen Posts ein benutzerdefiniertes JsonDeserialize eingerichtet habe, während ich nach Lösungen gesucht habe. Ich werde einen Blick darauf werfen. – ALM

+0

Ein Mitarbeiter hat eine bessere Lösung gefunden, als ihn auf jedes Attribut zu setzen, und Sie können ihn bei der Deserialisierung für jeden String.class-Typ erstellen. Ich habe die obige Lösung gepostet. – ALM

Verwandte Themen