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.
Related
I want to deserialize an object which is annotated with #JsonRootName. However the JSON in which the object is transported contains another extra property. As a result Jackson is complaining with:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (FIELD_NAME), expected END_OBJECT: Current token not END_OBJECT (to match wrapper object with root name 'account'), but FIELD_NAME at [Source: (ByteArrayInputStream); line: 1, column: 26].
Apparently deserialization of #JsonRootName annotated objects works ONLY if that object is the sole property in JSON file - since it's not expecting the "lastTransactionID" to be there.
Here's my Account class:
#JsonRootName("account")
public class Account {
private String id;
}
This is the JSON I need to deserialise:
{
"account": {
"id": "1234"
},
"lastTransactionID": "1"
}
Since I'm using spring I have this setup also spring.jackson.deserialization.unwrap_root_value=true.
Is there any way to solve this without:
having to write a custom deserializer?
OR
intercepting the response and stripping it of the extra property before deserialization takes place?
It looks like simplest way to solve this issue is create wrapper for Account class and deserialise json as usual with disabled DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES feature.
public static class Wrapper {
public Account account;
}
In this case other fields will be ignored.
It's not a nice solution, I know, but it solve a problem.
We can use ObjectMapper to Map json to java Objects.
public Account jsonToObject(Map<String, Object> map){
ObjectMapper objectMapper = new ObjectMapper();
Account account = objectMapper.convertvalue(map.get("account"),Account.class);
return account;
}
You can use JsonIgnoreProperties(ignoreUnknown=true) annotation on your Account class. Please refer below link for more details.
https://www.thetechnojournals.com/2019/10/entity-object-conversion-to-dto-object.html
Can someone point me to the correct way to convert xml into json with jackson?
I have one service that accepts a post request with an xml body, I want to take that xml and send it to another service as a json.
I've seen some examples where people use an ObjectMapper, but ideally, I would have an interface ModelJsonView and then use the setMixInAnnotation() method to bind it to the corresponding model class.
Try this:
String xml = "<testName>Tester</testName><testValue>100</testValue>"
JSONObject xmlToJsonObject = XML.toJSONObject(xml);
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
Object json = mapper.readValue(xmlToJsonObject.toString(), Object.class);
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json));
Include org.json and jackson jars.
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());
}
I'm trying to post a POJO entity like below in Arquillian test class.
MyPojo pojo = new MyPojo();
pojo.setBuffer(ByteBuffer.wrap("Happy new year".getBytes()); //this is the problem
pojo.setOtherFiled(someotherfield)
Client client = ClientBuilder.newClient();
Invocation.Builder builder = client.target(url).request(
MediaType.APPLICATION_JSON_TYPE);
MyPojo response = builder.post(Entity.json(pojo), MyPojo.class);
My rest resource end point looks like this
MyPojo myEndPoint(MyPojo pojoParam){
//the body is immaterial since it's not going inside the body.
}
I'm getting javax.ws.rs.BadRequestException:HTTP 400 Bad Request.
If I comment out pojo.setBuffer(ByteBuffer.wrap("Happy new year".getBytes());, it's not giving that error.
What is the problem with the above code how to correct it?
Finally I figured out why it's happening. The Jackson cannot serialize ByteBuffer as it is an abstract class. It's not straight forward it might need additional type information.
At the client end we send the json(jackson serializes the POJO) but when reconstructing the POJO class before passing to the rest end point, it fails to reconstruct the object of the POJO class from json as it doesn't know how to create a ByteBuffer instance.
I figured it by trying to use jackson to serialize and de-serialize ByteBuffer in a stand alone class. It will throw
org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.nio.ByteBuffer, problem: abstract types can only be instantiated with additional type information
Jackson lies in pre-processing phase of the request processing in Resteasy. So, Resteasy is giving 400 bad request as it could not process the request.
As a work around I'm using byte[] instead of ByteBuffer and converting it to ByteBuffer instance in the end point.
Upgrading the JSON Mapper to fasterxml will fix this issue. I have upgraded and the issue is fixed for me.
https://github.com/FasterXML/jackson
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.