JSON parse error: Cannot deserialize when using spring RestTemplate.exhange - json

I am new to JSON and spring. Was able to write simple examples consuming REST webservices. But as I apply to realtime scenario, the JSON is nested, and I don't have control in changing the structure.
Below code giving me Parse Error. Cannot deserialize instance of pg.domain.LookupDo[] out of START_OBJECT token
LookupDo[] lookupDos = template.exchange(url, HttpMethod.GET, request, LookupDo[].class).getBody();
How do I structure domain object?
#JsonIgnoreProperties
public class LookupDo {
private String companyCode;
private String plant;
private String category;
private String value;
private String descr;

You need to match your class with your JSON structure
Response res = template.exchange(url, HttpMethod.GET, request, Response.class).getBody();
LookupDo[] lookupDos = res.getD().getResults();
public class Response{
private Data d;
...
}
public class Data{
private LookupDo[] results;
...
}

Related

Spring Boot REST multi part request (file + json) throwing 415 Unsupported Media Type exception

I am using spring boot version = 1.5.2.RELEASE.
When I am sending multi part file with json object to upload file in postman, It throwing 415 Unsupported Media Type exception.
This is my controller class.
#RestController
#RequestMapping("/service/promotion/")
public class JobController {
....
....
....
#RequestMapping(value = "/job/test", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public ResponseEntity<Object> createJobTest(#Valid #RequestBody JobRequest jobRequest,
#RequestParam(value = "file", required = false) MultipartFile multiPartFile) throws Exception {
My json request class.
public class JobRequest {
private String campaignKey;
private String communicationId;
private Integer channelId;
private String templateType;
private String subject;
private String frequencyControl;
private Integer leadsRequested;
private String keywordRelavance;
private String scheduledAt;
private String file;
private String updatedBy;
//getter and setter
}
Json request in postman
Multipart file request in postman
Header Content-type
But when I removed consumes from controller class and from postman as well like
#RequestMapping(value = "/job/test", method = RequestMethod.POST, produces = "application/json")
then debugger coming in controller class but multi part file value coming
null in request object like
I googled a lot there are many similar questions which already posted but none of them helped me.
Please help me to sort out this mystery.
Thank you.
Check this File upload along with other object in Jersey restful web service
Another way is you can pass whole object in text like you are passing file in form-data and convert in object.
#RequestMapping(value = "/uploadDocs", method = RequestMethod.POST, produces = "application/json", consumes = "multipart/form-data")
public ResponseEntity<Object> methodName(#RequestParam("files") MultipartFile file, #RequestParam("anyKeyName") String objectString)
Than you can convert string to object using
Class object = new ObjectMapper().readValue(objectString, Class.class);

Type of data received from AngularJS POST?

I send json Object from AngularJS POST
(json['name']="Name";json['lastName']="LastNAme");
In Spring mvc Controller I got this message
"name=Name&lastName=LastName"
I don't know the type of this message, whether it is JSON or String and how to parse to a java object.
Create a model representating your JSON object.
public class Person{
private String name;
private String lastname;
//...Setters + Getters + default constructor
}
Then in your controller handler :
#Controller
//Mapping here
public class YourController{
#PostMapping
public void getPerson(#RequestBody Person person){
//process here
}
}

Non Required JSON attribute in Spring (Jackson Mapping)

I have this function in a Spring controller:
#RequestMapping(value = "/*", method = RequestMethod.POST)
#ResponseBody
#Consumes("application/json")
public JSONresponse alta(#RequestBody JSONrequest parametros, HttpServletRequest request) {
some code...}
JSON request is a JavaClass like this:
public class JSONrequest {
private String code;
private String message;
//getters and setter}
I'm using Jackson to map this, and works correctly. But my question is: It's possible make message attribute non required? I would like the web service to accept JSON with both attributes or only with the "code" attribute
You can use required property of JsonProperty. But this property is available from 2.7.x or higher versions.
public class JSONrequest {
#JsonProperty(value ="CODE",required = true)
private String code;
#JsonProperty(value ="MESSAGE",required = false)
private String message;
Above example makes code attribute as mandatory while message as an optional field for deserialization.

Square Retrofit: Exception converting byte[]

I'm using Retrofit to get some data from my WebAPI REST service. However my model contains a byte[] and this leads to an exception.
The exception I receive looks like this:
Caused by: retrofit.converter.ConversionException: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 122 path $.Photo
This exception appears because my model has a byte[] called Photo.
My model:
public class Artists {
private long ID;
private String Firstname;
private String Lastname;
private String Description;
private String Countrycode;
private byte[] Photo;
private java.util.Date Born;
private java.util.Date Death;
private java.util.Date Edited;
My REST API Java interface:
public interface ArtistRestService {
#GET("/artist/{id}")
Artists getArtist(#Path("id") long artistID);
#GET("/artist")
List<IdEditedRestObj> getArtists();
}
I know that I could use retrofit.mime.TypedByteArray but I also use GreenDAO an ORM mapper and I do not feel like to refactor the whole stack.
Is there an simple workaround/solution so I can somehow parse the incoming json so that exception does no take place?
Solution found:
Using https://github.com/square/retrofit/blob/master/retrofit-converters/jackson/src/main/java/retrofit/converter/JacksonConverter.java
public RestService(String url){
restAdapter = new RestAdapter.Builder()
.setClient(new OkClient(getClient()))
.setEndpoint(url)
.setConverter(new JacksonConverter())
.setErrorHandler(new RetrofitErrorHandler())
.setLogLevel(RestAdapter.LogLevel.HEADERS_AND_ARGS)
.build();
}
Everything works fine now, thx

Process JSON with Jersey and Jackson

I am using jersey in Java. I want to get JSON data sent via a post request. However, I am not sure how to do this, despite my searching. I am able to receive JSON data at a path, yet I can't figure out how to parse it into java variables. I assume that I need to use jackson to do this. However, I don't understand how to pass the received JSON to jackson.
#Path("/register")
public class ResourceRegister
{
#POST
#Consumes(MediaType.APPLICATION_JSON)
public String RegisterUser(//not sure what to take in here to get the json )
{
//code to deal with the json
}
There are several ways of accepting the JSON and using it in back-end.
1. set POJO elements using JAXB APIs and use object of that POJO class to access passed parameters. this will be helpful while JSON size is large.
Example:
your service declaration would be as following
#Path("/register")
public class ResourceRegister
{
#POST
#Consumes(MediaType.APPLICATION_JSON)
public String RegisterUser(RegParams regParams)
{
//code to deal with the json
}
.....
}
and you will write a POJO like following
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#JsonIgnoreProperties(ignoreUnknown=true)
#JsonWriteNullProperties(false)
public class RegParams implements Serializable {
#JsonProperty("userId")
private long userId;
#JsonProperty("userName")
private String userName;
..
..
}
retrive JSON as a string and use jersey APIs to work with the same.
in this case you can declare your service as following
#Path("/register")
public class ResourceRegister
{
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String RegisterUser(#FormParam("jsonObj")String jsonString)
{
//code to deal with the json
}
.....
}
and you can process that string by using jersey APIs like following
ObjectMapper om = new ObjectMapper();
JsonNode mainNode = om.readTree(jsonString);
//access fields
mainNode.get..(as per data passed, string, int etc)
for more referance you can refer this or this
You just need to place #JsonProperty annotation to your class properties and add that class to your Resource method as paramater.
You might need #JsonIgnoreProperties annotation as well if you are not deserializing everything inside the incoming json
See below:
#POST
#Consumes(MediaType.APPLICATION_JSON)
public String registerUser(MyUser myUser)
{
//code to deal with the json
}
public class MyUser{
#JsonProperty
private String name;
#JsonProperty
private String surname;
//getters & setters & constructors if you need
}