I've a JSON Array that needs to be consumed at the rest controller. It always says JSON parser error
{
"message": "JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token\n at [Source: (PushbackInputStream); line: 1, column: 1]",
"errorUid": "c794a587-2f27-4402-b43b-5ec46a5bccfc"
}
Here is my request object
{
"results":[{
"keyname":"bb-response",
"bbResponse":{
"count": 8,
"transactionId": "hu7h78707ssf8",
"responseMessage": [{
"type": "NTY",
"status": "F"
},
{
"type": "HYG",
"status": "F"
}]}
}]}
Here is my code of the controller
#PostMapping(value = "/post-keys")
#ResponseStatus(HttpStatus.OK)
public String postKeys(#RequestBody List<RequestWrapper> requestWrapperList) {
log.info("Starting to send messages ");
return "success";
}
My RequestWrapper Class
public class RequestWrapper implements Serializable {
String keyname;
BBResponse bbResponse;
}
My BBResponse class is
public class BBResponse implements Serializable {
private int count;
private List<Response> responseMessage;
private String transactionId;
}
Can any one let me know where am I doing wrong? Any ideas would be greatly appreciated
Solved. The issue was with the JSON request. The correct request looks like this
[{
"keyname":"bb-response",
"bbResponse":{
"count": 8,
"transactionId": "hu7h78707ssf8",
"responseMessage": [{
"type": "NTY",
"status": "F"
},
{
"type": "HYG",
"status": "F"
}]}
}]
Related
I have an API method like below inside my RestController
#PostMapping("/asd")
public ResponseEntity<String> asd(#RequestBody MyParams params) { ... }
MyParams class is like below.
public class MyParams implements Serializable {
public List<Long> ids;
public List<String> ignoredTypes;
public Map<String, List<String>> aMapping;
}
In postman, I pass a JSON string like
{
"ids": [28712, 344248],
"ignoredTypes": [],
"aMapping": "{\"Person\":[\"name\",\"age\"],\"Title\":[\"start\",\"end\"]}",
}
I get an error saying
2021-08-16 18:25:53.953 WARN 4164 --- [io-8080-exec-10]
.w.s.m.s.DefaultHandlerExceptionResolver : Resolved
[org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error: Cannot construct instance of
java.util.LinkedHashMap (although at least one Creator exists): no
String-argument constructor/factory method to deserialize from String
value ('{"Person":["name","age"],"Title":["start","end"]}'); nested
exception is
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot
construct instance of java.util.LinkedHashMap (although at least one
Creator exists): no String-argument constructor/factory method to
deserialize from String value
('{"Person":["name","age"],"Title":["start","end"]}') at [Source:
(PushbackInputStream); line: 12, column: 20] (through reference chain:
com.xyz.MyParams["aMapping"])]
So basically java.util.Map cannot be parsed from JSON string. How can I do that?
Did you tried like this
{
"prop1": [1],
"prop2": ["string"],
"prop3": {
"additionalProp1": [
"string"
],
"additionalProp2": [
"string"
],
"additionalProp3": [
"string"
]
}
}
Try to pass the JSON object as it is without stringifying
I changed the request body and it worked.
{
"ids": [
28712,
344248
],
"ignoredTypes": [
],
"aMapping": {
"Person": [
"name",
"age"
],
"Title": [
"start",
"end"
]
}
}
Hi i am using retrofit to call my API with spring boot.
API Response
[
{
"name": "whishky",
"price": 1000
},
{
"name": "vodka",
"price": 200
}
]
My pojo class looks like
public class MyResponse {
List<MyObject> resp;
}
And MyObject class looks like
public class MyObject implements Serializable {
#JsonProperty("name")
private String name;
#JsonProperty("price")
private Double price;
}
API call
Call<MyResponse> saveRequestCall = MyApi.fetchData(request);
Response<MyResponse> execute = saveRequestCall.execute();
Now the problem is when i call the API i am getting the exception
2020-04-25 18:08:18,895 ERROR c.s.e.b.XYZServiceImpl Error in fetching datawith exception com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `zzz.MyResponse` out of START_ARRAY token
at [Source: (InputStreamReader); line: 1, column: 1]
Any help will be appreciated regarding how i can parse this.
The problem seems to be mapping to MyResponse because it's excepecting something like
{
"resp": [
{
"name": "whishky",
"price": 1000
},
...
]
}
It should be fixed if you use
Call<List<MyObject>> saveRequestCall = MyApi.fetchData(request);
Response<List<MyObject>> execute = saveRequestCall.execute();
The above json represent JSONArray of JSONObject with two properties name and price, so you don't need to wrap List<MyObject> resp in another class, you can directly deserialize json into List<MyObject>
Call<List<MyObject>> saveRequestCall = MyApi.fetchData(request);
Response<List<MyObject>> execute = saveRequestCall.execute();
I have a basic Rest Controller which returns a list of models in json to the client:
#RestController
public class DataControllerREST {
#Autowired
private DataService dataService;
#GetMapping("/data")
public List<Data> getData() {
return dataService.list();
}
}
Which returns data in this format:
[
{
"id": 1,
"name": "data 1",
"description": "description 1",
"active": true,
"img": "path/to/img"
},
// etc ...
]
Thats great for starting, but i thought about returning data of this format:
[
"success": true,
"count": 12,
"data": [
{
"id": 1,
"name": "data 1",
"description": "description 1",
"active": true,
"img": "path/to/img"
},
{
"id": 2,
"name": "data 2",
"description": "description 2",
"active": true,
"img": "path/to/img"
},
]
// etc ...
]
But i am not sure about this issue as i can not return any class as JSON... anybody has suggestions or advices?
Greetings and thanks!
"as i can not return any class as JSON" - says who?
In fact, that's exactly what you should do. In this case, you will want to create an outer class that contains all of the fields that you want. It would look something like this:
public class DataResponse {
private Boolean success;
private Integer count;
private List<Data> data;
<relevant getters and setters>
}
And your service code would change to something like this:
#GetMapping("/data")
public DataResponse getData() {
List<Data> results = dataService.list();
DataResponse response = new DataResponse ();
response.setSuccess(true);
response.setCount(results.size());
response.setData(results);
return response;
}
I'm trying to marshal a recursive bean to JSON with MOXy in Jersey, following the specification of RFC6901 aka JSON Pointer.
E.g., I'd like to marshal this:
public class Bean {
public Integer id;
public String name;
public Bean other;
public List<Bean> next;
}
x = new Bean(123, "X");
a = new Bean(456, "A");
x.other = a;
x.next.add(x);
x.next.add(a);
into this:
{
"id": 123,
"name": "X",
"a": { "id": 456, "name": "A", "next": [ ] },
"next": [
{ "$ref": "#" },
{ "$ref": "#/a" }
]
}
and then unmarshal this JSON to the original bean. Does someone have any suggestion/solution to this problem?
I have a json like this:
{
"games": [
{
"id": "mhhlhlmlezgwniokgawxloi7mi",
"from": "425364_456#localhost",
"to": "788295_456#localhost",
"token": "xqastwxo5zghlgjcapmq5tirae",
"desc": "6CeF9/YEFAiUPgLaohbWt9pC7rt9PJlKE6TG6NkA4hE=",
"timestamp": 1412806372232
},
{
"id": "62jzlm64zjghna723grfyb6y64",
"from": "425364_456#localhost",
"to": "788295_456#localhost",
"token": "xqastwxo5zghlgjcapmq5tirae",
"desc": "Z/ww2XroGoIG5hrgiWsU1P8YHrv4SxiYHHoojzt9tdc=",
"timestamp": 1412806373651
}
]
}
I'm trying to deserialize it to an Object with ObjectMapper. Essentially as you can see, it is a List of games.
I have classes like these:
#JsonRootName(value="games")
public class GameJson{
private List<Game> games;
// getters and setters
}
the Game class is here:
public class Game{
private String id;
private String from;
private String to;
private String token;
private String desc;
private Instant timestamp;
// getters and setters
}
In my code, the ObjectMapper is doing this:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
GameJson json = mapper.readValue(
new FileInputStream(gamesFile), GameJson.class);
Then I get this error:
Can not deserialize instance of com.games.collection.GameJson out of START_ARRAY token
I am trying different ways to do this, but coming out with no luck. Can someone please help?
Thanks!
Get rid of
#JsonRootName(value="games")
That annotation identifies the annotated type as the target for the JSON object mapped to a JSON key named "games". In your case, that is a JSON array. An array cannot be deserialized into your GameJson class.
As you stated in the comments, you also need to remove the configuration that enables #JsonRootName.
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);