62 Stimmen

Kann Jackson so konfiguriert werden, dass er führende und abschließende Leerzeichen aus allen String-Eigenschaften entfernt?

Beispiel JSON (beachten Sie, dass die Zeichenfolge Leerzeichen am Ende enthält):

{ "aNumber": 0, "aString": "string   " }

Im Idealfall hat die deserialisierte Instanz eine aString Eigenschaft mit einem Wert von "string" (d.h. ohne nachfolgende Leerzeichen). Dies scheint etwas zu sein, das wahrscheinlich unterstützt wird, aber ich kann es nicht finden (z. B. in DeserializationConfig.Feature ).

Wir verwenden Spring MVC 3.x, so dass eine Spring-basierte Lösung auch in Ordnung wäre.

Ich habe versucht, Spring's WebDataBinder zu konfigurieren, basierend auf einem Vorschlag in einem Forumsbeitrag aber es scheint nicht zu funktionieren, wenn ein Jackson Message Converter verwendet wird:

@InitBinder
public void initBinder( WebDataBinder binder )
{
    binder.registerCustomEditor( String.class, new StringTrimmerEditor( " \t\r\n\f", true ) );
}

36voto

Maciej Marczuk Punkte 3333

Einfache Lösung für Spring Boot-Benutzer: Fügen Sie einfach die SimpleModule-Erweiterung von walv zu Ihrem Anwendungskontext hinzu:

package com.example;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class StringTrimModule extends SimpleModule {

    public StringTrimModule() {
        addDeserializer(String.class, new StdScalarDeserializer<String>(String.class) {
            @Override
            public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException,
                    JsonProcessingException {
                return jsonParser.getValueAsString().trim();
            }
        });
    }
}

Eine weitere Möglichkeit, Jackson anzupassen, ist das Hinzufügen von Beans des Typs com.fasterxml.jackson.databind.Module zu Ihrem Kontext. Sie werden mit jeder Bean des Typs ObjectMapper registriert und bieten einen globalen Mechanismus, um benutzerdefinierte Module beizusteuern, wenn Sie neue Funktionen zu Ihrer Anwendung hinzufügen.

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-spring-mvc.html#howto-customize-the-jackson-objectmapper

wenn Sie pas Wenn Sie Spring Boot verwenden, müssen Sie das StringTrimModule selbst registrieren (Sie brauchen es nicht mit @Component zu annotieren)

<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
    <property name="modulesToInstall" value="com.example.StringTrimModule"/>
</bean

25voto

DCKing Punkte 4163

Mit einem benutzerdefinierter Deserialisierer könnten Sie Folgendes tun:

 <your bean>
 @JsonDeserialize(using=WhiteSpaceRemovalSerializer.class)
 public void setAString(String aString) {
    // body
 }

 <somewhere>
 public class WhiteSpaceRemovalDeserializer extends JsonDeserializer<String> {
     @Override
     public String deserialize(JsonParser jp, DeserializationContext ctxt) {
         // This is where you can deserialize your value the way you want.
         // Don't know if the following expression is correct, this is just an idea.
         return jp.getCurrentToken().asText().trim();
     }
 }

Diese Lösung impliziert, dass dieses Bean-Attribut immer auf diese Weise serialisiert wird, und Sie müssen jedes Attribut, das auf diese Weise deserialisiert werden soll, mit Anmerkungen versehen.

21voto

Eugene Maysyuk Punkte 2289

Ich denke, es ist besser, Standard StringDeserializer zu erweitern, da es bereits einige spezifische Fälle behandelt (siehe aquí y aquí ), die von Bibliotheken von Drittanbietern verwendet werden können. Unten finden Sie die Konfiguration für Spring Boot. Dies ist nur mit Jackson 2.9.0 und höher möglich, da ab der Version 2.9.0 der StringDeserializer nicht mehr final ist. Wenn Sie eine Jackson-Version unter 2.9.0 haben, können Sie trotzdem den Inhalt des StringDeserializers in Ihren Code kopieren, um die oben genannten Fälle zu behandeln.

@JsonComponent
public class StringDeserializer extends com.fasterxml.jackson.databind.deser.std.StringDeserializer {

    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = super.deserialize(p, ctxt);
        return value != null ? value.trim() : null;
    }
}

17voto

walv Punkte 2443

Das Problem der Annotation @JsonDeserialize besteht darin, dass man immer daran denken muss, sie in den Setter einzufügen. Um es global "einmal und für immer" mit Spring MVC zu machen, habe ich die nächsten Schritte gemacht:

pom.xml:

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.3.3</version>
</dependency>

Benutzerdefinierten ObjectMapper erstellen:

package com.mycompany;

    import java.io.IOException;
    import org.apache.commons.lang3.StringUtils;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.DeserializationContext;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
    import com.fasterxml.jackson.databind.module.SimpleModule;

    public class MyObjectMapper extends ObjectMapper {

        public MyObjectMapper() {
            registerModule(new MyModule());
        }
    }

    class MyModule extends SimpleModule {

        public MyModule() {
            addDeserializer(String.class, new StdScalarDeserializer<String>  (String.class) {
                @Override
                public String deserialize(JsonParser jp, DeserializationContext  ctxt) throws IOException,
                    JsonProcessingException {
                    return StringUtils.trim(jp.getValueAsString());
                }
            });
        }
    }

Aktualisieren Sie die Servlet-context.xml von Spring:

<bean id="objectMapper" class="com.mycompany.MyObjectMapper" />

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper" ref="objectMapper" />
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

8voto

vanduc1102 Punkte 4874

Com.fasterxml.jackson.dataformat

pom.xml

   <dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-csv</artifactId>
      <version>2.5.3</version>
    </dependency>

CsvUtil.java

     CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader().sortedBy();
     CsvMapper mapper = new CsvMapper();
     mapper.enable(CsvParser.Feature.TRIM_SPACES);
     InputStream inputStream = ResourceUtils.getURL(fileName).openStream();
     MappingIterator<T> readValues =
          mapper.readerFor(type).with(bootstrapSchema).readValues(inputStream);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X