How to deserialize Json string from Kafka topic in spring boot - java

I created a POJO to map a payload received from a Kafka topic.
It works if the format of payload is:
{"payload":{"name":notification,"key":"2637","message":"This is a notif"}
When I produce this message of JSON string type.
"{\"payload\":{\"name\":\"notification\",\"key\":\"2637\",\"message\":\"This is a notif\"}"
It is throwing
Could not read JSON:Cannot construct instance of myfilename : no sting-argument constructor/factory method to deserialize from string value.
How to fix it?

I think you just need to use a StringDeserializer if the message is just a String representing escaped JSON, and handle the message as a String. I don't think you can automatically bind to a POJO because it is not an actual JSON object.
You could write a custom deserializer to convert the String then delegate to an ObjectMapper.

Your issue possibly could be resolved by using below setting in the mapper :
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
On the side note, if you are already using spring-kafka, you can use the default JsonDesrializer or a custom deserializer.
consumerProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
More documentations are available in the spring documentation
Another ref : Deserialize kafka messages in KafkaConsumer using springboot

Related

Map partial json to dto

I was working with rest api and I have a json on POST which I need to map to a dto. But, I have only 5 properties on json , but more than that on the dto. How do I use bean mapper to map it automatically and what about the rest of the properties. Will they be set to Null?
Spring boot comes with Jackson deserializer out-of-the-box. So, it will use the proper method (default null value or constructor properties, based on your settings). For fine tuner, see more at JsonInclude annotation for collections include's strategy and so.
JsonInclude

Spring Message Converter for xml and json

Can someone please help clarify and show how to properly go about this issue?
What I understand so far is that the Spring framework uses Message Converters when a method is annotated with #ResponseBody to convert the return Java object to a format that can be accepted by the Client. If the clients' HTTP request Accept Header includes "application/json", it will use Jackson and the Jackson converter to convert the object and return it in a json format. Similarly if the Accept Header includes "application/xml", then the Message Converter will use Jaxb and the corresponding converter to convert the object to xml.
Now my issue is that I include both the Jackson and Jaxb libraries as specified in Spring documentation so that the corresponding converters can work. This should be enough for Spring to employ #ResponseBody as its supposed to. However, when I send an HTTP Request with the Accept header "application/xml" I get a 406 status code and when I send one with "application/json" I receive a correct json response.
From my research online, I see that some people use the ContentNegotiation technique to work around this, but I would like to use the Message Converter for now. However, every technique to make the Message Converter technique to respond to json and xml resource requests involve formatting my POJO with JAXB annotation. Is this really necessary?
I guess what I am asking is how would one set up their project properly so that Spring can use the Message Converter technique to respond to json and xml requests? What libraries must be included? Does one need to add JAXB annotations or is there an automatic way for Spring to format an object into xml the way it does for json?
I thank you for your time and help with this, but so far I am really loving Spring's implementation of JAX-RS!

Spring Cloud - SQS

I'm trying to get a simple queue handler working with the Spring Cloud framework. I've successfully got the message handler polling the queue, However. The problem I'm seeing is that when I post a message to the queue, my handler is failing to unmarshall the payload in to the required java Object.
#MessageMapping("MyMessageQueue")
#SuppressWarnings("UnusedDeclaration")
public void handleCreateListingMessage(#Headers Map<String, String> headers, MyMessage message) {
//do something with the MyMessage object
}
The error I'm getting is
No converter found to convert to class MyMessage
As I understand it, the #MessageMapping should use Jackson to unmarshall my JSON payload into a MyMessage object. However its complaining that it cannot find a converter.
Has anyone come across this?
I'm using the 1.0.0.BUILD-SNAPSHOT version of Spring Cloud.
Jackson is only used if a contentType header is set with value application/json on the SQS message. Otherwise the converters do not know what type of content is contained in the message's payload and the right converter cannot be chosen.
If you use QueueMessagingTemplate#convertAndSend as in the reference application, the contentType header will automatically be set.

Resteasy PostProcessInterceptor after ResteasyJacksonProvider

We have a Resteasy webservice.
I use Jackson provider for JSON, both outgoing JSON in response and incoming JSON in request.
Is it possible to have a PostProcessInterceptor to be executed after JSON-Jackson serialization?
My PostProcessInterceptor has to change the JSON content for every outgoing response. But when the PostProcessInterceptor is executed if I print the entity response.getEntity().toString(); I see the toString method of the java.lang.Object, not the JSON String. That's because the Object has not yet been serialized by Jackson.
Is it possible to serialize with Resteasy/Jackson before running the PostProcessInterceptor?
I've also tried to use #Precedence annotation on my PostProcessInterceptor. But it doesn't work, even using "DECODER" precedence (which is the last one).
Any idea? Thanks in advance.
I would go for a CDI interceptor instead. You can get the intercepted method parameters from the InvocationContext and change them if necessary.

Android RestTemplate json deserialization

I need to write a Json client in Android for Zenfolio API. I decided to use Spring ResTemplate with MappingHttpJacksonConverter. When i do POST with "exchange" method i recieve json response with one element named "#type" that causes deserializatoon exception. Is there an annotation that tells deserializer to omit that tag? How to turn on annotation for json deserializer?
Try #JsonIgnoreProperties(ignoreUnknown=true) on your mapping classes if you want to ignore all elements that you are not interested in.
Try using #JsonIgnore ("#type"), Jackson annotations are enabled by default.
See http://wiki.fasterxml.com/JacksonAnnotations for more info.

Categories