How to add a list to an object in Spring - java

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);
}

Related

Jackson with Spring WebFlux

Json:
{
"response": {
"count": 3,
"items": [
6651536,
20410167,
40345521
]
}
}
NOT WORK - FriendsDTO:
#Jacksonized
#Builder
#Value
public class FriendsDTO {
int count;
#JsonProperty("items")
List<Integer> friends;
}
WORK - FriendsDTO:
#Jacksonized
#Builder
#Value
public class FriendsDTO {
Response response;
#Jacksonized
#Builder
#Value
public static class Response {
int count;
#JsonProperty("items")
List<Integer> friends;
}
}
WebFluxClient request:
FriendsDTO friends = webFluxClient.get()
.uri(config.methodGetFriends(), builder -> {
builder.queryParam("access_token", accessToken);
builder.queryParam("v", config.version());
return builder.build();
})
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(FriendsDTO.class)
.log()
.block();
logger.info(friends.toString());
output WORK: FriendsDTO(response=FriendsDTO.Response(count=3, friends=[6651536, 20410167, 40345521]))
output NOT WORK: FriendsDTO(count=0, friends=null)
How can I get rid of this misunderstanding in the Response view for successful json parsing ?
Thats the expected behaviour
{
name : "name",
description : "description"
}
This can be written as
class <ClassName>{
private String name;
private String description;
}
The json does not carry the ClassName. Similarly in your case, the word Response should be a valid attribute, like how I defined name in this example.
So , if you want , this class to work
#Jacksonized
#Builder
#Value
public class FriendsDTO {
int count;
#JsonProperty("items")
List<Integer> friends;
}
You JSON should be changed from
{
"response": {
"count": 3,
"items": [
6651536,
20410167,
40345521
]
}
}
To
{
"count": 3,
"items": [
6651536,
20410167,
40345521
]
}

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

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?

Spring REST API, custom entity fields in the response

I'm working in a REST API (Java, SpringBoot, QueryDsl...) and I would like to customize the fields that I have in the result. By default I'm obtaining all fields of the entity but the fields that I need depends on the request. This should be something dynamic.
As far as I know, using projections I can obtain something like this but I have to declare previously the projection and I would like to work with something dynamic not static. On the other hand I have seen than something like GraphQL allows this behaviour but I would have to refactor everything.
Has anyone had this problem before?
This is my code:
BaseRestCRUDController
public abstract class BaseRestCRUDController<T extends EntityBase, V extends BaseDTO> {
#GetMapping("/list")
public ResponseEntity<List<V>> findAll(Predicate predicate, Pageable pageable) {
log.info("FindAll");
return new ResponseEntity(getCRUDService().findAll(predicate, pageable), HttpStatus.OK);
}
}
ExampleController
#RestController
#RequestMapping("/api/example")
public class ExampleController
extends BaseRestCRUDController<Example, ExampleDTO> {
#Autowired
private ExampleService ExampleService;
#Override
public ResponseEntity<List<ExampleDTO>> findAll(
#QuerydslPredicate(root = Example.class) Predicate predicate, Pageable pageable) {
return super.findAll(predicate, pageable);
}
#Override
protected CRUDService<Example, ExampleDTO> getCRUDService() {
return ExampleService;
}
}
Example (Entity)
public class Example {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "creation_date")
private Instant creationDate;
#Column(name = "last_update")
private Instant lastUpdate;
#Column(name = "erasure_date")
private Instant erasureDate;
}
http://localhost:8080/api/example/list?name=test&page=0&size=5&sort=id,desc
http://localhost:8080/api/example/list?name=foo&page=1&size=10&sort=id,desc
http://localhost:8080/api/example/list?page=0&size=2&sort=id,asc
[
{
"id": 1,
"name": "e1",
"creationDate": "2021-11-15T23:00:00Z",
"lastUpdate": null,
"erasureDate": null
},
{
"id": 2,
"name": "e2",
"creationDate": "2021-11-15T23:00:00Z",
"lastUpdate": null,
"erasureDate": null
},
{
"id": 3,
"name": "e3",
"creationDate": "2021-11-15T23:00:00Z",
"lastUpdate": null,
"erasureDate": null
}
]
How can I obtain something like this without use projections?
http://localhost:8080/api/example/list?fields=id,name&page=1&size=10&sort=id,desc
[
{
"id": 1,
"name": "e1"
},
{
"id": 2,
"name": "e2"
},
{
"id": 3,
"name": "e3"
}
]
http://localhost:8080/api/example/list?fields=name&page=1&size=10&sort=id,desc
[
{
"name": "e1",
},
{
"name": "e2",
},
{
"name": "e3",
}
]
#Ignore
private Instant creationDate;
Try this.
You can use #Ignore on getter,setter or fields.

Spring RestTemplate returns null object when trying to deserialize nested list of object

So this is the Json I am trying to convert to a Java bean
I am using jackson to bind JSON to my data objects
{
"legend": {
"id": "379ec5d8c",
"name": "Stabil Koos",
"payers": [{
"id": "ab1651df-b835-495558-a2a5-2e6d42f7a41e",
"ranking": 1,
"buyer": {
"id": "67a6359838-0fda-43a6-9e2b-51a7d399b6a1",
"nationality": "en",
"stats": {
"gameeCount": 16581,
"count": 99098
}
}
},
{
"id": "379ecw555d8c",
"ranking": 2,
"buyer": {
"id": "2b451d0eda-ab0c-4345660-be3f-6ba3bebf1f81",
"nationality": "no",
"stats": {
"gamerCount": 1182,
"count": 7113
}
}
}
]
}
}
My beans look like this ;
public class League implements Serializable {
private String id;
private String name;
#JsonUnwrapped
private List<Payer> payers;
// getters and setters
Payers bean :
public class Payers implements Serializable {
private String id;
private long ranking;
private Buyer buyer;
// getters and setters
I am using Rest Template and postForObject in Junit
#Before
public void beforeTest() {
restTemplate = new RestTemplate();
headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
entity = new HttpEntity(REQUEST, headers);
}
And my final code to retrieve the object is :
#Test
public void retrieveData() {
League league = restTemplate.postForObject(ENDPOINT_URL, entity, League.class);
System.out.println(legend);
}
The JSON you show is for an object that has a league property which is a League object and not a league object itself. You need an additional response class:
class LeagueResponse {
private League league;
League getLeague() { return league; }
}
and:
LeagueResponse leagueResponse = restTemplate.postForObject(ENDPOINT_URL, entity, LeagueResponse.class);
League league = leagueResponse.getLeague();

Mapping complex JSON objects in RestTemplate

The structure of JSON looks like:
{
"id": "0001",
"type": "portable",
"name": "mobile",
"results":[
{
"company": "Apple",
"country": "US",
"city": "Cupertino"
},
{
"company": "Google",
"country": "Japan",
"city": "Tokyo"
}
]
}
I tried to map the above json to my "Response" class but I could only retrieve id, type and name. For json object "results" is shows results:[].
Here is the code I have implemented;
CompanyDetail class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class CompanyDetail {
public String company;
public String country;
public String city;
//getters and setters
}
Company class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class CompanyD {
public String name;
public List<Detail> result;
//getters and setters
}
Implementation class:
#Override
public ResponseEntity<String> getResponseEntity() {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate .getForEntity(
"url", String.class);
logger.info("Response:"+response);
return response;
}
#Override
public Company getResponseObject() {
RestTemplate restTemplate=new RestTemplate();
Company comp=(Company) restTemplate.getForObject("url",
Company.class,200);
List<CompanyDetail> companyInfo = comp.getCompanyDetail();
for (CompanyDetail companyDetail : companyInfo) {
logger.info("Country:"+companyDetail.getCountry());
logger.info("City:"+companyDetail.getCity());
logger.info("Company:"+companyDetail.getCompany());
}
return comp;
From both the implementation method I am getting null values for the "results" json object. I could not figure out what is wrong with my code.
Thanks in advance.
I'm having the same issue however in your case it looks like you misspelled "resluts".

Categories

Resources