Apex Data Transfer Object. Deserializing data - java

I am new to Apex and SF and I have to manage some errors from an 3rd party API we are calling. I have been using DTO with very simple response objects and the error response object we get back has one more level.
JSON response from API:
{
"error": {
"message": "File couldn't be downloaded: main_panel"
}
}
DTO file:
public class CreateCadRequestError {
public string error;
public CreateCadRequestErrorMessage message;
}
public class CreateCadRequestErrorMessage {
public string message;
}
Apex class deserializing data
class SoloConnector {
resp = makeNetworkCall()...
SoloDTO.CreateCadRequestError resp = ( SoloDTO.CreateCadRequestError )JSON.deserialize( response.getBody(), SoloDTO.CreateCadRequestError.class );
System.debug('resp: ' + resp.error + resp.message);
}
I am getting an error
illegal value for primitive
I assume its my DTO class and not being able to serialize the data. Any suggetsions?

Found the answer, My DTO set up was incorrect:
public class CreateCadRequestError {
public CreateCadRequestErrorMessage error;
}
public class CreateCadRequestErrorMessage {
public string message;
}

Related

I am trying to create an API using SpringBoot but I don't know how to handle json request/response

I am new to Java and Spring boot. I am creating a new API.
Using postman I am sending a request body which contains request header and request payload.
Then I have a controller which handles the request with the help of RequestPayload class. (And a service and dao file but I am sure those are ok.)
Kindly let me know what Am I missing here or what do I not know.
public class RequestPayload {
String pol_pkg_prod_code;
JSONObject checklist;
public JSONObject getCheckList() {
return checklist;
}
public void setCheckList(JSONObject checklist) {
this.checklist = checklist;
}
public String pol_pkg_prod_code() {
return pol_pkg_prod_code;
}
public void setpol_pkg_prod_code(String pol_pkg_prod_code) {
this.pol_pkg_prod_code = pol_pkg_prod_code;
}
You need a POJO class that will match the structure of your JSON payload, actually a few nested classes. Spring will automatically parse JSON into this POJO.
public class Request {
private RequestPayload reqPayload;
// Getter Setter
}
public class RequestPayload {
private Checklist checklist;
// Getter Setter
}
public class Checklist {
#JsonProperty("pol_pkg_prod_code")
private String polPkgProdCode;
}
Then add it to Controller as an argument like this:
#RequestBody Request request
This tutorial explains it well
https://www.baeldung.com/spring-request-response-body

How to format JSON Response In Java Spring?

I have a Response Class with the set of private fields. Front end developers asked me to send the response of a service in this JSON format.
So far
Response should in JSON format and like this
{
"status": "SUCCESS",
"message": {
"code": "040",
"description": "verified"
},
"qrContent": "aaa | bbb"
}
QrCodePaymentResponse response = new QrCodePaymentResponse();
if (firstThree.equalsIgnoreCase(QRType.EZDYNAMIC.getDescription())) {
axiPayQrCodePaymentService.ezCashDynamicQR(axiPayQrCodePayment,serviceContext);
response.setStatus(RequestStatus.SUCCESS.getStatus());
response.setMessage(----------------);
response.setQrContent(returnValue.getQrContent);
}
How to modify above code to send requested format?
Thanks.
use the spring RestController. it's methods return the data as a JSON format
QrCodePaymentResponse.java
public class QrCodePaymentResponse{
private String response;
private String qrContent;
private Message message;
//set getters and setters
}
Message.java
public class Message{
private String code;
private String description;
//set getters and setters
}
AppController.java
#RestController
public class AppController {
#RequestMapping(value="/get", method=RequestMethod.GET)
public QrCodePaymentResponse getPaymentResponse(){
QrCodePaymentResponse response = new QrCodePaymentResponse();
Message message = new Message();
//set values to message
if (firstThree.equalsIgnoreCase(QRType.EZDYNAMIC.getDescription())) {
axiPayQrCodePaymentService.ezCashDynamicQR(axiPayQrCodePayment,serviceContext);
response.setStatus(RequestStatus.SUCCESS.getStatus());
response.setMessage(message);
response.setQrContent(returnValue.getQrContent);
}
return response;
}
}

How to handle a response of a service returning either a single object or an array of these?

I am trying to invoke a third-party API through REST call in Spring. Currently, I'm using postForObject. I am converting the request class to string and calling the post for object. The response is taken as string and then converted it into the class. I have defined the class with below parameters
Class responseDto {
private Arraylist < Response > response;
getResponse();
setResponse();
}
Response {
String code;
String trid;
Getters();
Setters();
}
I am using Jackson dependency to serialize and deserialize. This class is working fine for the below response:
{
"response":[
{
"code":"100",
"trid":"123"
}
]
}
However, in error scenario, the request returns a JSON class with the same name 'response' as given below
{
"response":{
"code":"700",
"trid":"123"
}
}
The deserialize fails for the class I defined with some JSON mapping exception:
com.fasterxml.jackson.databind.JsonMappingException: Can not
deserialize instance of java.util.ArrayList out of START_OBJECT token
How can I resolve this issue in Java and Spring?
SOLUTION 1: Using #JsonFormat ( > 2.6 version)
Just annotate your field with #JsonFormat as
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonFormat.Feature;
public class ResponseDto {
#JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<Response> response;
public List<Response> getResponse() {
return response;
}
public void setResponse(List<Response> response) {
this.response = response;
}
}
SOLUTION 2: Setting DeserializationFeature
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
// global setting, can be overridden using #JsonFormat in beans
// when using #JsonFormat on fields, then this is not needed
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
ResponseDto dto = mapper.readValue(stringResponse, ResponseDto.class);
}
Now response node in json containing single object, single object array, multiple object array will be successfully parsed as list of Response object.

Java generics and jackson mapper

Hi I have the following classes:
public class MyRequest {
}
and
public class MyResponse {
}
and
public class Request<T> {
private String code;
private T request;
public setCode(String code) {
this.code = codel
}
public setRequest(T request) {
this.request = request
}
}
and following service request method:
public MyResponse getMyResponse(Request<MyRequest> myRequest) {
//process
try {
ObjectMapper mapper = new ObjectMapper();
String jsonInString = mapper.writeValueAsString(myRequest);
System.out.println(jsonInString);
} catch(Exception exp) {}
}
and following Json request is sending from JavaScript;
{
"code":"TESTCODE",
"request":null
}
After I send the request I an getting an Invalid Json error. Can anyone tell me what is wrong with my request Json or something else is wrong..?
By any chance are you using the model 'Request' as an inner class. If yes,
just try using the modifier static with 'Request'.
or rather move out the model 'Request' to a separate class
Non-static Inner classes by design contain a reference to the outer-class, which does cause problems in deserialization.
http://www.cowtowncoder.com/blog/archives/2010/08/entry_411.html

Coverting JSON String which is part of JSON object to JSON Object on the run

I am consuming a REST web services using REST template in my project which returns a JSON as below:
{"data": [{
"id": "INT-1468819244684-event-no-97",
"object1": {
"JSONString": "{\"object2\":[{\"object3\":\"value3\",\"object4\":\"value4\"}]}"
}
}]
}
While consuming the above JSON response I am able to create a bean class and able to dump JSON object/values into the same.
But the problem is above json response contains a string as below:
"JSONString": "{\"object2\":[{\"object3\":\"value3\",\"object4\":\"value4\"}]}"
which is actually a json. So I have a bean in which I can fetch JSONString as String. So currently I can use below bean structure to fetch response in objects:
public class response {
Data data;
}
public class Data {
String id;
Object1 object1;
}
public class Object1 {
String jsonString;
}
But above jsonString contains a string in the form of json, so I want to somehow convert this JSON String to JSON Object at run time only when other objects are created and dump all its content in the same bean so that application should be ready to use its content. So ideally my bean hierarchy should be something like below:
public class response {
Data data;
}
public class Data {
String id;
Object1 object1;
}
public class Object1 {
JSONString jsonString;
}
public class JSONString {
Object2 object2;
}
public class Object2 {
String object3;
String object4;
}
Please guide me how to do the same.
You can use Jackson's ObjectMapper.readValue in this way:
// Create or use your existing ObjectMapper
ObjectMapper om = new ObjectMapper();
#JsonProperty("JSONString")
public String getJSONString() {
if (this.jsonString == null)
return null;
return om.writeValueAsString(this.jsonString);
}
public void setJSONString(String s) {
this.jsonString = om.readValue(s, JSONString.class);
}

Categories

Resources