Hello I have read all the posts on this, but nothing seems to help
I have a public getter that points to a circular structure that I do not want serialized into Json. I have looked through the other posts and tried the suggestions but nothing works.
Currently, I am using ObjectMapper #JsonIgnore and #JsonAutoDetect like this:
#JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE, getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
public class Bah {
#JsonIgnore
public String getFoo() { return foo; }
However, the getter is still being serialized into my Json structure. But when I rename getFoo to something without get (e.g. foo()) it works, but "public getX()" seems to override the #JsonIgnore
What am I missing? I'm sure its something dumb
Thanks
Peter
OK, I got it, and as predicted it was really dumb!
Turns out I had both com.codehaus.jackson and com.fasterxml.jackson in my project. The ObjectMapper came from fasterxml and the annotations came from codehaus >:-P
Now everything is working as expected as expected. Thank you all for the help.
P
Try disabling AUTO_DETECT_GETTERS in your ObjectMapper. You can do this wherever you are instantiating ObjectMapper like this:
ObjectMapper om = new ObjectMapper();
om.disable(MapperFeature.AUTO_DETECT_GETTERS);
Or, extend ObjectMapper and use the custom one throughout your project:
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
disable(MapperFeature.AUTO_DETECT_GETTERS);
// more project-wide config
}
}
Related
I have a private field with a private getter method (because I hope to prevent other users from using the getter outside this class, while I have a use case for this getter within this class), but I hope the field to be serialized using objectMapper. What is a good way to do it? Would appreciate any idea!
#Data
public class TestClass{
#Getter(AccessLevel.PRIVATE)
private String field
}
ObjectMapper by default will serialize only public fields, but you can change it using setVisibility method.
You can do it like this:
TestClass testClass = new TestClass("field");
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
objectMapper.writeValueAsString(testClass);
The problem
I need to polymorphically JSON-(de-)serialize an #Autowired Spring bean (I'm using Spring Boot 2.0.4) using only original properties.
Since the bean is "enhanced", it is a subclass of my "original" bean, with class name ending with something like $$EnhancerBySpringCGLIB$$12345.
Tried so far
To avoid Jackson trying to serialize the "enhanced" part, I've declared my bean as a supertype of itself with
#JsonSerialize(as=MyClass.class)
It worked as intended.
But, when I try to do polymorphic serialization with
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.WRAPPER_OBJECT)
placed on the interface that the said class implements, the key of the wrapper object is the name of the enhanced class! The rest of JSON string is OK, that is, only properties of the "original" class are included. Needless to say, I can't de-serialize it now, since the mentioned subclass is not around any more.
Using JsonTypeInfo.Id.NAME defeats the whole idea of polymorphic deserialisation, IMHO. I can figure out the target class by querying ApplicationContext, if nothing else works.
EDIT:
Here is a Foo Bar example:
#JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.WRAPPER_OBJECT)
public class Foo {
private String foo = "Foo";
#JsonSerialize(as = Bar.class)
public static class Bar extends Foo {
private String bar = "Bar";
}
public static class UnwantedMutant extends Bar {
private String aThing = "Not welcome";
}
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
UnwantedMutant mutant = new UnwantedMutant();
System.out.println(mapper.writeValueAsString(mutant));
}
}
This prints
{"mypackage.Foo$UnwantedMutant":{"foo":"Foo","bar":"Bar"}}
while
{"mypackage.Foo$Bar":{"foo":"Foo","bar":"Bar"}}
is expected/desired.
So, the question:
is there any solution to this problem with "pure" Jackson means, or I just have to live with it?
Did you try with:
#JsonRootName(value = "NameOfYourClass") ?
Sorry if I didn't understand your question.
I need to define an ObjectMapper globally serialize/deserialize objects and I need only fields with the public getters and setters will be serialized.
It could be great if there exists something like:
objectMapper.setVisibilityChecker(objectMapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY)
.withIsGetterVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY)
.withSetterVisibility(JsonAutoDetect.Visibility.PUBLIC_ONLY)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
but with "and" and not "or".
Any idea to do that?
PS: I could do it with annotations, but I need to do it globally.
Thanks in advance.
Seeing the success of the question I have been forced to seek a solution by myself. It's not a ideal solution, but it is enought for me.
private void configureObjectMapper(MappingJackson2HttpMessageConverter converter) {
final ObjectMapper objectMapper = new ObjectMapper();
// Only serialize fields with both public accessors
objectMapper.configure(MapperFeature.REQUIRE_SETTERS_FOR_GETTERS, true);
// If a field is not found, then ignore it and continue processing, with no fail
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
converter.setObjectMapper(objectMapper);
}
Regards!
The Java object has to be serialized into a json string in the servlet filter for a jersey application.
Have the following object,
#XmlRootElement
#JsonIgnoreProperties({"bar"})
public class Foo{
String a="1";
String b="2";
#JsonIgnore
String bar="3";
};
ObjectMapper om = new ObjectMapper();
om.writeValueAsString(fooObject);
returns,
{
a:"1",
b:"2",
bar:"3" // Inspite of Jsonignore and jsonignoreproperties bar is returned
}
How do I overcome this?
Fixing the imports to fasterxml from codehaus and adding the following feature to the mapper fixed the issue.
mapper.configure(MapperFeature.USE_ANNOTATIONS, true);
use #XmlTransient:
#XmlTransient
String bar="3";
For parsing JSON like this twitter API users/show response I've been using Jackson and Gson Java libraries as candidates to do this work. I'm only interested in a small subset of properties of the JSON so Gson was nice because of its very concise syntax but I'm losing an internal battle to continue to use Gson as Jackson is already used elsewhere in our application and it has documented better performance (which I concede are both good reasons to lose Gson).
For a POJO like
public class TwitterUser {
private String id_str;
private String screen_name;
public String getId_str() {
return id_str;
}
public void setId_str(String id_str) {
this.id_str = id_str;
}
public String getScreen_name() {
return screen_name;
}
public void setScreen_name(String screen_name) {
this.screen_name = screen_name;
}
}
The only code for Gson needed to build this is one line,
TwitterUser user = new Gson().fromJson(jsonStr, TwitterUser.class);
That's pretty nice to me; scales well and is opt-in for the properties you want. Jackson on the other hand is a little more laborious for building a POJO from selected fields.
Map<String,Object> userData = new ObjectMapper().readValue(jsonStr, Map.class);
//then build TwitterUser manually
or
TwitterUser user = new ObjectMapper().readValue(jsonStr, TwitterUser.class);
//each unused property must be marked as ignorable. Yikes! For 30 odd ignored fields thats too much configuration.
So after that long winded explanation, is there a way I can use Jackson with less code than is demonstrated above?
With Jackson 1.4+ you can use the class-level #JsonIgnoreProperties annotation to silently ignore unknown fields, with ignoreUnknown set to true.
#JsonIgnoreProperties(ignoreUnknown = true)
public class TwitterUser {
// snip...
}
http://wiki.fasterxml.com/JacksonAnnotations
http://wiki.fasterxml.com/JacksonHowToIgnoreUnknown