JsonMappingException no single-String constructor/factory method Jackson - java

I am trying to parse JSON data being sent from UI in my Controller using Spring build Jackson support and this is my code
final Map<String, CartDataHelper> entriesToUpdateMap = new ObjectMapper().readValue(entriesToUpdate, new TypeReference<Map<String, CartDataHelper>>()
my JSON string is
{"0":"{\"categoryCode\":\"shoes\",\"productCode\":\"300050253\",\"initialQty\":\"3\",\"leftoverQty\":\"0\",\"newQty\":\"3\"}",
"1":"{\"categoryCode\":\"shoes\",\"productCode\":\"300050254\",\"initialQty\":\"3\",\"leftoverQty\":\"0\",\"newQty\":\"3\"}"}
i checked the JSON format using some online services and it seems valid, while tryin gto parse JSON data i am getting following exception
org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class controllers.util.CartDataHelper] from JSON String; no single-String constructor/factory method
my CartDataHelper class contains simple properties for for productCode, categoryCode etc with a no argument constructor

As comments mentioned, your JSON contains Map<String,String> and NOT Map<String,CartDataHelper>: values are JSON Strings, not JSON Objects.
Ideally you would not try writing out objects as JSON Strings; and if so, things would work.

It seems that on the client side the json is sent as a string instead as an object. That way on the server side you are receiveing a string and not a CartDataHelper as you pretend.
Try sending JSON.parse(stringCartDataHelper). It worked for me with the same issue.

Related

Getting error org.springframework.http.converter.HttpMessageNotReadableException:Can not construct instance of java.time.LocalDate

I am trying to do the Rest Get call using oAuth2RestTemplate.getForEntity to service and expecting json reply to be mapped in one of my model class but as the mapping class uses local date (Java 8 concept) I am getting the below error at the time of desterilization :
org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not construct instance of java.time.LocalDate: no String-argument constructor/factory method to deserialize from String value ('1988-02-08')
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream#96ce9eb2; line: 1,
Here is the snippet of my code :
ResponseEntity<Some mapping class> response = this.oAuth2RestTemplate.getForEntity(this.ServiceUrl, Some mapping class.class, inputParameter);
I am aware that this is happening because my model class maps birth date in local date which is introduced in java 8 and my oAuth2RestTemplate is not supporting it. using below code solves the problem
ObjectMapper mapperObj = new ObjectMapper();
mapperObj.registerModule(new JavaTimeModule());
mapperObj.disable(WRITE_DATES_AS_TIMESTAMPS);
but in this case I need to take my service response in string and then I will need to convert it. I need a solution with oAuth2RestTemplate.Can someone help.

How to parse a nested unpredictable parameterised Json without creating any POJO?

Receiving JSON input from server whose parameter name may change with time. output format which also will be a json is fixed. But input json may change as it comes from different publishers. Client want an externaal mapping file(json format also) which they will only modify if input json property name needs to be modified or extra parameter is needed. It's spring boot project. Input Json will be nested and may not be nested depending on the publishers.
Input JSON-1
respective Output JSON-1
Without creating POJO, it is possible. You would need to get json property values by property name. You may like to explore com.google.gson.JsonParser. It takes Json String and parses it.
JsonParser myParser = new JsonParser();
JsonElement elems = myParser.parse(jsonString);

Make Jackson interpret single value JSON

I'm looking for a solution to this problem and I can not find anything.
I have this JSON response from an HttpURLConnection:
"OK"
At first look I thought this kind of response was not correct because I always saw some key -> value pair JSON. After i read that the JSONs can take this form I learned :
And https://jsonlint.com/ give me a Valid JSON response if a try to validate "OK"so i think it's correct. And now my question is: How I can map a Java class (called RestResponse) with this JSON response in Jackson?
I try this but not work give me JsonMappingException: no single-String constructor/factory method :
final String json = "OK";
final ObjectMapper mapper = new ObjectMapper()
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
final RestResponse response = mapper.readValue(json, RestResponse.class);
I do not even know where to start with my RestResponse java class because it has no attributes that can mark with Jackson annotation like #JsonProperty.
Does anyone know why Jackson does not take this response case into consideration?
Or is there simply another method?
Thank you guys.
Your RestResponse will need a constructor that takes a single string. Annotate the constructor with #JsonCreator.

Convert from JSON with Jackson Annotations

I am attempting to convert JSON into a Java object with the Play framework. I do not have easy control over the input JSON, which contains dashes in the names.
{ "field-name": "value" }
As a result, I cannot create a Java object with a default mapping to the JSON. I have a class which looks like this:
import com.fasterxml.jackson.annotation.JsonProperty;
public class Data {
#JsonProperty("field-name")
public String fieldName;
}
I know that Play 2.4 uses Jackson, and
I have a unit test which is able to populate the object from the JSON using a default Jackson ObjectMapper.
The JSON is the body of a POST request, and I attempt to use it like this:
Form<Data> form = Form.form(Data.class).bindFromRequest();
If I print form, I can that the data field is populated with the expected values. However, when I do form.get(), the returned value has a null field. (In the actual code, there are more fields, which are Strings or longs. All of them are null or 0.)
Am I attempting to customize the JSON deserialization in the wrong way? Or am I doing something else wrong?
As you've expected you've used the wrong way to deserialize. The Forms class is for PlayForms only and not for Json request. Have a look at the BodyParser and JsonActions documentation:
#BodyParser.Of(BodyParser.Json.class)
public Result index() {
RequestBody body = request().body();
Data data = Json.fromJson(body.asJson(), Data.class);
return ok("Got java object: " + data.toString());
}

Unmarshal nested JSON object to generic Java object

I'm using Jersey (2.5.1) for a RESTish API with JAXB to marshal JSON to/from POJOs. The client will be doing a POST with the following request:
{
"type":"myevent",
"data":{
"id":"123",
"count":2
}
}
I have an 'Event' class which holds a type string and a data payload.
#XmlRootElement
public class Event {
#XmlElement public String type;
#XmlElement public JSONObject data;
...
}
The 'data' payload is a JSON object, however I don't know what type, or what the 'schema' of the object is. All I know is it's JSON. Above I have the type as a JSONObject, but that's just an example, maybe this needs to be Object? Map? Something else?
I want to be able to get the 'data' payload and persist this as JSON somewhere else.
I thought about using a String for the data payload, but then any API client would need to encode this and I would need to decode it before passing it on.
Any suggestions?
I usually work with strings on the backend side and then
JSONObject json = new JSONObject(s);
would create a json obj from that s (you don't need to decode).
On the client side I believe you just need to escape the " with something like a replaceAll function applied on that string

Categories

Resources