Spring boot rest service duplicated response body - java

I'm using Spring Boot framework and my response returns duplicated with reversed backward.
I'm asking for advices, how can i solve this situation?
Controller End Point
#GetMapping("/getPDetailsW/{W}")
public PPreviewW getPDetailsPreviewW(#PathVariable String W) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
String nullCheckBill = "bos";
PPreviewW response = new PromoPreviewWGsm();
PPreviewInfo pPreviewInfo = listRepository.findPByW(W);
log.info(dtf.format(now) + "|getPDetailsPreviewW|" + W+ "|için istek atıldı.");
response.setDisplayId(pPreviewInfo.getDISPLAY_ID());
response.setAccountCode(pPreviewInfo.getACCOUNT_CODE());
if (pPreviewInfo.W!= "bos") {
nullCheckBill = promoPreviewInfo.W;
}
if (nullCheckBill == "bos") {
response.setNEXTFLAG(Boolean.FALSE);
} else {
response.setNEXTFLAG(Boolean.TRUE);
}
return response;
}
I have #RestController annotation at top of my Controller class.
PPreviewW response class
#Getter
#Setter
public class PPreviewW implements Serializable {
public String DisplayId;
public String AccountCode;
}
I'm using lombok getters and setters
Repository Class
public PPreviewInfo findPByW(String W) {
PPreviewInfo list = jdbcTemplate
.queryForObject(QueryConstants.GET_P_PREVIEW_INFOW, new Object[]{W}, new PPreviewInfoMapper());
return list;
}
#Repository and #Autowired annotations at top of Repository class.
and QueryContants includes my sql which returns correct size for example like XXXX and YYYY
PPreviewInfo Class
#Getter
#Setter
public class PPreviewInfo {
public String CUSTOMER_ID;
public String BILLING_ACCOUNT_CODE;
}
PPreviewInfoMapper Class
public class PPreviewInfoMapper implements RowMapper<PPreviewInfo> {
#Override
public PPreviewInfo mapRow(ResultSet rs, int i) throws SQLException {
PPreviewInfo pbn = new PPreviewInfo();
pbn.setDISPLAY_ID(rs.getString("DISPLAY_ID"));
pbn.setACCOUNT_CODE(rs.getString("ACCOUNT_CODE"));
return pbn;
}
}
response
{"DisplayId":"XXXX","AccountCode":"YYYYYY","NEXTFLAG":true,"nextflag":true,"displayId":"XXXX","accountCode":"YYYYYY"}

The visibility of the attributes might be causing the issue, you can see if changing them to private might help in resolution:
#Getter
#Setter
public class PPreviewW implements Serializable {
private String DisplayId;

Related

Spring Data Couchbase: Count() nor findAll() does not work but findBy() works

I am currently setting up a Rest API server using Spring Boot (v2.5.5), Spring Data Couchbase (v4.2.5) and Couchbase (v6.6.1).
I get a really strange behavior when requesting
count() -> 0
findAll() -> []
Whereas
findById() is returning a result.
My entity:
{"mkey": { "keyContent": "AA", "mkeyStatus": "L" }, "sequences": [ { "direction": "B", "loc1Value": "NCE", "loc2Value": "NYC" } ] }
#Document #Data #AllArgsConstructor #NoArgsConstructor #EqualsAndHashCode public class AirlineProfile {
#Id private String id;
#Field private MKey mkey;
#Field private List<Sequence> sequences;
#EqualsAndHashCode #AllArgsConstructor #NoArgsConstructor #Data static class MKey {
#Field private String keyContent;
#Field private String mkeyStatus;
}
#EqualsAndHashCode #AllArgsConstructor #NoArgsConstructor #Data static class Sequence {
#Field private String loc1Value;
#Field private String loc2Value;
#Field private String direction;
}
}
My repository is extending the CrudRepository.
public interface AirlineProfileRepository extends CrudRepository<AirlineProfile, String> {}
While my Service is the following:
#Service #Qualifier("AirlineProfileServiceImpl") public class AirlineProfileServiceImpl
implements AirlineProfileService {
#Autowired private AirlineProfileRepository airlineProfileRepository;
#Override
public long count() {
return airlineProfileRepository.count();
}
#Override
public List<AirlineProfile> findAll() {
List<AirlineProfile> airlineProfiles = new ArrayList<>();
for (AirlineProfile airlineProfile : airlineProfileRepository.findAll()) {
airlineProfiles.add(airlineProfile);
}
return airlineProfiles;
}
#Override public AirlineProfile findById(String id) {
return airlineProfileRepository.findById(id).orElse(null);
}
}
And my controller the following:
#RestController #RequestMapping("/api") public class AirlineProfileController {
#Autowired AirlineProfileService airlineProfileService;
#GetMapping("/airlineprofile/count") public long count() {
System.out.println("Count");
return airlineProfileService.count();
}
#GetMapping("/airlineprofile/all") public List<AirlineProfile> getAllAirlineProfiles() {
System.out.println("Get all AirlineProfile");
return airlineProfileService.findAll();
}
#GetMapping("/airlineprofile/id={id}") public AirlineProfile getAirlineProfileById(#PathVariable String id) {
System.out.println("Get AirlineProfile for id = " + id);
return airlineProfileService.findById(id);
}
}
I do not know if I missed something at Server or Couchbase side ... :(
Thank you for your help!
Ok, found that:
public interface AirlineProfileRepository extends CrudRepository<AirlineProfile, String> {
#Query("#{#n1ql.selectEntity}")
List<AirlineProfile> findAll();
}
Is working ...
So, I am questioning myself about the usability of findAll() ...

Using #JsonCreator to create two instances of same class in one JSON DTO

I would like to deserialize JSON of this structure:
{
"employee_pricing_type":"COMPUTE_BY_OWN_RATE",
"employee_rate":10,
"customer_pricing_type":"COMPUTE_BY_OWN_RATE",
"customer_rate":200
}
I have such POJO to create price setting from a HTTP request:
public class ObjectPricingSetting {
#JsonProperty("pricing_type") // describes output
private final ObjectPricingType pricingType;
#JsonProperty("own_rate") // describes output
private final BigDecimal ownRate;
public ObjectPricingSetting(final ObjectPricingType pricingType, final BigDecimal ownRate) {
AssertUtils.notNull(pricingType, "pricingType");
this.pricingType = pricingType;
if (ownRate != null) {
AssertUtils.isGtZero(ownRate, "ownRate");
this.ownRate = ownRate;
} else {
this.ownRate = null;
}
}
public ObjectPricingType getPricingType() {
return pricingType;
}
public BigDecimal getOwnRate() {
return ownRate;
}
}
this is DTO:
#JsonInclude(JsonInclude.Include.NON_NULL)
public class ObjectPricingCommand extends BaseDto<ObjectId> {
#JsonProperty(value = "employee_pricing_setting")
private ObjectPricingSetting employeePricingSetting;
#JsonProperty(value = "customer_pricing_setting")
private ObjectPricingSetting customerPricingSetting;
}
I would like to create these two instances of ObjectPricingSetting with #JsonCreator.
Q: How should I anotate #JsonProperty parameter in ObjectPricingSetting constructor to recognize what JSON value should use to create these two instances?
You can use #JsonUnwrapped with a prefix in your parent class:
#JsonInclude(JsonInclude.Include.NON_NULL)
public class ObjectPricingCommand extends BaseDto<ObjectId> {
#JsonUnwrapped(prefix = "employee_")
private ObjectPricingSetting employeePricingSetting;
#JsonUnwrapped(prefix = "customer_")
private ObjectPricingSetting customerPricingSetting;
}
Then you can use the normal #JsonCreator/#JsonProperty in your nested DTO, without the prefix:
public class ObjectPricingSetting {
#JsonCreator
public ObjectPricingSetting(
#JsonProperty("pricing_type") final ObjectPricingType pricingType,
#JsonProperty("rate") final BigDecimal ownRate) {
...

#RestController autoserialize POJO's

I have a Spring mvc application, with a #RestController like such:
#RestController
#RequestMapping("levels")
public class LevelController {
private final GetLevelOneCount getLevelOneCount;
private final GetLevelTwoCount getLevelTwoCount;
private final GetLevelThreeCount getLevelThreeCount;
#Inject
public LevelController(GetLevelOneCount getLevelOneCount,
GetLevelTwoCount getLevelTwoCount,
GetLevelThreeCount getLevelThreeCount) {
this.getLevelOneCount = getLevelOneCount;
this.getLevelTwoCount = getLevelTwoCount;
this.getLevelThreeCount = getLevelThreeCount;
}
#GetMapping("/level1/{id}")
public LevelModel levelOne(#PathVariable String id) throws SQLException {
LevelModel levelOneModel = new LevelModel();
levelOneModel.setLevelQuery(getLevelOneCount.execute(id));
levelOneModel.setLevelDirQuery(getLevelOneCount.executeDir(id));
levelOneModel.setLevelDateQuery(getLevelOneCount.executeDate(id));
return levelOneModel;
}
my LevelModel is a POJO with private variables, now i wonder, if this can get serialized to propper JSON with private variables?
package com.pwc.tag.service.levels;
public class LevelModel {
private Long LevelQuery;
private Long LevelDirQuery;
private Long LevelDateQuery;
public Long getLevelQuery() {
return LevelQuery;
}
public void setLevelQuery(Long levelQuery) {
LevelQuery = levelQuery;
}
public Long getLevelDirQuery() {
return LevelDirQuery;
}
public void setLevelDirQuery(Long levelDirQuery) {
LevelDirQuery = levelDirQuery;
}
public Long getLevelDateQuery() {
return LevelDateQuery;
}
public void setLevelDateQuery(Long levelDateQuery) {
LevelDateQuery = levelDateQuery;
}
}
Yes, your object will be serialized to a proper JSON structure including the private field, because of the getters and setters.
If these fields should not be present in the output object, you can add the #JsonIgnore annotation to exclude them from the JSON structure.
P.S. the common approach is to start names of java properties with a lower case letter.

Creating a reusable Reader class in SpringBoot

I'm making a small learning project. In it i'm reading some JSON from a restservice and persisting it in a postgres DB. The restservice has several JSON models that are available from different URL's. I have created a simple reader class that reads the JSON from a url and sends it to the DB. This works with the Model and Service classes hardcoded in the Reader class. I am trying to make it more generic however so i can use the reader class and pass in the model class and service class (that has an add method that calls the save method form the repository for that Model). I tried this with the models implementing an interface and having the interface as parameter in the constructor of the reader class or passing the model classname as a string to the Reader constructor and it being a parameter for a Classloader.
I haven't gotten it to work and probably it is a silly syntax problem but maybe somebody here can help out. Below are the classes:
#Slf4j
#Service
#AllArgsConstructor
public class Reader {
private MapService mapService;
public void readStream(String url) {
try (InputStream is = new URL(url).openStream()) {
JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));
Gson gson = new GsonBuilder().create();
reader.beginArray();
while (reader.hasNext()) {
MapInputModel map = gson.fromJson(reader, MapInputModel.class);
mapService.add(map);
}
reader.close();
} catch (MalformedURLException e) {
log.error("MalformedURLException" + e.getMessage());
} catch (IOException e) {
log.error("IOException" + e.getMessage());
}
}
}
.
#Service
#RequiredArgsConstructor
#Transactional(propagation = Propagation.REQUIRED)
public class MapService {
private final MapModelMapper mapModelMapper;
private final MapEntityRepository mapEntityRepository;
public void add(final MapInputModel mapInputModel) {
mapEntityRepository.save(mapModelMapper.toEntity(mapInputModel));
}
.
#Getter
#AllArgsConstructor
public class MapInputModel {
private String name;
private List<String> translations;
}
The Mapservice and MapInputModel need to be replaceable with similar classes, like:
#Getter
#AllArgsConstructor
public class IconModel {
Map<String, String> icon;
}
I'm using SpringBoot and Lombok in this project.
-------- edit: updated classmodels ---------
#Getter
#AllArgsConstructor
public class MapInputModel implements InputModel {
private String name;
private List<String> translations;
}
public interface IService<T>{
void add(final T model);
}
#Service
#RequiredArgsConstructor
#Transactional(propagation = Propagation.REQUIRED)
public class MapService implements IService<MapInputModel> {
private final MapModelMapper mapModelMapper;
private final MapEntityRepository mapEntityRepository;
#Override
public void add(final MapInputModel mapInputModel) {
mapEntityRepository.save(mapModelMapper.toEntity(mapInputModel));
}
}
#Slf4j
public class Reader {
private IService<InputModel> service;
private InputModel model;
public Reader(IService<InputModel> service, InputModel model) {
this.service = service;
this.model = model;
}
// code
}

Unable to parse json with List elements inside it

I have a Java class which has 2 List Object inside it and i am Json serializing the parent class.
#JsonSerialize
public class RequestSalesJson {
#JsonProperty("nonUniqueSalesList")
private List<SalesDataJson> getNonUniqueSalesDataJson;
#JsonProperty("uniqueSalesList")
private List<SalesDataJson> uniqueSalesDataJson;
public List<SalesDataJson> getGetNonUniqueSalesDataJson() {
return getNonUniqueSalesDataJson;
}
public void setGetNonUniqueSalesDataJson(List<SalesDataJson> getNonUniqueSalesDataJson) {
this.getNonUniqueSalesDataJson = getNonUniqueSalesDataJson;
}
public List<SalesDataJson> getUniqueSalesDataJson() {
return uniqueSalesDataJson;
}
public void setUniqueSalesDataJson(List<SalesDataJson> uniqueSalesDataJson) {
this.uniqueSalesDataJson = uniqueSalesDataJson;
}
}
SalesReturnJson.java
#JsonSerialize
public class SalesReturnJson {
#JsonProperty("starttime")
private String startTime;
#JsonProperty("pn")
private String partNumber;
#JsonProperty("so")
private String SalesOrderNumber;
#JsonProperty("wo")
private String workOrderNumber;
#JsonProperty("loc")
//other variables declared..
}
Controller.java :-
#RequestMapping(value = "/addAllSalesData",method = RequestMethod.POST)
public void addAllSalesData(#RequestBody RequestSalesJson requestSalesJsons){
log.info("POST : '/addSalesData'");
try{
System.out.print("In Controller "+requestSalesJsons.getUniqueSalesDataJson());
//salesService.processSalesData(requestSalesJsons);
}
catch(Exception e){
// return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
The value here is coming to be null.
Below is the json i am using :-
{ "uniqueSalesJson": [{"SO":4000955,"Part Number":"000","Locator":255638,"Lot Number":"P01-2059139","Reservation Quantity":2,"Status":"Released to warehouse","COE":"Fabrication","ORG":"P07","Start_Time":"2017-09-19 11:21:36"},{"SO":4000955,"Part Number":"000","Locator":255652,"Lot Number":"P01-2059140","Reservation Quantity":10,"Status":"Released to warehouse","COE":"Fabrication","ORG":"P07","Start_Time":"2017-09-19 11:21:36"}],"nonUniqueSalesJson":[{"SO":4000992,"Part Number":"1276M84G15","Locator":12345,"Lot Number":"P01-2344141","Reservation Quantity":6,"Status":"PACKED","COE":"Fabrication","ORG":"P07","Start_Time":"2017-09-19 11:21:36"},{"SO":4000992,"Part Number":"1276M84G15","Locator":12345,"Lot Number":"P01-2344141","Reservation Quantity":6,"Status":"PICKED","COE":"Fabrication","ORG":"P07","Start_Time":"2017-09-19 11:21:36"}]}
There are some issues in your code that let me doubt that your application compiles. First of all, rename the SalesReturnJson class to SalesDataJson.
Then check your #JsonProperty annotations. The value here must match exactly the property key in the Json String. Refactoring all this stuff will lead you to your root entity class:
#JsonSerialize
public class RequestSalesJson {
#JsonProperty("nonUniqueSalesJson")
private List<SalesDataJson> nonUniqueSalesDataJson;
#JsonProperty("uniqueSalesJson")
private List<SalesDataJson> uniqueSalesDataJson;
...
}
and your SalesDataJson class (missing a lot of attributes which the mapper ignores by configuration):
#JsonSerialize
public class SalesDataJson {
#JsonProperty("Start_Time")
private String startTime;
#JsonProperty("Part Number")
private String partNumber;
#JsonProperty("SO")
private String SalesOrderNumber;
}
This sample works as expected with the com.fasterxml.jackson.databind.ObjectMapper
Hope that helps!

Categories