Jackson library ignoring properties - json

Jackson #JsonIgnoreProperties not ignoring possibleTargets ,but ignoring owner and lemf .How i can ignore lists.
#JsonIgnoreProperties( {"owner","lemf"," possibleTargets"} )
#Entity
public class Warrant extends Nameable {
#LazyCollection(LazyCollectionOption.FALSE)
#OneToMany(mappedBy ="warrant",targetEntity = com.endersys.lims.model.Target.class)
private List<Target> possibleTargets;
Output:
[{"status":"SCHEDULED","startDate":1320962400000,"endDate":1320962400000,"caseId":"1","possibleTargets":[],"name":"warrant_1","description":"decription","identity":"warrant_1","version":1,"systemId":1,"active":true}]

I was also have problem lazyload because jackson was trying to serialize ignored fields.I have find a post related to this.Using jackson 1.9 problem solved ,I use #JsonIgnore but #JsonIgnoreProperties still not working on onetomany relations.

Use Jackson version 2.4 it works perfectly.
This is how you can implemented:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties({"id"})
In this developerWork post I found an example to implement Jackson v2.4 all the code and library is available.

Related

SpringBoot RestController not recognizing spring.jackson.property-naming-strategy property

I have a SpringBoot (2.5.x) RestController which is returning Lists and would like to force the JSON representation to use specific naming convention for the properties. I've tried the spring.jackson.property-naming-strategy property in application.properties but it seems to have no effect. Also tried custom MappingJackson2HttpMessageConverter, using setPropertyNamingStrategy on the Autowired objectMapper, and using the #JsonNaming annotation in the controller class.
Any ideas on what I'm doing wrong?
Thanks!
--john
Put this on the class
#JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
But it is outdated
At the same time it is still available
I don't know why
my spring boot 2.5.4
This is what I ended up doing:
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonInclude.Include
import com.fasterxml.jackson.databind.PropertyNamingStrategies
import com.fasterxml.jackson.databind.annotation.JsonNaming
#JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
#JsonInclude(Include.NON_NULL)
class Facility {
String facility
String facilityCode
Integer sampleCount
}

Is it a good practice to add redundant #JsonProperty when using JacksonMapper

Is it a good practice to add redundant #JsonProperty when using JacksonMapper? Even if the class vars are same named as the incoming json(and you deserialize the json)?
What can be possible upsides?
What can be possible downsides?
The downside,as you suggested, it's reduandant,especially when this class was replaced from codehaus package to fasterxml so if you have old property you will have to refactor class
org.codehaus.jackson is an older version of Jackson.
com.fasterxml.jackson represents the new project and package.

MessageBodyWriter not found for media type=application/json when returning JSON in REST web service with Jersey

I am trying to create a very simple REST service using Jersey. Here is the service code
#Path("/UserService")
public class UserService {
#GET
#Path("/users")
#Produces(MediaType.APPLICATION_XML)
public List<User> getUsers() {
User user = new User(1, "Thomas", "Greene");
List<User> userList = new ArrayList<User>();
userList.add(user);
return userList;
}
}
When I run it through Postman, it returns me a XML response
Now, I want to get a JSON response back. So, I changed the mediatype to application/json:
#Path("/UserService")
public class UserService {
#GET
#Path("/users")
#Produces(MediaType.APPLICATION_JSON)
public List<User> getUsers(){
User user = new User(1, "Thomas", "Greene");
List<User> userList = new ArrayList<User>();
userList.add(user);
return userList;
}
}
It gives me the below error in Tomcat logs:
SEVERE: MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.List.
Can someone please guide me how to get a JSON response back?
To use Jackson 2.x as your JSON provider you need to add jersey-media-json-jackson module to your pom.xml file:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22.2</version>
</dependency>
And then register the JacksonFeature in your Application/ResourceConfig subclass.
For more details, have a look at Jersey documentation.
I am a bit upset about JAXB binding as well at the moment, therefore let me summarize my findings here - please correct me if I say something stupid:
Of course you have to have a library to do the JSON (de)serialization, in my case it is Moxy.
You have to tell JAXB which classes it should support. There are multiple ways to do that, the simplest seems to be to add a jaxb.properties file in the directory matching your classes and its sole content is the text javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory. With the directory I mean, if your classes are in the directory src/main/java and there the package com.pkg1.entities, add this file in src/main/resources and there as com/pkg1/entities/jaxb.properties.
By default JAXB works on POJOs. So you need to have a constructor without arguments, a get- and a set-method. Only then this field will be present in the JSON.
What I do often is to add a second constructor that gets the runtime object passed in and sets all fields to be exposed directly. Hence I do not need and do not want a set-method. Solution is to annotate the get method with #XmlElement.
Did I say you need an empty/default constructor? Took me once three hours to find out why class1 was working fine, class2 got the MessageBodyWriter error. I had forgotten the constructor. Grrrrr.
You get the same error (I believe) when the class is configured fine but one of its fields returns a type it cannot serialize.
I believe to have had one case where the class annotation #XmlRootElement caused that error. Not sure but I barely use that annotation at the moment.
In case you have a List as one of the elements to be turned into a Json array, JAXB will use the myAbstract class to do the serialization. Not very useful, you want the actual objects to be serialized. But how should JAXB know who implemented/extended this class? You have to tell with the annotation #XmlSeeAlso. So the MyAbstract class gets a class annotation #XmlSeeAlso({MyConcrete1.class, MyConcrete2.class}). At least Moxy does add then an additional type field telling the consumer which class it was. Makes total sense.
Although you can return userList the better option would be to return Response.ok().entity(userList).build(); Then you can return errors as well. Logically it is the same.
Watchout what kind of data types you use. String is fine, ArrayList as well, Hashtable not. Depends on the serializer you use as well.
I hope this helps others.
You need a json serializer on your class path to make this work.
Just add jackson and jersey will use this in the writer.
E.g. if you are using maven, add this to the pom.xml
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.4</version>
</dependency>
Your xml was working so I assume that you have #XmlRootElement annotation in your User class.
The thing is, it knows how to convert it to xml with the annotation #XmlRootElement but it doesn't know how to convert it to JSON.
So for making it convert everything to JSON with the same annotation of xml(ie #XmlRootElement) we can add
jersey-media-moxy-<whatever version>.jar
or for maven users
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
</dependency>
Also it should have a no argument constructor
I tried a ton of these dependencies but none of them worked for my version of Jersey3. What I needed to do was turn the Arraylist into an actual array. I managed this with toArray() and it started serializing correctly!

Seam 2.3 RESTEasy on JBoss 7.1 #JsonIgnore

How to achieve that some properties are ignored in the JSON-output (like XmlTransient for XML-output)?
#GET
#Path("/{companyId}")
#Produces(MediaType.APPLICATION_JSON)
public PortfolioCompany getCompany(#PathParam("companyId") long id);
I've been playing around with the RESTeasy-support in Seam 2.3 deployed as an EAR on a JBoss 7.1. I started by adding the same dependencies to my ejb-project as in the Seam-restbay-example.
It is basically working fine for #Produces(MediaType.APPLICATION_XML), where all properties annotated with #XmlTransient are ignored, in order to prevent some LazyInitialisationExceptions.
But how to achieve this behavior for #Produces(MediaType.APPLICATION_JSON)?
I've read Seam uses Jettison by default, which uses the #XmlTransient annotation for both, XML and JSON (because technically it transforms from XML -> to JSON). But I get a "Caused by: org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer" which indicates that in fact it is using Jackson..?
For Jackson there is the annotation like #JsonIgnore, but having the same maven dependencies like restbay - this "cannot to be resolved to a type".
/**
* #return the contact
*/
#OneToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
#XmlTransient // working for produces XML but not for JSON
//#JsonIgnore = unknown type
public Contact getContact() {
return contact;
}
Anyone any experiences or hints on that?
thanks
EDIT: Really no one having the need of realizing lazy collections for REST-services with Seam??
After some research:
#JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property ="#id")
is what apparently would be needed. But that is only provided with Jackson 2.x. But the seam2.3/jboss7 setup is obviously using Jackson 1.9...
The default annotation mode of #XmlType/#XmlRootElement is to capture everyfield, including the lazy initializer from hibernate. Use #XmlAccessorType(XmlAccessType.NONE) in your entities and then individually annotate the fiels with #XmlElement so that only the necessary fields are processeded

Restlet/Jackson JSON wrapper for ArrayList<Profile>

i'm using the Restlet library for a WS server and i've recently switched from XStream/Jettison to Jackson as a JSON serializer/deserializer because of some issues.
A first drawback is that my ArrayList< Profile > (previously a Vector with Jettison) it doesn't wrap the list of Profiles when serialized and the JSON instead of "Profile:[{firstProfile}, {secondProfile}]" it looks like: [{firstProfile}, {secondProfile}]
I can overcome to this issue in the client telling manually which is the correct mapping but i would prefer to use a KVC approach.
I've looked around and it seems that it's a known issue: http://wiki.fasterxml.com/JacksonPolymorphicDeserialization (5.1 Missing type information on Serialization) that it suggest to:
Use arrays instead of Lists
Sub-class list, using class MyPojoList extends ArrayList { }
Force use of specific root type
the simplest way it should be to return an "Profile[] profile" array but it seems not working, before trying the other solutions i've rechecked around and it seems that you can use a #XmlRootElement(name = "Profile") to wrap the JSON root element: http://jira.codehaus.org/browse/JACKSON-163?focusedCommentId=213588&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-213588
so for using JAXB annotations with Jackson you need to configure the objectMapper: http://wiki.fasterxml.com/JacksonJAXBAnnotations
but in restlet to do so you need to override createObjectMapper to pass a Custom converter (see: http://restlet-discuss.1400322.n2.nabble.com/Set-custom-objectMapper-to-Jackson-Extension-td6287812.html and http://restlet-discuss.1400322.n2.nabble.com/Jackson-Mix-in-Annotations-td6211060.html#a6231831)
this is what i'm trying now! the question is there a more straightforward way to achieve this??
Thanks!!
the solution for me is to annotate the Profile class with:
#JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT)
public class Profile extends Element implements Serializable {
and now the json now looks like:
{"Profile":{ ... }}
and the return type is a Sub-classed list:
public class ProfileList extends ArrayList<Profile>
{}
see http://wiki.fasterxml.com/JacksonPolymorphicDeserialization 5.1
I think what you want is not really available in a sense that JAX-B seems to have some rules on how to deal with lists. See this converstation on the RESTeasy mailing list