RabbitMQ Add an object to another one coming from queue in Spring - java

I have this json object that is mapped to this model class:
Json:
{
"type": "NEW",
"operation": "NEW",
"id": 1,
"entity": "DOCUMENT",
"entityType": "NIE",
"documents": {
"id": 1,
"additionals": {
"issuing_authority": "Spain",
"country_doc": "ES",
"place_of_birth": "",
"valid_from": "1995-08-09",
"valid_to": "0001-01-01"
},
"code": "X12345",
"typeDocument": "NIE"
}
}
The model class:
public class PeopleDocumentDTO {
private String processType;
private String operation;
private String entity;
private String entityType;
private Long id;
private Document document;
#Getter
#Setter
class Customer {
private String systemId;
private String customerId;
}
private List<Customer> customers;
}
The thing is that model class also includes a list of customers that have to be added and its coming from another microservice here:
#Service
public class WebClientService {
public Mono<CuCoPerson> getCuCoPerson(Integer cucoId, String GS_AUTH_TOKEN) {
WebClient webClient = WebClient.create();
return webClient.get()
.uri(GET_RELATION_BY_ID + cucoId)
.header("Accept", "application/json")
.header("Authorization", GS_AUTH_TOKEN)
.retrieve()
.bodyToMono(CuCoPerson.class)
.map(cuCoPerson -> {
List<CustomerRelation> matches = cuCoPerson.getRelatedCustomers()
.stream()
.filter(relation -> relation.getSystemId().equals(400) || relation.getSystemId().equals(300) || relation.getSystemId().equals(410))
.filter(relation -> relation.getCustomerId().contains("F"))
.collect(Collectors.toList());
cuCoPerson.setRelatedCustomers(matches);
return cuCoPerson;
});
}
}
Last but not least, this is my listenerClass where I map my message:
#RabbitListener(queues = "${event.queue}")
public void receivedMessage(Message message) throws JsonProcessingException {
String json = "";
json = new String(message.getBody(), StandardCharsets.UTF_8);
System.out.println(json);
logger.info("Received message: {}", json);
ObjectMapper objectMapper = new ObjectMapper();
PeopleDocumentDTO dto = objectMapper.readValue(json, PeopleDocumentDTO.class);
So, how can I add this cuCoPerson to my model DTO?

Related

#JsonView does not filter fields

I have problem while deserializing JSON to Java Object. I have models and views as shown below:
public class View {
public static class CreateIpSuccessResponse {}
public static class CreateIpErrorResponse {}
}
I use this views in this classes:
Root class:
#Data
#NoArgsConstructor
#AllArgsConstructor
public class CreateIpResponse {
#JsonProperty(value = "pResponseCode")
#JsonView({View.CreateIpSuccessResponse.class, View.CreateIpErrorResponse.class})
private Object pResponseCode;
#JsonProperty(value = "pResponse")
#JsonView({View.CreateIpSuccessResponse.class, View.CreateIpErrorResponse.class})
private CreateIpPResponse createIpPResponse;
}
First subclass:
#Data
public class CreateIpPResponse {
#JsonProperty("Status")
#JsonView({View.CreateIpSuccessResponse.class, View.CreateIpErrorResponse.class})
private String status;
#JsonProperty("Result")
#JsonView({View.CreateIpSuccessResponse.class, View.CreateIpErrorResponse.class})
private CreateIpResult result;
#JsonProperty("responseCode")
#JsonView({View.CreateIpSuccessResponse.class, View.CreateIpErrorResponse.class})
private String responseCode;
}
Second subclass:
#Data
public class CreateIpResult {
#JsonProperty(value = "partyid")
#JsonView(View.CreateIpSuccessResponse.class)
private String partyId;
#JsonProperty(value = "Error")
#JsonView(View.CreateIpErrorResponse.class)
private String error;
}
Example of my json deserialization:
public CreateIpResponse createIp(CreateIpRequest createIpRequest) throws IOException, SQLException {
String pRequest = new ObjectMapper().writer().withDefaultPrettyPrinter().writeValueAsString(createIpRequest);
Map<String, Object> response = openAccountRepository.callProcedure(pRequest, "createClientIP");
BigDecimal responseCode = (BigDecimal) response.get("pResponseCode");
if (responseCode.equals(new BigDecimal("200"))) {
return mapper
.readerWithView(View.CreateIpSuccessResponse.class)
.forType(CreateIpResponse.class)
.readValue(mapper.writeValueAsString(response));
} else {
return mapper
.readerWithView(View.CreateIpErrorResponse.class)
.forType(CreateIpResponse.class)
.readValue(mapper.writeValueAsString(response));
}
}
When I deserialize CreateIpSuccessResponse view, I expect:
{
"pResponseCode": 200,
"pResponse": {
"Status": "OK",
"Result": {
"partyid": "98493305"
},
"responseCode": "200"
}
}
But I get:
{
"pResponseCode": 200,
"pResponse": {
"Status": "OK",
"Result": {
"partyid": "98493305",
"Error": null
},
"responseCode": "200"
}
}
and vice versa, when I deserialize CreateIpErrorResponse view, I expect:
{
"pResponseCode": 400,
"pResponse": {
"Status": "Error",
"Result": {
"Error": "Некорректная дата выпуска"
},
"responseCode": "200"
}
}
But I get:
{
"pResponseCode": 400,
"pResponse": {
"Status": "Error",
"Result": {
"partyid": null,
"Error": "Некорректная дата выпуска"
},
"responseCode": "200"
}
}
My question is why i don`t getting result that i need?
It seems that ObjectMapper is not ignoring null values when serializing objects. So when creating he object mapper use the setSerializationInclusion(Include.NON_NULL) method call to tell the ObjectMapper to ignore the null values:
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
You can find the details here
Edit: added the summarization of the solution as moken suggested in comments.

Not able to deserialize nested JSON array Spring Resttemplate

I am not able to deserialize nested JSON array from response JSON using Spring Rest template.
JSON response which I am consuming is as follows
[
{
"creationTime": "2023-01-13",
"code": "456",
"cid": "123",
"priority": "CRITICAL",
"reviewDate": null,
"systemCall": [
{
"creationTime": "2023-01-13",
"status": null,
"id": "787878",
"modificationTime": "2023-01-13",
"creatorId": "ABC"
},
{
"creationTime": "2023-01-14",
"status": null,
"id": "787879",
"modificationTime": "2023-01-14",
"creatorId": "DEF"
}
],
level: "1"
}
]
And My model classes as follows
public class Resolution {
private String creationTime;
private String code;
private String cid;
private String priority;
private String reviewDate
private List<SystemCallVo> systemCall;
private String level;
public Resolution(){
}
//Getters and Settrs
}
public class SystemCallVo {
private String creationTime;
private String status;
private String id;
private String modificationTime;
private String creatorId;
public SystemCallVo(){
}
//Getters and Setters
}
public class ResolutionVo extends Resolution{
public ResolutionVo(){
}
}
I am calling my endpoint using rest template as follows.
ResponseEntity<List<ResolutionVo>> response = this.restTemplateConfig.restTemplate().exchange(builder.toUriString(), HttpMethod.POST, httpEntity, new ParameterizedTypeReference<List<ResolutionVo>>() {
}, new Object[0]);
Problem is List systemCall object is always null in response received through resttemplate even though systemCall attribute is present in JSON whenever I hit endpoint through swagger.
There is a defect in RestTemplate.exchange that prevents the deserialisation of even moderately complex JSON objects.
Read the response as a String and then deserialise to List<ResolutionVo> with an com.fasterxml.jackson.databind.ObjectMapper instance as follows:
ResponseEntity<String> response = this.restTemplateConfig.restTemplate().exchange(builder.toUriString(), HttpMethod.POST, httpEntity, String.class, new Object[0]);
String body = response.getBody();
List<ResolutionVo> value = objectMapper.readValue(body, new TypeReference<List<ResolutionVo>>() {});
I think this is a related issue.

How to add a list to an object in Spring

I have this object class that has a list of customers as an attribute:
#Data
#NoArgsConstructor
#AllArgsConstructor
public class PeopleDTO {
private String processType;
private String operation;
private String entity;
private String entityType;
private Long id;
private Document document;
#Getter
#Setter
class Customer {
private String systemId;
private String customerId;
}
private List<Customer> customers;
}
This list is retrieved calling another microservice using webclient as follows:
public Mono<CuCoPerson> getCuCoPerson(Integer cucoId, String GS_AUTH_TOKEN) {
WebClient webClient = WebClient.create();
return webClient.get()
.uri(GET_RELATION_BY_ID + cucoId)
.header("Accept", "application/json")
.header("Authorization", GS_AUTH_TOKEN)
.retrieve()
.bodyToMono(CuCoPerson.class)
.map(cuCoPerson -> {
List<CustomerRelation> matches = cuCoPerson.getRelatedCustomers()
.stream()
.filter(relation -> relation.getSystemId().equals(400) || relation.getSystemId().equals(300) || relation.getSystemId().equals(410))
.filter(relation -> relation.getCustomerId().contains("F"))
.collect(Collectors.toList());
cuCoPerson.setRelatedCustomers(matches);
return cuCoPerson;
});
}
This method return a cucoPerson as follows:
{
"id": 1,
"relatedCustomers": [
{
"customerId": "xxx",
"systemId": 999
}
]
}
So now I want to add this object to my PeopleDTO class, but I don't know how. This is what I've done son far (hardcoded):
public PeopleDTO createPeople(Long id) {
PeopleDTO people = new PeopleDTO();
people.setProcessType("ONLINE");
people.setOperation("UPDATE");
people.setEntity("DOCUMENT");
people.setEntityType("DOCUMENT");
people.setIdCuco(id);
people.setDocument(new Document());
people.setCustomers(......);
}
So as you can see I don't know how to add a Mono in the last line.
The expected result should be like this:
{
"type": "ONLINE",
"operation": "UPDATE",
"id": 1,
"entity": "DOCUMENT",
"entityType": "NIE",
"documents": {
"id": 1,
"additionals": {
"issuing_authority": "Spain",
"country_doc": "ES",
"place_of_birth": "",
"valid_from": "1995-08-09",
"valid_to": "0001-01-01"
},
"code": "X12345",
"typeDocument": "NIE"
},
"id": 1,
"relatedCustomers": [
{
"customerId": "xxx",
"systemId": 999
}
]
}
first, create a list of customers like:
List<Customer> customers=new ArrayList<>;
Then add all the Customers to it one by one using a loop,
then you can directly add that to your object like
people.setCustomers(customers);
your object assignment should look something like:
public PeopleDTO createPeople(Long id) {
PeopleDTO people = new PeopleDTO();
people.setProcessType("ONLINE");
people.setOperation("UPDATE");
people.setEntity("DOCUMENT");
people.setEntityType("DOCUMENT");
people.setIdCuco(id);
people.setDocument(new Document());
List<Customer> customers=new ArrayList<>;
//add data to customer
people.setCustomers(customers);
}

How to wrap JSON response in a parent object

The current response from my Spring REST service is as below :
[
{
"id": "5cc81d256aaed62f8e6462f4",
"email": "exmaplefdd#gmail.com"
},
{
"id": "5cc81d386aaed62f8e6462f5",
"email": "exmaplefdd#gmail.com"
}
]
I want to wrap that in a json object as below :
{
"elements":[
{
"id": "5cc81d256aaed62f8e6462f4",
"email": "exmaplefdd#gmail.com"
},
{
"id": "5cc81d386aaed62f8e6462f5",
"email": "exmaplefdd#gmail.com"
}
]
}
The controller :
#RequestMapping(value = "/users", method = GET,produces = "application/xml")
#ResponseBody
public ResponseEntity<List<User>> getPartnersByDate(#RequestParam("type") String type, #RequestParam("id") String id) throws ParseException {
List<User> usersList = userService.getUsersByType(type);
return new ResponseEntity<List<User>>(usersList, HttpStatus.OK);
}
User model class :
#Document(collection = "user")
public class User {
#Id
private String id;
private String email;
}
How can I implement this?
You could make a new Object to serialize:
class ResponseWrapper {
private List<User> elements;
ResponseWrapper(List<User> elements) {
this.elements = elements;
}
}
Then return an instance of ResponseWrapper in your controller method:
#RequestMapping(value = "/users", method = GET,produces = "application/xml")
#ResponseBody
public ResponseEntity<ResponseWrapper> getPartnersByDate(#RequestParam("type") String type, #RequestParam("id") String id) throws ParseException {
List<User> usersList = userService.getUsersByType(type);
ResponseWrapper wrapper = new ResponseWrapper(usersList);
return new ResponseEntity<ResponseWrapper>(wrapper, HttpStatus.OK);
}

How to read json with mulitple array in spring mvc controller?

I am sending json from ajax to controller that contain multiple array.
Json Data:
{
"node": [
{
"id": "dev_1",
"blockId": "11"
},
{
"id": "dev_2",
"blockId": "15"
}
],
"connect": [
{
"id": "con_5",
"typeId": "2"
}
],
"name": "test"
}
Controller:
#RequestMapping(value = "/saveBoard", method = RequestMethod.POST)
public JsonResponse saveBoard(#RequestBody String jsonData) throws IOException {
JsonResponse response = new JsonResponse();
ObjectMapper mapper = new ObjectMapper();
final JsonNode jsonNode = mapper.readTree(jsonData).get("node");
if(jsonNode.isArray()) {
for (final JsonNode nodes : jsonNode) {
System.out.println("jsonNode : "+ nodes);
}
}
return response;
}
I have tried with object mapper but not succeed.
Here i want to read different array for different classes like node for node class with some specified fields, connect for connect class and string for another use.
UPDATE
Contorller:
#RequestMapping(value = "/saveBoard", method = RequestMethod.POST)
public JsonResponse saveMissionBoard(#RequestBody MissionJsonPojo chartJson) {
boolean status = false;
String messsage = "";
JsonResponse response = new JsonResponse();
System.out.println("data : " + flowChartJson.getNodes());
return response;
}
Ajax:
$.ajax({
url: '<c:url value="/board/saveBoard"/>',
type: 'POST',
data: JSON.stringify(chartJson),
dataType: "json",
contentType: "application/json",
success: function(response) {
console.log("In success");
},
error: function (a, b, c) { }
});
JSON:
{
"nodes": [
{
"missionDeviceId": "device_1",
"device": "1",
"deviceXCoordinate": 79,
"deviceYCoordinate": 73,
"blockId": "1##1"
},
{
"missionDeviceId": "device_2",
"device": "3",
"deviceXCoordinate": 340,
"deviceYCoordinate": 146,
"blockId": "2##5"
}
],
"connections": [
{
"missionConnectionId": "con_5",
"sourceId": "device_1",
"targetId": "device_2",
"device": "2"
}
],
"name": "test"
}
Node Pojo:
public class Nodes{
private String missionDeviceId;
private Integer device;
private String deviceXCoordinate;
private String deviceYCoordinate;
private String blockId; //getters setters
}
Connection Pojo:
public class Connections{
private String missionConnectionId;
private String sourceId;
private String targetId;
private Integer device; //getters and setters
}
MissionJsonPojo:
public class MissionJsonPojo{
private List<Nodes> nodes;
private List<Connections> connections;
private String name; //getters and setters
}
As suggested by #dambros, create a POJO structure like this:
public class Node {
private String id;
private String blockId;
//setter-getters.
}
public class Connect {
private String id;
private String typeId;
//setter-getters.
}
import java.util.List;
public class Payload {
private List<Node> nodes;
private List<Connect> connects;
private String name;
//setter-getters
}
And change your method signature to:
public JsonResponse saveBoard(#RequestBody Payload payload) throws IOException {
}
This should solve your problem.

Categories

Resources