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?)
Related
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 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
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.
Requirement
I am building a REST API. It has two REST calls. The call /format to output formatted JSON based on the parameters provided. The call /raw with same parameters should output JSON with raw values (without the formatting). The formatting here would be locale specific like date changes, displaying the correct currency, decimal formatting, time formatting etc for the values.
Tools
Java, Tomcat, Spring, Apache CXF, JAX-RS and Jackson.
Implementation
REST service is setup and works fine. No problems there. I have written seperate custom serializers in which I provide desired formatting using NumberFormat, DateFormat, DecimalFormat etc. I have extended the SimpleModule from Jackson to register all my custom serializers mentioned above. I am using two separate ObjectMapper (FomatOM and RawOM).FormatOM registers the custom Module for formatted JSON output, RawOM is for raw JSON output as per the requirement. These two objectmappers are registered to two different JacksonJsonProviders and declared as beans in my spring config xml. For /format I use FormatOM with custom serializers, and in /raw I use RawOM.
Problem
It doesn't work as I would have expected. I expected that when I make a request through /format call the FormatOM would be used and for /raw RawOM would be used. What is happening is whichever call I make first, subsequent calls are served using the same ObjectMapper. Thus, if the first call is /raw; subsequent calls to /format or /raw render raw JSON output. After a Tomcat restart, if the first call is to /format then subsequent calls to either API calls render formatted JSON output
Questions
1. How do you achieve my requirement for rendering formatted + raw JSON
output?
2. What's is wrong with my implementation?
3. Any ideas or suggestions or critiques?
4. Any other way to have request based mappers?
Thanks
One work-around is just to use a StreamingOutput, and bundle specific ObjectMapper in there, use it directly (ObjectMapper.writeValue(output, value);)
Thanks for your answer StaxMan. Since I am using Spring, I decided to inject the JacksonJsonProvider and do JacksonJsonProvider.setMapper(mapper) to set the mapper per request. If anyone has tried the above approach and ran into a problem do let me know. If I run into any sort of issue, I shall update this answer.
I am currently building my own custom Security Token Services using the Opensaml and Openws APIs.
I am using CXF with Spring, this technology facilitates interceptors that allow me to manipulate and insert elements (SAML Assertions etc) into the soap header.
However, I would like to insert an OpenWS RequestSecurityToken object into the soap body, via my web service method.
The OpenWS RequestSecurityToken object itself does no have a non-argument constructor defined, and neither does it's superclasses. Root class being org.w3c.xml.Element which also does not have an empty constructor.
JAXB throws an exception, complaining about this, saying it can't handle interfaces - even though these classes are not interfaces!
I do not have the source code and so am not able to add constructors easily. Much has been posted on the internet about this, with pointers to custom annotations, adapter classes and custom marshallers, but I cannot work out which approach to adopt.
BTW: OpenWS and Opensaml does come with Marshallers and Unmarshallers for each object. I was wondering if anyone has managed to force JAXB to use custom marshallers at all?
You can use an XmlAdapter, check out:
http://bdoughan.blogspot.com/2010/12/jaxb-and-immutable-objects.html
http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html