Jackson überwindet Unterstriche zugunsten des Kamelfalls


160

Ich rufe eine JSON-Zeichenfolge aus dem Internet ab. Wie die meisten JSON, die ich gesehen habe, enthält es lange Schlüssel, die durch Unterstriche getrennt sind. Im Wesentlichen ist mein Ziel, JSON in Java-Objekte zu deserialisieren, aber ich verwende keine Unterstriche in Java-Code.

Zum Beispiel könnte ich eine UserKlasse mit firstNameFeld in Kamel-Fall haben, gleichzeitig muss ich Jackson irgendwie anweisen, den first_nameSchlüssel von JSON dem firstNameKlassenfeld zuzuordnen . Ist es möglich?

class User{
    protected String firstName;
    protected String getFirstName(){return firstName;}
}

Antworten:


103

Sie sollten @JsonPropertydas Feld für das Feld verwenden, in dem Sie die Standardnamenzuordnung ändern möchten.

class User{
    @JsonProperty("first_name")
    protected String firstName;
    protected String getFirstName(){return firstName;}
}

Für weitere Informationen: die API


86
Tun Sie dies nicht, sonst müssen Sie es für jede Immobilie tun. Siehe die Antwort von thehpi unten.
— Ryan Shillington

Ich konnte nur eine Eigenschaft mit Anmerkungen versehen, aber die Reihenfolge der Eigenschaften in der generierten Zeichenfolge wurde geändert: Die mit Anmerkungen versehenen Eigenschaften wurden zuletzt angezeigt. (Jackson 2.3.0)
— eebbesen

1
@RyanShillington - Korrigieren Sie mich, wenn ich falsch liege, aber dies ist Ihre einzige Option, wenn die JSON-Zeichenfolge, aus der Sie analysieren, kein konsistentes Format verwendet, dh sowohl camelCase als auch Unterstrich verwendet?
— DavidR

@ DavidR Das ist richtig. Ich gehe davon aus, dass Sie die Quelldaten nicht reparieren können. Das ist Scheiße.
— Ryan Shillington

@ Paulsai ok, also zögern Sie nicht, sie zu verwenden :)
— Alex

351

Sie können das so konfigurieren ObjectMapper, dass Kamelkoffer in Namen mit einem Unterstrich umgewandelt werden:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

Oder kommentieren Sie eine bestimmte Modellklasse mit dieser Anmerkung:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

Vor Jackson 2.7 wurde die Konstante benannt:

PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES

5
Beachten Sie, dass dies nur in Jackson 1.9 eingeführt wurde.
— David Moles

62
@deprecated Seit 2.7 verwenden Sie stattdessen SNAKE_CASE.
— Thermech

1
one qq: Wenn ich die Namensstrategie snake_case verwende, werden die JSON-Dateien mit Unterstrichen in Camel Case deserialisiert?
— Ram Patra

2
@ Ramswaroop Ja, das lässt Jackson sprechen und erwarten snake_case
— Drew Stephens

1
@Ramswaroop Für mich mit Jackson 2.7.3 und Eigenschaften, die mit just @JsonProperty(Name abgeleitet von normalen camelCaseJava-Eigenschaften) kommentiert wurden PropertyNamingStrategy.SNAKE_CASE, funktioniert die Deserialisierung nicht mehr mit camelCase JSON (wie ich es verwendet habe) und erfordert snake_case.
— Drew Stephens

119

Wenn es sich um eine Spring-Boot-Anwendung handelt, verwenden Sie in der Datei application.properties einfach

spring.jackson.property-naming-Strategy = SNAKE_CASE

Oder Kommentieren Sie die Modellklasse mit dieser Anmerkung.

@JsonNaming (PropertyNamingStrategy.SnakeCaseStrategy.class)


3
Wenn ich meine Klasse mit "@JsonNaming (PropertyNamingStrategy.SnakeCaseStrategy.class)" kommentiere, funktioniert es. Aber wenn ich "spring.jackson.property-naming-Strategy = SNAKE_CASE" in "application.properties" verwende, wird es nicht. Ich verwende "Spring Boot (v2.0.0.BUILD-SNAPSHOT)". Hast du eine Idee ?
— Bruno

1
das gleiche hier, spring.jackson.property-naming-strategy=SNAKE_CASEfunktioniert nicht, ich benutze Spring Boot 2.0
— Soulmachine

1
Das gleiche gilt für spring.jackson.property-naming-Strategy = SNAKE_CASE. Ich verwende Spring Boot 2.0.5. Aber die Verwendung von Anmerkungen funktioniert für mich
— Neo Pham

Vielleicht ist dein ObjectMappernicht vom Frühling erschaffen? Erstellen Sie eine @ Configuration-Klasse mit einer @ Bean-Methode, die einen ObjectMapper zurückgibt. Ich bin mir nicht sicher, ob dies notwendig ist.
— Ondra Žižka

48

Wenn Sie dies für eine einzige Klasse wollen, können Sie das verwenden PropertyNamingStrategy mit dem @JsonNaming , etwa wie folgt:

@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
public static class Request {

    String businessName;
    String businessLegalName;

}

Wird serialisiert zu:

{
    "business_name" : "",
    "business_legal_name" : ""
}

Da Jackson 2.7das LowerCaseWithUnderscoresStrategyin zugunsten von veraltet ist SnakeCaseStrategy, sollten Sie also verwenden:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public static class Request {

    String businessName;
    String businessLegalName;

}

29

Die obigen Antworten zu @JsonPropertyund CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORESsind 100% genau, obwohl einige Leute (wie ich) möglicherweise versuchen, dies in einer Spring MVC-Anwendung mit codebasierter Konfiguration zu tun. Hier ist ein Beispielcode (den ich im Inneren habe Beans.java), um den gewünschten Effekt zu erzielen:

@Bean
public ObjectMapper jacksonObjectMapper() {
    return new ObjectMapper().setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
}

9
Eine Alternative für Spring Boot, wenn Sie Spring Boot <= 1.3 verwenden, application.propertieszusätzlich spring.jackson.property-naming-strategy=CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCOR‌​ES. Verwenden Sie spring.jackson.property-naming-strategy=SNAKE_CASEstattdessen für Spring Boot 1.4 .
— Dump Cake

1
@zapl Ja, Sie haben Recht, ich habe wahrscheinlich Jacksons Version anstelle der Spring-Boot-Version erwähnt. Lassen Sie mich diesen Kommentar löschen, um Verwirrung zu vermeiden.
— Ram Patra

1
Ab Version 2.7 von Jackson ist es SNAKE_CASE. Dies funktionierte für mich: final ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE);
— Jonathan

12

Die derzeit beste Vorgehensweise besteht darin, Jackson innerhalb von application.yml(oder) zu konfigurierenproperties ) Datei .

Beispiel:

spring:
  jackson:
    property-naming-strategy: SNAKE_CASE

Wenn Sie komplexere Konfigurationsanforderungen haben, können Sie Jackson auch programmgesteuert konfigurieren.

import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonConfiguration {

    @Bean
    public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
        return new Jackson2ObjectMapperBuilder()
                .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        // insert other configurations
    }

} 

Wissen Sie, ob eine andere Instanz von jackson2objectmapper geladen wird und diese überschreibt? Und können Sie bestätigen, dass auch diese Bean geladen wird?
— Kenny Cason

Geben Sie auch DuffJs Lösung einen Wirbel. Es ist ziemlich ähnlich.
— Kenny Cason

Ich denke, die Eigenschaften zu optimieren ist der richtige Weg; und auch empfohlen. Das macht das Gleiche.
— WesternGun

@ WesternGun guten Anruf. Ich neige dazu, dies über Yaml / Eigenschaften zu tun, wenn dies möglich ist.
— Kenny Cason

6

Hier gibt es nur wenige Antworten, die beide Strategien für zwei verschiedene Versionen der Jackson-Bibliothek angeben:

Für Jackson 2.6. *

ObjectMapper objMapper = new ObjectMapper(new JsonFactory()); // or YAMLFactory()
objMapper.setNamingStrategy(
     PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

Für Jackson 2.7. *

ObjectMapper objMapper = new ObjectMapper(new JsonFactory()); // or YAMLFactory()
objMapper.setNamingStrategy(
     PropertyNamingStrategy.SNAKE_CASE);

wieder haben sie einige Werte verworfen, jetzt haben sie KEBAB_CASE, yum!
— Kalpesh Soni

FTR: Kebab-Fall ist nicht snake_case ;-)
— René
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.