How can I convert that json string to my class - gson

I have a json string that has a data like this:
description: { "en" : "english desc", "es": "spanish description" }
This field is in my Item class, but it is a string:
class Item
private String description;
I am using GSON to parse this Json. I am getting error because data in Json string is not a string. It's a JSON object.
I should give a parameter of default language(en for example) and it should be parsed like:
description = "english desc"
How can I do that?

Description should be a composite object which contains en and es string fields as per your input string.
refer e.g.
import com.google.gson.Gson;
public class Demo1 {
class Item {
Description description;
public Description getDescription() {
return description;
}
public void setDescription(Description description) {
this.description = description;
}
#Override
public String toString() {
return "Item [" + description + "]";
}
class Description {
String en;
String es;
public String getEn() {
return en;
}
public void setEn(String en) {
this.en = en;
}
public String getEs() {
return es;
}
public void setEs(String es) {
this.es = es;
}
#Override
public String toString() {
return "Description [en=" + en + ", es=" + es + "]";
}
}
}
public static void main(final String[] args) {
String json = "{ description: { \"en\" : \"english desc\", \"es\": \"spanish description\" } }";
Gson gson = new Gson();
Item i = gson.fromJson(json, Item.class);
System.out.println("item:" + i);
}
}

Related

Spring Web Client Not Binding JSON to POJO correctly?

Hi I'm using Spring Web Client to access Taste Dive REST API.
Here's the method I use to access the endpoint
public TasteDiveItemDto getReccs(Collection<Book> bookCollection) {
String parameters = "";
for(Book b : bookCollection)
parameters = parameters + "book:" + b.getTitle() + "%2C";
// remove the %2C at end of string
parameters = parameters.substring(0, parameters.length() - 3);
logger.info("Parameters = " + parameters);
// We want 2 reccs for every 1 book in the collection
int limit = bookCollection.size() * 2;
String req = "/similar" + "?q=" + parameters + "&" + "k=" + API_KEY + "&" + "limit=" + Integer.toString(limit);
logger.info("req = " + req);
logger.info("Accessing TasteDive API...");
return CLIENT.get().uri(req).retrieve().bodyToMono(TasteDiveItemDto.class).block();
}
And here are my POJOs
public class TasteDiveItemDto {
#JsonProperty("Similar")
private Similar similar;
public Similar getSimilar() {
return similar;
}
public void setSimilar(Similar similar) {
this.similar = similar;
}
#Override
public String toString() {
return "TasteDiveItemDto [similar=" + similar + "]";
}
}
public class Similar {
#JsonProperty("Info")
private Info[] info;
#JsonProperty("Results")
private Info[] results;
public Info[] getInfo() {
return info;
}
public void setInfo(Info[] info) {
this.info = info;
}
public Info[] getResults() {
return results;
}
public void setResults(Info[] results) {
this.results = results;
}
#Override
public String toString() {
return "Similar [info=" + Arrays.toString(info) + ", results=" + Arrays.toString(results) + "]";
}
}
public class Info {
#JsonProperty("Name")
private String name;
#JsonProperty("Type")
private String type;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#Override
public String toString() {
return "Info [name=" + name + ", type=" + type + "]";
}
}
Here's what I'm getting back from the endpoint when I use my toString method
TasteDiveItemDto
[
similar=
Similar
[
info=
[
Info
[
name=book:chemistry%2cbook:norwegian wood%2cbook:infinite jest%2cbook:flowers for algernon,
type=unknown
],
Info
[
name=book:chemistry%2cbook:norwegian wood%2cbook:infinite jest%2cbook:flowers for algernon,
type=unknown
]
],
results=[]
]
]
So what's essentially getting mapped are the parameters I put in the endpoint and not the correct JSON response. I've tried to use #JsonProperty on the methods and fields but to no luck.
I'm still a beginner at Spring and only read a bit of the Web Client documentation so I can't figure out entirely what I'm doing incorrectly. The strange thing is when I used Web Client to access Google Books API using the same methodology it worked out perfectly.
Please let me know if you need anymore information from my program. Thanks!

Spring Rest -> Hibernate entity to JSON

I am creating REST API using spring framework. My entity is based on one table and REST API is supposed to be invoked using POST operation with below JSON structure. Can someone explain me how to map the entity class so that it can consume below-shown json.
Since my entity is based on only one table, I am not able to understand how can it create nested json objects for same table properties.
{
"process_ar_receipt": {
"message_header": {
"source_system_guid": "DDED-DBCD-REV-E1F4343DB3434",
"source_system": "MeSo_TravelAds"
},
"receipt_header": {
"customer_number": "123",
"source_receipt_number": "TESTRCPT_1523",
}
}
}
you could use Gson to convert the json to a DTO
https://jarroba.com/gson-json-java-ejemplos/
pseudo code
assuming your Entity class as
#Entity(name="foo")
class Data{
#Id
private String source_system_guid;
#Column
private String source_system;
#Column
private String customer_number;
#Column
private String source_receipt_number;
public Data() {}
public Data(String ssId, String sourceSystm, String custNum, String srcRcptNum) {
this.source_system_guid = ssId;
this.source_system = sourceSystm;
this.customer_number = custNum;
this.source_receipt_number = srcRcptNum;
}
public String getSource_system_guid() {
return source_system_guid;
}
public void setSource_system_guid(String source_system_guid) {
this.source_system_guid = source_system_guid;
}
public String getSource_system() {
return source_system;
}
public void setSource_system(String source_system) {
this.source_system = source_system;
}
public String getCustomer_number() {
return customer_number;
}
public void setCustomer_number(String customer_number) {
this.customer_number = customer_number;
}
public String getSource_receipt_number() {
return source_receipt_number;
}
public void setSource_receipt_number(String source_receipt_number) {
this.source_receipt_number = source_receipt_number;
}
}
Now since your DTO/BO i.e. Data Transfer Object or Business Object is different from the actual entity we will create the required BO object as below
class DataTO{
#JsonProperty("process_ar_receipt")
private ReceiptTO receiptTO=new ReceiptTO();
public ReceiptTO getReceiptTO() {
return receiptTO;
}
public void setReceiptTO(ReceiptTO receiptTO) {
this.receiptTO = receiptTO;
}
}
class ReceiptTO{
#JsonProperty("message_header")
private MessageHeader messageHeder = new MessageHeader();
#JsonProperty("receipt_header")
private ReceiptHeader receiptHeder = new ReceiptHeader();
public MessageHeader getMessageHeder() {
return messageHeder;
}
public void setMessageHeder(MessageHeader messageHeder) {
this.messageHeder = messageHeder;
}
public ReceiptHeader getReceiptHeder() {
return receiptHeder;
}
public void setReceiptHeder(ReceiptHeader receiptHeder) {
this.receiptHeder = receiptHeder;
}
}
class MessageHeader{
#JsonProperty("source_System_Guid")
private String sourceSystemId;
#JsonProperty("system_Id")
private String systemId;
public String getSourceSystemId() {
return sourceSystemId;
}
public void setSourceSystemId(String sourceSystemId) {
this.sourceSystemId = sourceSystemId;
}
public String getSystemId() {
return systemId;
}
public void setSystemId(String systemId) {
this.systemId = systemId;
}
}
class ReceiptHeader{
#JsonProperty("customer_number")
private String customerNumber;
#JsonProperty("source_rcpt_number")
private String sourceReceiptNumber;
public String getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(String customerNumber) {
this.customerNumber = customerNumber;
}
public String getSourceReceiptNumber() {
return sourceReceiptNumber;
}
public void setSourceReceiptNumber(String sourceReceiptNumber) {
this.sourceReceiptNumber = sourceReceiptNumber;
}
}
The #JsonProperty annotation is imported from org.codehaus.jackson.annotate.JsonProperty; i.e from jackson jar
Now a Simple Test class to demo DTO/BO back and forth Entity conversion
public class Test{
public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
List<Data> datas = new ArrayList<Data>();
datas.add(new Data("DDED-DBCD-REV-E1F4343DB3434","MeSo_TravelAds","123","TESTRCPT_1523"));
datas.add(new Data("ADED-EWQD-REV-E1F4343YG3434","FooSo_MusicAds","132","TESTRCPT_1523"));
datas.add(new Data("YDED-YUTR-REV-E1F43UIDB3434","BarSo_HealthAds","143","TESTRCPT_1523"));
List<DataTO> dataTOs = new ArrayList<DataTO>();
for (Data data : datas) {
DataTO dataTO = new DataTO();
dataTO.getReceiptTO().getMessageHeder().setSourceSystemId(data.getSource_system_guid());
dataTO.getReceiptTO().getMessageHeder().setSystemId(data.getSource_system());
dataTO.getReceiptTO().getReceiptHeder().setCustomerNumber(data.getCustomer_number());
dataTO.getReceiptTO().getReceiptHeder().setSourceReceiptNumber(data.getSource_receipt_number());
dataTOs.add(dataTO);
}
ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(dataTOs);
System.out.println(str);
}
}
This will give you below result
[
{
"process_ar_receipt":{
"message_header":{
"source_System_Guid":"DDED-DBCD-REV-E1F4343DB3434",
"system_Id":"MeSo_TravelAds"
},
"receipt_header":{
"customer_number":"123",
"source_rcpt_number":"TESTRCPT_1523"
}
}
},
{
"process_ar_receipt":{
"message_header":{
"source_System_Guid":"ADED-EWQD-REV-E1F4343YG3434",
"system_Id":"FooSo_MusicAds"
},
"receipt_header":{
"customer_number":"132",
"source_rcpt_number":"TESTRCPT_1523"
}
}
},
{
"process_ar_receipt":{
"message_header":{
"source_System_Guid":"YDED-YUTR-REV-E1F43UIDB3434",
"system_Id":"BarSo_HealthAds"
},
"receipt_header":{
"customer_number":"143",
"source_rcpt_number":"TESTRCPT_1523"
}
}
}
]
similarly the other conversion
String input = "{ \r\n" +
" \"process_ar_receipt\":{ \r\n" +
" \"message_header\":{ \r\n" +
" \"source_System_Guid\":\"ADED-EWQD-REV-E1F4343YG3434\",\r\n" +
" \"system_Id\":\"FooSo_MusicAds\"\r\n" +
" },\r\n" +
" \"receipt_header\":{ \r\n" +
" \"customer_number\":\"132\",\r\n" +
" \"source_rcpt_number\":\"TESTRCPT_1523\"\r\n" +
" }\r\n" +
" }\r\n" +
" }";
DataTO dataTO = mapper.readValue(input, DataTO.class);
System.out.println(dataTO.getReceiptTO().getMessageHeder().getSourceSystemId());
System.out.println(dataTO.getReceiptTO().getMessageHeder().getSystemId());
System.out.println(dataTO.getReceiptTO().getReceiptHeder().getCustomerNumber());
System.out.println(dataTO.getReceiptTO().getReceiptHeder().getSourceReceiptNumber());
this will print
ADED-EWQD-REV-E1F4343YG3434
FooSo_MusicAds
132
TESTRCPT_1523
You dont have to use the mapper code you can directly add the jackson converter as HttpMessageConverted which will convert the JSON to java object automatically
#Configuration
#EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {
... other configurations
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
builder.propertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
builder.serializationInclusion(Include.NON_EMPTY);
builder.indentOutput(true).dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
}
}

Junit : status expected <200> but it was <400>

I am trying to write test case for post request on controller level. when I am running through postman I am getting 200 0k
#RestController
#RequestMapping("/hello")
public class HelloResource {
#Autowired
HelloService helloService;
#PostMapping("/post")
public Hello helloPost(#RequestBody Hello hello) {
return hello;
}
}
class Hello {
private String title;
private String value;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Hello(String title, String value) {
super();
this.title = title;
this.value = value;
}
public Hello() {
super();
}
}
Test case
#Test
public void helloPost() throws Exception {
String json = "{\n" +
" \"title\":\"Greetting\", \n" +
" \"value\":\"Hello world\",\n" +
"}";
mockMvc.perform(post("/hello/post")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk());
Try the json like below:-
String json = "{\"title\":\"Greetting\",\"value\":\"Hello world\"}";

DAO instance not working in service class - NullPointerException

In my spring boot project I created a Repository interface (which extends CRUDRepository) and an Entity class of the Table in my DB.
This is my Repo:
#Repository
public interface AuthPaymentDao extends CrudRepository<TFraudCard,String> {
#Query("SELECT t FROM TFraudCard t where t.tokenNumber = (?1)")
TFraudCard findByTokenNumber(String tokenNumber);
}
This is my Entity Class (TOKEN_NUMBER is the primary Key in the TFRAUDCARD TABLE):
#Entity
#Table(name = "TFRAUDCARD")
public class TFraudCard {
#Id
#Column(name="TOKEN_NUMBER")
private String tokenNumber;
#Column(name="TRANSACTIONNUMBER")
private int transactionNumber;
#Column(name="CARDNUMBER")
private int cardNumber;
#Column(name="DATEADDED", insertable = false, updatable = false, nullable = false)
private Timestamp dateAdded;
#Column(name="CALLINGENTITY", nullable = false)
private String callingEntity;
#Column(name="ACCOUNTID")
private String accountId;
#Column(name="ROUTINGNUMBER")
private String routingNumber;
#Column(name="BANKACCOUNTNUMBER")
private String bankAccountNumber;
#Column(name="COMMENTS")
private String comments;
#Column(name="USERID")
private String userId;
#Column(name="REMOVEDATE")
private Timestamp removeDate;
public String getTokenNumber() {
return tokenNumber;
}
public void setTokenNumber(String tokenNumber) {
this.tokenNumber = tokenNumber;
}
public int getTransactionNumber() {
return transactionNumber;
}
public void setTransactionNumber(int transactionNumber) {
this.transactionNumber = transactionNumber;
}
public int getCardNumber() {
return cardNumber;
}
public void setCardNumber(int cardNumber) {
this.cardNumber = cardNumber;
}
public Timestamp getDateAdded() {
return dateAdded;
}
public void setDateAdded(Timestamp dateAdded) {
this.dateAdded = dateAdded;
}
public String getCallingEntity() {
return callingEntity;
}
public void setCallingEntity(String callingEntity) {
this.callingEntity = callingEntity;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getRoutingNumber() {
return routingNumber;
}
public void setRoutingNumber(String routingNumber) {
this.routingNumber = routingNumber;
}
public String getBankAccountNumber() {
return bankAccountNumber;
}
public void setBankAccountNumber(String bankAccountNumber) {
this.bankAccountNumber = bankAccountNumber;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public Timestamp getRemoveDate() {
return removeDate;
}
public void setRemoveDate(Timestamp removeDate) {
this.removeDate = removeDate;
}
public TFraudCard() {
super();
}
public TFraudCard(String tokenNumber, int transactionNumber, int cardNumber, Timestamp dateAdded,
String callingEntity, String accountId, String routingNumber, String bankAccountNumber, String comments,
String userId, Timestamp removeDate) {
super();
this.tokenNumber = tokenNumber;
this.transactionNumber = transactionNumber;
this.cardNumber = cardNumber;
this.dateAdded = dateAdded;
this.callingEntity = callingEntity;
this.accountId = accountId;
this.routingNumber = routingNumber;
this.bankAccountNumber = bankAccountNumber;
this.comments = comments;
this.userId = userId;
this.removeDate = removeDate;
}
#Override
public String toString() {
return "TFraudCard [tokenNumber=" + tokenNumber + ", transactionNumber=" + transactionNumber + ", cardNumber="
+ cardNumber + ", dateAdded=" + dateAdded + ", callingEntity=" + callingEntity + ", accountId="
+ accountId + ", routingNumber=" + routingNumber + ", bankAccountNumber=" + bankAccountNumber
+ ", comments=" + comments + ", userId=" + userId + ", removeDate=" + removeDate + "]";
}
}
My Service Class:
Autowiring the DAO instance inside my Service Class:
Implementing the DAO instance inside a Method in the Service Class:
private void fraudCheck(PaymentDetail paymentDetail) throws RegularPaymentBusinessException {
logger.info("INSIDE FRAUD CHECK METHOD");
String pmtInd=paymentDetail.getPmtInd();
logger.info("pmtInd: " + pmtInd);
String tokenizedCardNum=paymentDetail.getTokenizedCardNum();
logger.info("tokenizedCardNum: " + tokenizedCardNum);
if(pmtInd.equalsIgnoreCase(VepsConstants.GIFT_CARD_IDENTIFIER) || pmtInd.equalsIgnoreCase(VepsConstants.CREDIT_CARD_IDENTIFIER) || pmtInd.equalsIgnoreCase(VepsConstants.DEBIT_CARD_IDENTIFIER)) {
logger.info("INSIDE CARD CHECK");
TFraudCard fraudCard = authPaymentDao.findByTokenNumber(tokenizedCardNum);
logger.info("fraudCard Details: " + fraudCard.toString());
if(fraudCard!=null) {
logger.info("INSIDE EXCEPTION FLOW FOR CARD FRAUD CHECK");
throw new RegularPaymentBusinessException(VepsConstants._9966, VepsConstants._9966_MESSAGE, VepsConstants.FAILURE);
}
}
}
Even though I pass the same token Number (tokenizedCardNumber) in my method as the data in the TOKEN_NUMBER column of my TFRAUDCARD table I still get a NullPointerException when I try to print a toString() of the Entity Object.
Here is the NullPointerException on my cloudFoundry logs (Click on it to see zoomed image) :
I'm providing the DB details in my dev properties file:
I have gone over every scenario in my head for why it breaks but I still can't come up with an answer. I'm using my variable marked with #Id i.e. the Primary Key for my find() method in the Repository.
I'm also adding a #Query annotation just to be even more specific.
It still does not work.

problems with FindByLocationWithin

I'm trying to query a mongo repository to return data that is within a specified geo circle. I'm using the following code:
Page<Img> findByLocationWithin(Circle circle, Pageable pageable);
and then in my controller I'm using:
Distance distance = new Distance(7.5, Metrics.MILES);
Circle circle = new Circle(location, distance);
Page<Img> results = imgRepository.findByLocationWithin(circle, pageable);
However it definitely doesn't use a radius of 7.5 miles as if I create the circle a few hundred metres away from where the data is located, it returns nothing. I've checked the logs in mongo and it says that the following code is being performed:
"location" : {
"$within" : {
"$center" : [
[
30.198,
-1.695
],
0.0018924144710663706
]
}
}
This means it's not using $geoWithin or $centerSphere. How can I fix these problems?
I had the same problem with spring and Couchbase... but the query is not the problem... Because Spring convert the distance in the geometric values.
In my case I also returned null, but my problem was solved, in the model class, the attribute that specifies the coordinate [x, y] must be of type Library Point org.springframework.data.geo.Point;
package com.webServices.rutas.model;
import org.springframework.data.couchbase.core.mapping.id.GeneratedValue;
import org.springframework.data.couchbase.core.mapping.id.GenerationStrategy;
import org.springframework.data.geo.Point;
import com.couchbase.client.java.repository.annotation.Field;
import com.couchbase.client.java.repository.annotation.Id;
public class Parada {
#Id #GeneratedValue(strategy = GenerationStrategy.UNIQUE)
private String id;
#Field
private String type;
#Field
private String nombre;
#Field
private String urlFoto;
#Field
private Point coordenada;
public Parada(String nombre, String urlFoto, Point coordenada) {
super();
this.type = "parada";
this.nombre = nombre;
this.urlFoto = urlFoto;
this.coordenada = coordenada;
}
public Parada() {
super();
this.type = "parada";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getUrlFoto() {
return urlFoto;
}
public void setUrlFoto(String urlFoto) {
this.urlFoto = urlFoto;
}
public Point getCoordenada() {
return coordenada;
}
public void setCoordenada(Point coordenada) {
this.coordenada = coordenada;
}
#Override
public String toString() {
return "Parada [id=" + id + ", type=" + type + ", nombre=" + nombre + ", urlFoto=" + urlFoto + ", coordenada="
+ coordenada + "]";
}
}
In the service:
public Iterable<Parada> getParadasCercanasRadio(Punto punto){
Point cuadro = new Point(-2.2,-80.9);
Circle circle = new Circle(cuadro,new Distance(300000, Metrics.KILOMETERS));
return paradaRepository.findByCoordenadaWithin(circle);
}
In the Repository:
#Dimensional(designDocument = "paradas", spatialViewName = "paradas")
Iterable<Parada> findByCoordenadaWithin(Circle p);
P.D. Sorry for my English.

Resources