I'm passing a Java object to a Web service that accepts json, using HttpURLConnection.
Employing com.fasterxml.jackson to convert the object to json string and then writing it to the output stream, the service works fine for simple dummy POJOs, but the application breaks when I use a complex object that I'm originally intend to send,
with the console filled with exceptions like StackOverflow and endless clutter of
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690)
at
com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
Common solutions are like annotating the class with json annotation.
Is there any other way to get around it, like using different accept:content-type for web service (other than json or xml as they require annotated objects) or like that?
You can use mixin annotations to provide hints for Jackson on how to serialize your data, without polluting the POJO with unnecessary dependencies.
Here's the reference to documentation article, that has good example:
http://wiki.fasterxml.com/JacksonMixInAnnotations
Related
I am using JAX-RS whereby I have an interface which contains annotated methods for my endpoints (Apache CXF). I am using Jackson as my serializer.
I have noticed that the first request is particularly slow. This is because the JSON serializer is building its internal metadata on how to serialize/deserialize a given type on the first request.
It is possible to get Jackson to do this upfront (before the first request) by registering the type with Jackson. Is it possible to do this in a generic way, such that I have an interface and using reflection it goes and finds all the inputs and outputs to the JAX-RS annotated methods and registers the types with Jackson?
I figured this must be an "already solved" problem and in the vein of DRY - is there something out there that will do this already without me having to write some nasty reflection code myself? (Or any helper methods in Spring etc that could help here?)
I am providing the ability to deserialize a list of entities returned from JPA, however the list type returned from JPA is DelegatingResultList which has no default constructor.
The implementation uses proxy beans with AOP where I intercept interfaces that extend a set of interfaces to provide basic queries.
I can easily fix this by checking in my aspect if the object type is DelegatingResultList and then copy to an ArrayList, but I don't want to have to do this for every single aspect that I'm covering.
I am using the default typing to set as a property like so:
objectMapper.enableDefaultTyping(DefaultTyping.NON_FINAL, As.PROPERTY);
The json in the serialized format with my value wrapper looks like this:
{"#class":"my.wrapper.ValueWrapper",
"response": ["org.apache.openjpa.kernel.DelegatingResultList",
[{"#class":"my.entity.TaxInfoEntity","taxType":"01","taxVal":"0.07"}, ..."]]"}
I have read about using mixins and custom deserializers, but everything I've tried doesn't seem to work.
I have tried using a Mixin, but I have no reference to the ResultList property as it's not saved in the json. Not to mention it doesn't even kick in when it's trying to deserialize.
I have tried using a custom deserializer but again, this never kicks in when deserializing. Would I be correct in assuming the mixin and custom deserializer only kick in if you try to deserialize passing the class as the type?
This of course would be read only as it's a cached value. So my intention is to convert to an Arraylist instead. How would I achieve this using Jackson?
I'm trying to learn Spring Boot by implementing a simple REST API.
My understanding was that if I need to transfer an object over the wire, that object should implement Serializable.
In many examples on the net though, including official ones, domain classes that need to be transferred from server to client (or vice-versa) do not to implement Serializable.
For instance: https://spring.io/guides/gs/rest-service/
But in some cases, they do:
For instance: https://github.com/szerhusenBC/jwt-spring-security-demo/blob/master/src/main/java/org/zerhusen/security/JwtAuthenticationRequest.java
Is there a general rule of thumb on when to implement Serializable?
To update this, advice about Serializable has changed, the recommendation currently seems to be Don’t use Serializable for anything.
Using the Java serialization API means you need something in Java on the other side of the wire to deserialize the objects, so you have to control the code that deserializes as well as the code that serializes.
This typically isn't relevant for REST applications, consuming the application response is the business of someone else's code, usually outside your organization. When building a REST application it's normal to try to avoid imposing limitations on what is consuming it, picking a format that is more technology-agnostic and broadly available.
Some reasons for having an object implement java.io.Serializable would be:
so you can put it in an HttpSession
so you can pass it across a network between parts of a distributed application
so you can save it to the file system and restore it later (for instance, you could make the contents of a queue serializable and have the queue contents saved when the application shuts down, reading from the save location when the application starts to restore the queue to its state on shutdown).
In all these cases, you serialize so you can save something to a filesystem or send it across a network.
There are many ways to serialize an object. Java's object serialization is just one of them. From the official documentation:
To serialize an object means to convert its state to a byte stream
REST APIs usually send and receive JSON or XML. In that case serializing an object means converting its state to a String.
There is no direct connection between "sending an object over the wire" and implementing Serializable. The technologies you use dictate whether or not Serializable has to be implemented.
The specific examples you have mentioned do not transfer objects over the wire. From the example links I see that the controller methods return a domain object with ResponseBody annotation. Just because the return type of the method is the domain object it is not necessary that the whole object is being sent to the client. One of the handler method in Spring mvc framework internally intercepts the invocation and determines that the method return type does not translate to direct ModelAndView object. RequestResponseBoodyMethodProcessor which handles the return value of such annotated methods and uses one of the message converters to write the return object to the http response body. In the case the message converter used would be MappingJackson2HttpMessageConverter. So if are to follow the same coding style you are not required to implement Serializable for your domain objects.
Have a look at this link for the Http message converters provided by default from spring. The list is quiet extensive however not exhaustive and if requirements arise you can implement your own custom message converter to user as-well.
that's a good question when to implement Serializable interface.
these links can provides some useful contents:
Serializing java.io.Serializable instance into JSON with Spring and Jackson JSON
When and why JPA entities should implement the Serializable interface?
I sometimes wonder about this, and I think
Because Java is a open source language, and more libraries providered by third party. for tells who will serialize and deserialize the object, the java offical declare a constract interface, makes transfer easy and safety throught different library.
It's just a constract, most third-party libraries can serialize/deserialize when checking implement this constract. and jackson's jar library is not use it.
So you can deem if you use serialize/deserialize object data in your own system, and simple process, likes just serialize and response it(jackson in spring MVC), you needn't to implements it.
but if you used in other jar library, likes saving in HttpSession, or other third-party componens/library, you should(or have to) implement Serializable, otherwise the libraries will throw a exception to tell you the constract interfaced which it knows is not provide.
But they said it's a good habit and best properties that to implement the Serializable when serialize a custom class. :)
you should serialize if you are using caching for database operations.Usually the third party cache providers like (hazle cast, Jboss cache etc..) internally serialize/ de serialise objects.In that case model classes should implement Serializable to facilitate caching.
We have a front-end service that uses a back-end service to get a list of Metric objects. We've written a Java ClientSDK for the back-end service to make life easier for development of client applications of that service.
We also expose a list of Metrics from the front-end service. For now, we're directly exposing and converting the back-end Metric objects to JSON.
My concern is that if changes are made to the back-end Metric object - say a developer adds a new secret ID field - we don't want to expose it from the front-end service.
We're also writing a clientSDK for the front-end service. We don't want to reference the Metric class from the back-end clientSDK, so the logical option is to define a similar Metric object in the front-end SDK.
I don't want to waste CPU cycles copying 1000's of Metrics from one class definition to another.
Is there a way to specify which fields I should expose from the back-end Metric to the front-end definition of Metric as I'm converting to JSON? Better yet, can I reference the front-end definition to the JSON converter as I ask it to marshal the back-end object?
We're using Jackson with the Spring rest framework for context, but I'd be happy to drop that in a heartbeat since marshaling objects via annotations seems to be the root cause of this problem.
Take a look at Jackson's JsonView construct.
I can see your example looking something like this:
class Views {
static class Client {}
static class Backend extends Client {}
}
public class Metric {
#JsonView(Views.Client.class) String metricName;
#JsonView(Views.Client.class) String count;
#JsonView(Views.Backend.class) String secretKey;
}
The #JsonView annotation is supported on Spring #ResponseBody annotated methods as of Spring 4.1.
As Nicholas Hausschild has suggested you can achieve this by annotations with your marshalling/unmarshalling framework.
However you can simply use inheritance and casting like this:
class SomeSuperClass {
String exposeThis;
String exposeThat;
// getters and setters...
}
class SomeSubClass extends SomeSuperClass {
String doNotExposeThis;
// getters and setters...
}
This way you can cast to the super class when returning an object to the JSON parser, and at the same time use the subclass internally to carry additional information which you don't really want to expose.
Another possibility is the use of Mixins, so you can define different scenarios without touching the original DTO.
I myself use a library I wrote to achieve this dynamically:
https://github.com/Antibrumm/jackson-antpathfilter
This works well for not too deep graphs, else someone wrote another approach in a similar way here which seems more performant for these scenarios, but behaves a bit different.
https://github.com/krishna81m/jackson-nested-prop-filter
I'm using web services and I want to step it up a notch. I'm using Axis2 with JAX-WS. I'm thinking of transfering objects instead of String[]. After I googled a bit, I found that JAXB is the right support to do this.
However, everytime I want to add a modelclass that needs to be transferred, I need to do a lot of work (to shut up about all the annotations where I can make mistakes). So I thought it would be easier to abstract this a bit.
I was thinking of creating web services using the Object type. I can then use methods as addObject(Object object), removeObject(Object object), retrieveObject(). This means my server needs to handle incomming objects. If I then add a new model class, I just need to catch it at server end. My client will need to include the model classes causing some redundancy but I'm OK with that. I have the feeling that Java cannot support my idea at this momemnt. At least JAX-WS & JAXB technologies.
Can you guys tell me if I'm right or wrong about this, if this is a good idea or not and if so, maybe point me into the right direction on how to fix this (even if it means using another technology)
Thanks in advance!
Your client won't need a model type, but you will have to serialize and deserialize your data when you send messages from your server to your client. I'm not sure if JAX-WS is different from JAX-RS, but if they are the same, then you can add annotations that mark whether or not you want to produce/consume json or xml.
Once you serialize your model to json, your client will have no problem reading your data.
Also, yest you can use object when creating request and response objects. In a webservice that I recently wrote I created a service response class similar to this
public class Response
{
private Object data;
private boolean success;
public Response()
{
super();
}
//write getters and setters here
}
I think that I'm using the Object class in a similar fashion to what you have in mind.
I definitely recommend you JAX-RS (implementing JAXB), in particular using the Jersey framework. It's usage is simple and allow you to marshall and unmarshall business objects.
Look at this Jersey Example
Hope it helps!