Adding hypermedia for resource JSON representation using Jackson - java

I am generating my restful resource JSON representation using jackson and it works very well as far as standard property conversion is concerned. However I would also like to generate a bunch of hypermedia in the same json object for which i need to use uriinfo from jersey. Is there a way to pass uriinfo to jackson somehow and use a custom parser to use the uriinfo to generate hypermedia.
jackson version 2.x

You might want to take a look at jersey-linking. It basically uses annotations to generate URIs for you.

Related

Converting java object to xml

How can i convert java object to xml? I am trying to convert an incoming java object to xml in spring integration with a converter bean. is there another way than marshalling in Jaxb ? like using #TypeConverter. Or implementing converter class.
I'm not familiar with #TypeConverter, but looks that that is an EclipseLink feature for JPA. In the end it has this JavaDoc on the #Convert:
/**
* Constant name for the reserved XML converter.
* This will use JAXB to convert the object to and from XML.
*/
public static final String XML = "xml";
So, it still would require from you a JaxB Marshaller to be configured.
Not sure from here why do you ask about Spring Integration if your end goal is JPA...
Anyway: the best way to convert object to XML in Spring Integration is indeed use a MarshallingTransformer which could be configured with any org.springframework.oxm.Marshaller impl, not only JaxB.
If you are looking for some conversion way in between, you may also look into MappingJackson2MessageConverter when you inject an XmlMapper from Jackson lib.
For better assisting you, we definitely need to know more about your use-case and what and how you'd like to marshal into an XML.

why addConverterFactory is need in Retrofit

My question is around Retrofit and GSON. I know GSON is used for JAVA object <-> JSON . I know that Retrofit parses our response. What i don't understand is why we need GsonConverterFactory .Also why is addConverterFactory needed in retrofit
UPDATE:
Pojo objects in Kotlin are data classes and annotation use is as in Java
ANSWER:
If your application is Restful, so gets and sends data from / to server
Converter factory need to be added, just for retrofit can convert JSON data (got from server) into java (model) objects (POJO), to use in Android Project.
There are some converter libraries for converting JSON to Java objects,
(GSON, Jackson..etc) you have to decide which converter you want to use in your project and add same factory
Dependencies in app.gradle
implementation "com.squareup.retrofit2:converter-gson:VERSION"
and Factories in Retrofit settings
GsonConverterFactory or JacksonConverterFactory
Retrofit.Builder().addConverterFactory(GsonConverterFactory.create());
Also if the remote data type is XML, you need to add SimpleXmlConverterFactory
if the json converters don't meet your needs you'll need to Add a customized converter factory for serialization and deserialization of your objects. consider this case.
i wish you'll find this article helpful.
The world is not just json and gson. There are other formats that you can use to implement Rest Apis, i.e. XML.
Also, in the world of json parsers there's not only gson but way more like Jackson and Moshi.
It would be extremely difficult to maintain all possible format converters inside Retrofit, so it offloads the parsing to classes that implement the interface for a converter. Putting this behind a factory lets Retrofit decouple even the creation of these converters, so it can have different ones for different responses and requests.
This also allows you to have multiple converters within the same Retrofit instance and it's also an easy way to let you implement your own converter.
All in all, this decoupling allows for way more flexibility than coupling it with specific libraries.
If you are using Spring, you should create a mapper configuration (or use a default, like in this example), in the retrofit configuration, you should att this code:
#Bean
fun retrofitBuilder(): Retrofit.Builder {
return Retrofit.Builder()
.addConverterFactory(JacksonConverterFactory.create(ObjectMapper()))
}
Then, in your application could read and write Kotlin data class Json, even with no # information.

Jersey XML into Map

Due to old project decisions, I work on a project that uses Jersey to connect to services that return XML data. Sometimes I could create the bean/pojo/whatever annotated with XmlRootElement and use webTarget.get(MyPojo.class)
However, if I try to do what I would do with, say, Jackson, and do webTarget.get(Map.class) I get the following error:
MessageBodyReader not found for media type=text/xml, type=interface java.util.Map, genericType=interface java.util.Map.
My case is, I have a XML that can have arbitrary fields whithin, so the ideal way for me to read it is to read a Map. Is there any way I can do that without having to rely in other libraries? I don't need to serialize data, only deserialize responses from the web services I connect to.
Found the answer, and it's kinda depressing.
According to the Unofficial JAXB Guide, you can't use a Map as a root element, unless you do a very ugly hack, described there. So, the solutions are:
Read as a String, and use Jackson to read a Map from the string.
Do the ugly hack.
Describe part of the schema in a bean, but the part that can have variable fields can be deserialized to a Map.

How is javax.ws.rs.client.Entity serializing objects to json?

What serializer is Entity.json(T entity) using to serialize/deserialize objects? Is it somehow possible to use a custom serializer?
In my case the serialization is wrong because my object contains fields with the Guava Optional data type and absent values are returned as {"present":false} instead of null.
The JSON serializer isn't specified by JAX-RS, it depends on your configuration. For example, Jersey JAX-RS allows several (https://jersey.java.net/documentation/latest/media.html), including
MOXy
Java API for JSON Processing (JSON-P)
Jackson
Jettison
But a better solution is not to use Optional (either Guava or Java 8) for fields. See http://blog.joda.org/2014/11/optional-in-java-se-8.html
My only fear is that Optional will be overused. Please focus on using
it as a return type (from methods that perform some useful piece of
functionality) Please don't use it as the field of a Java-Bean.
Not directly solving your problem. I suggest you use Googles Gson as a parser. It is very flexible and configurable.
Tutorial
It also skips blank fields so the json size is not too large.

Jersey JSON marshalling of empty lists

We have a Java List of objects which is marshalled via JSON which is created by Jersey.
The List is called "rows". When there is data we have:
{"records":"1","page":"1","total":"1","rows":[{"id":"692334","cell":["ECS","D","201009","","0","ABCD","11","11","","201009"]}]}
When there is no data we have:
{"page":0,"records":0,"total":0}
How can we make Jersey include the rows field even if the List has a size of 0? What we want is:
{"page":0,"records":0,"total":0,"rows":[]}
Note that we are already using a JAXB ContextResolver to ensure the JSON is correct for a single row. Not sure if we can configure this resolver to solve our problem.
Use Jackson JAX-RS provider instead of alternatives (badgerfish/jettison), which does not do XML-to-JSON conversion. Missing array is most likely due to this conversion. There are multiple ways to configure this (jersey mailing list should have a few), and latest versions may expose it directly via Jersey API.
Maybe this helps you:
http://jersey.java.net/nonav/documentation/latest/json.html#d4e903
seems that some array problems can be solved by using something like this:
JSONConfiguration.mapped().arrays("yourArrayName").build()
At least it solves the issue, when the list contains only 1 item it's also formated as an JSON array.
I managed to solve JSON array "bug" in Jersey json library. Secret ingredient is previusly mentioned JSONConfiguration and ContextResolver magic. See my following post it has a full code example, customized ContextResolver and rest Application class might be somewhat fuzzy logic in first look.
How to serialize Java primitives using Jersey REST
json array for zero or single-element Java lists
primitive integer or boolean fields without quotation chars

Categories