Jackson Not Overriding Getter with @JsonProperty

我只是一个虾纸丫 提交于 2020-01-14 07:09:29

问题


JsonProperty isn't overriding the default name jackson gets from the getter. If I serialize the class below with ObjectMapper and jackson I get

{"hi":"hello"}

As you can see the JsonProperty annotation has no effect

class JacksonTester {
    String hi;

    @JsonProperty("hello")
    public String getHi() {
        return hi;
    }
}   

Putting @JsonProperty on the String itself doesn't work either. The only way it seems that I can change the name is by renaming the getter, the only problem is that it then will always be lowercase for the first letter


回答1:


The problem was that I was using both the old and new jackson libraries

i.e. before I had import org.codehaus.jackson.annotate.JsonProperty; Which I had to change to below, to be consistent with the library I was using.

Since I was using maven that also meant updating my maven dependencies. import com.fasterxml.jackson.annotation.JsonProperty;

For it to work, I needed the @JsonProperty annotation on the getter (putting it on the object didn't work)

I found the answer here (thanks to francescoforesti) @JsonProperty not working as expected




回答2:


I know its an old question but for me I got it working when I figured out that its conflicting with Gson library so I had to use @SerializedName("name") instead of @JsonProperty("name") hope this helps




回答3:


I had this problem when updating from older version to 2.8.3 of FasterXML Jackson.

The issue was when deserializing the JSON response from our DB into Java class object, our code didn't have @JsonSetter on the class' setters. Hence, when serializing, the output wasn't utilizing the class' getters to serialize the Java class object into JSON (hence the @JsonProperty() decorator wasn't taking effect).

I fixed the issue by adding @JsonSetter("name-from-db") to the setter method for that property.

Also, instead of @JsonProperty(), to rename properties using the getter method, you can and should use @JsonGetter() which is more specific to renaming properties.

Here's our code:

public class KwdGroup {
    private String kwdGroupType;

    // Return "type" instead of "kwd-group-type" in REST API response
    @JsonGetter("type") // Can use @JsonProperty("type") as well
    public String getKwdGroupType() {
        return kwdTypeMap.get(kwdGroupType);
    }

    @JsonSetter("kwd-group-type") // "kwd-group-type" is what JSON from the DB API outputs for code to consume 
    public void setKwdGroupType(String kwdGroupType) {
        this.kwdGroupType = kwdGroupType;
    }
}



回答4:


If using Kotlin

I understand the original question is in Java, but since Kotlin is becoming very popular and many might be using it I'd like to post this here to help others.

Anyway, for Kotlin, because how getters/setters work, if you are using val, meaning you only expose the getter, you may need to apply the annotation to the getter like below:

class JacksonTester(@get:JsonProperty("hello") val hi: String)




回答5:


I had same proplem

You need just to replace import import com.fasterxml.jackson.annotation.JsonProperty; on import org.codehaus.jackson.annotate.JsonProperty; Its work.




回答6:


Camel cases still seem to have issues even after defining proper annotations. Example:

@JsonProperty("mirrorport") private String mirrorPort;

Deserialization still fails when xml has <mirrorport>YES</mirrorport>




回答7:


I recently came across another interesting twist on this issue. We started using the Hibernate5Module to help with some lazy loading issues. Furthermore, we use Groovy so we are not defining getters and setters.

It turns out that the Hibernate Module seems to interfere with the @JsonProperty annotation. Specifically if you have something annotated with @Transient So, if you have something like:

@Transient
@ApiModelProperty(required = true)
@JsonProperty("alternateName")
String property

You won't see the alternateName in the JSON. Furthermore, your clients will likely have trouble with their POSTs and PUTs! To fix this, you can use a simple workaround. Define the getters and setters for the internal name you need to use(*) and don't use the value attribute on @JsonProperty So this works:

@Transient
@ApiModelProperty(required = true)
@JsonProperty
String alternateName

void setProperty(String property) {
    this.alternateName = property
}

@JsonIgnore
String getProperty() {
    this.alternateName
}

Note the use of the @JsonIgnore on the getter. If you don't, your framework will probably pick it up and you'll have duplicate entries for the same thing in your JSON.

Anyhow - I'm hoping this helps someone!

(*)We were trying to adhere to a particular interface, thus enforcing the name internally. However, the exposed API needed a different, user-friendly name.




回答8:


Place it on the variable, not the getter

class JacksonTester {
    @JsonProperty("hello")
    private String hi;

    public String getHi() {
        return hi;
    }
} 



回答9:


Have you tried below

class JacksonTester {
    private String hi;

    @JsonProperty("hello")
    public String getHi() {
        return hi;
    }
}   

I mean making the 'hi' variable declaration as private. Alternatively try to put a @JsonIgnore on the variable declaration and in case you would rather keep it at default scope.




回答10:


I was missing databind dependency

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${fasterxml.version}</version>
</dependency>



回答11:


Try this

class JacksonTester {
    private String hi;

    @JsonProperty("hi")
    public String getHi() {
        return hi;
    }
} 


来源:https://stackoverflow.com/questions/32843099/jackson-not-overriding-getter-with-jsonproperty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!