I am using Gson 1.6 and Spring Framework 3.0 for a Java web app on WebSphere 6.1. I have some Spring beans for which the actual instance is a CGLIB proxy. When I attempt to serialize these beans via Gson, the non-primitive properties of the class are not serialized. Instead I get something like:
{
"CGLIB$BOUND":true,
"CGLIB$CONSTRUCTED":true,
"booleanProperty":true,
"anotherBooleanProperty":true,
}
where I was expecting something more like
{
"stringProperty":"stringValue"
"integerObjectProperty":17,
"booleanProperty":true,
"anotherBooleanProperty":true,
}
When I serialize a non-proxied POJO, the output is exactly as I'd expect. How can I get Gson to generate the output I expect?
I'd say your problem is the result of a bad practice.
Spring Beans are usually defined by behaviour, not state. And you should only serialize Classes that have State, not behaviour.
Refactor your code, transfer the state from the Beans to Value Objects, and serialize those.
I would consider trying out another JSON processor, Jackson (http://jackson.codehaus.org), since it has some support for dealing with cglib proxied objects. And Spring supports Jackson so you have less code to write, compared to gson-based version.
Related
I am writing a rest api and at the compile time i only have the model interfaces which i want to use as dto in my rest api. I dont want my rest api to have dependency of model implementations at compile time as i have diggerent jars for dealing with different databases. So it is obvious that jersey is not able to deserialize the json as it is not aware of the concrete type. I googled about instantiating abstract types but all the solutions are for compile time only wbich is not an option for me. Any help would be much appriciated.
#POST
public Response addMessage(Message message) {
// How to deserialize message since Message is an interface
}
I'm implementing a REST service using Camel's cxfrs component. Various examples I've seen around the inets say I can get the service to return a JSON serialization of the object in question using a cxf:providers tag, like so
<cxf:rsServer id="rsServer" address="${CXFserver}${service}" serviceClass="org.trinityhealth.esb.PersonService"
loggingFeatureEnabled="true" loggingSizeLimit="20">
<cxf:providers>
<bean id="jsonHandler" class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
</cxf:providers>
</cxf:rsServer>
This compiles and deploys just fine. But no matter what variant of this config I try, the service responds with "No message body writer has been found for response class Person". The Person class has a "#XmlRootElement(name = "Person")" annotation in it, which I guess is great if I wanted XML produced. But I don't - I want JSON. Jackson has a ton of annotations, do I need to add one to the Person class to get my service to realize I want the class serialized by the Jackson writer?
I don't know Camel that well, but typically Jackson does NOT require root annotation, unlike JAXB (partly since JSON structure does not require name for root type), so it seems unlikely you would such annotation.
I am guessing that rather the registration does not succeed for some reason.
I have created a Jersey 2.5 Scala REST API Project.
I have a ResourceConfig file, we will call it MyApplication, that looks similar to this:
class MyApplication extends ResourceConfig {
packages(classOf[MyResource].getPackage().getName())
}
All it does is register the resource: MyResource. How can I configure Jersey (2.5) to provide out-of-the-box style JSON Serialization/Deserialization.
For example, here is what MyResource might look like:
#Path("/")
class MyResource {
#POST
#Produces(Array("application/json"))
#Consumes(Array("application/json"))
def getIt(request:SomeRequestModel) = {
/* Do something with the request, return some response model */
return new SomeResponseModel
}
}
So to reiterate, how can I configure Jersey to automatically deserialize and serialize the request and response models, respectively?
It's not actually Jersey that provides the serialisation, it simply draws on an implementation of JAX-RS to perform that role.
Assuming Jersey is a strict requirement, the easiest solution here is to use jackson with Scala bindings. You can find an example here: https://bitbucket.org/jordipradel/jersey-scala-example
If you're not completely tied to Jersey... Might I suggest trying either Spray or spray2-mini instead for a far more idiomatic Scala solution?
I have used Jersey little when developing Java REST services. However, I would say you appear to be conflating two concepts--registering JAX-RS providers and configuring providers to serialize/deserialize JSON.
To register a provider, you use ResourceConfig as you have done.
As for the second issue of configuring Jersey to "know" how to serialize/deserialize JSON:
"As stated in Section 4.3, “Auto-Discoverable Features” JSON-Processing media module is one of the modules where you don't need to explicitly register it's Features (JsonProcessingFeature) in your client/server Configurable as this feature is automatically discovered and registered when you add jersey-media-json-processing module to your classpath."
To add the Jackson flavor of that module to the classpath, you just manually put it there or do this with Maven:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.5</version>
</dependency>
I chose Jackson because it is in my view the best JSON serializer/deserializer in the Java realm.
Having said all this, I once experimented writing services with my preferred Java REST framework, RESTEasy, in Scala. It was more awkward than my first date. Scala and RESTEasy just don't fit together because of an idiom mismatch, issues with types, and so on.
If you want to write REST services in Scala, please consider frameworks built with the language in mind like Scalatra, Unfiltered, or Spray.
By default, Swagger parses a class's data members in order to document the objects used as parameters or returned by a given web service. If you're using Jackson, the Jackson annotations provide a much more accurate description of the API.
Does anyone know an (easy) way to get Swagger to parse Jackson annotations. Perhaps an overridden parser?
Not sure if this would help, but Jackson 2.1 and later expose POJO structure as seen by Jackson itself (ObjectMapper.acceptJsonFormatVisitor), which could be used for generating different kinds of artifacts. I have written an Avro schema generator with it, for example (as part of Jackson Avro module)
As of version 1.2, Swagger can parse Jackson annotations on its own. I confirmed this using Jackson 2.1.
I'd like to implement JAX-RS server (on WebSphere Application Server) and client applications using JSON (Jackson convertor) format and Wink provider.
Do i need to use JAXB annotations for my DTO class that would be passed to and from the REST service and so must be serializable?
Which response type do i need to use, JSONObject or my Class type, i.e MyClass or String in Post methods negotiation between client/server?
In which cases we use JAXB annotations for domain classes in Rest services?
Your insight/directions would be high appreciated.
Thanks in advance,
Erwin
I guess you need to read more about Jackson.
But here are some short answers:
For 90% of cases you don't need JAXB annotations on your classes at all.
You need to use your classes:
#POST
public MyClass myMethod(MyOtherClass mcls)
You use JAXB annotations for some complex mapping, when you are not satisfied with the default results.
In addition to the above answer: it is often makes sense to use Jackson for JSON handling within Apache Wink. Jackson is more powerful and flexible than bundled facilities.
http://www.ibm.com/developerworks/java/library/wa-aj-jackson/index.html shows how to configure Apache Wink for Jackson.