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.
Related
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?
I have an API built in Java Spring that return (using JacksonJaxbJsonProvider 2.5.5) a JSON object from this class:
public class FieldValues {
private String code;
private Object value;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
}
In the main object I've
#JsonRootName(value = "WorkRequest")
#XmlRootElement(name = "WorkRequest")
#JsonIgnoreProperties(ignoreUnknown = true)
public class WorkRequestDTOResponse {
private List<FieldValues> fieldValues;
public List<FieldValues> getFieldValues() {
return fieldValues;
}
public void setFieldValues(List<FieldValues> fieldValues) {
this.fieldValues = fieldValues;
}
}
But the output of the fieldValues object is this:
"fieldValues": [
{
"code": "anomaly",
"value": {
"#xsi.type": "ns3:boolean",
"$": "true"
}
},{
"code": "internal_note",
"value": {
"#xsi.type": "ns3:string",
"$": "Test text example"
}
}
]
instead what I need is this:
"fieldValues": [
{
"code": "anomaly",
"value": true
},{
"code": "internal_note",
"value": "Test text example"
}
]
This is my JSON Provider:
public class ErmesJSONProvider extends JacksonJaxbJsonProvider {
public ErmesJSONProvider() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
mapper.configure(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED, false);
_mapperConfig.setMapper(mapper);
_mapperConfig.getConfiguredMapper().setAnnotationIntrospector(new JacksonAnnotationIntrospector());
}
}
Trying to use a String instead an object:
public class FieldValues {
private String code;
private String value;
But if I set this value as String fieldValues.setValue("true"), the JSON output is "value": true instead "value": "true"
Likewise if I set this value as String but with an Integer fieldValues.setValue("1"), the JSON output is "value": 1 instead "value": "1"
If I print the return object using ObjectMapper I've the right JSON:
String payload = new ObjectMapper().writeValueAsString(requestResult)
but if I return a Response like this:
return Response.status(Response.Status.CREATED).entity(new GenericEntity<RequestResult>(requestResult){}).build()
it return the wrong JSON.
I can't understand why 😥
Someone can help me? Thanks.
I want to parse the json string and form a pojo object but the response is somewhat unusual.
I have folloing type of response from API
"data": {
"12": {
"value": "$0.00",
"order_id": "12",
"order_date": "2020-08-26 15:50:05",
"category_name": "Games",
"brand_id": "4",
"denomination_name": "AED 50",
"order_quantity": "1",
"vendor_order_id": "A-123",
"vendor_location": "",
"vouchers": {
"804873": {
"pin_code": "41110AE",
"serial_number": "fddfgfgf1234444"
}
}
},
"15": {
"value": "$0.00",
"order_id": "15",
"order_date": "2020-08-26 08:39:11",
"category_name": "Games",
"brand_id": "52",
"brand_name": "PlayStation",
"denomination_name": "$20",
"order_quantity": "1",
"vendor_order_id": "A-316",
"vendor_location": "",
"vouchers": {
"806328": {
"pin_code": "fdfd",
"serial_number": "fawwwww"
}
}
}
}
}
How do I parse this response since inside data the field name is order id same with voucher
If you use Jackson JSON library, you should have POJOs like those shown below and use PropertyNamingStrategy.SnakeCaseStrategy to handle property names in the input JSON:
// top-level container
public class Response {
private Map<Integer, Order> data;
// getter/setter
}
#JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Order {
private String value; // may be some Currency class
private Integer orderId;
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime orderDate;
private String categoryName;
private Integer brandId;
private String brandName;
private String denominationName; // may be Currency too
private Integer orderQuantity;
private String vendorOrderId;
private String vendorLocation;
private Map<Integer, Voucher> vouchers;
// getters/setters
}
#JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Voucher {
private String pinCode;
private String serialNumber;
// getters/setters
}
I'm trying to use gson to deserialize some data that I'm getting back from a SonarQube API on various code metrics. This is an example of the raw JSON coming back from the server:
{
"component": {
"id": "c5fc9d6k-e28b-4ea0-8922-df18c7e07ac1",
"key": "APP:master",
"name": "master",
"qualifier": "TRK",
"measures": [
{
"metric": "coverage",
"value": "19.9",
"periods": [
{
"index": 1,
"value": "0.09999999999999787"
},
{
"index": 2,
"value": "0.09999999999999787"
},
{
"index": 3,
"value": "0.6999999999999993"
},
{
"index": 4,
"value": "8.7"
}
]
},
{
"metric": "overall_coverage",
"value": "55.7",
"periods": [
{
"index": 1,
"value": "0.0"
},
{
"index": 2,
"value": "0.0"
},
{
"index": 3,
"value": "3.0"
},
{
"index": 4,
"value": "55.7"
}
]
},
{
"metric": "ncloc",
"value": "1089127",
"periods": [
{
"index": 1,
"value": "3835"
},
{
"index": 2,
"value": "3835"
},
{
"index": 3,
"value": "-74350"
},
{
"index": 4,
"value": "102501"
}
]
}
]
}
}
I'm attempting to deserialize it into a Component class with this code:
public Component getComponentMeasures(String componentKey, List<String> measures) throws ClientProtocolException,
IOException, JsonSyntaxException, UnsupportedOperationException, JSONException
{
HttpGet request = new HttpGet(baseURL + String.format("/api/measures/component?componentKey=%s&metricKeys=%s",
componentKey, StringUtils.join(measures, ",")));
HttpResponse response = client.execute(request);
Gson gson = new Gson();
String componenta = getJSONResponse(response);
System.out.print(componenta);
Component component = gson.fromJson(componenta, Component.class);
return component;
}
This is the Component class that I'm deserializing it into:
public class Component {
#SerializedName("id")
#Expose
private String id;
#SerializedName("key")
#Expose
private String key;
#SerializedName("name")
#Expose
private String name;
#SerializedName("qualifier")
#Expose
private String qualifier;
#SerializedName("path")
#Expose
private String path;
#SerializedName("measures")
#Expose
private Measure[] measures = null;
public String getId() {
return id;
}
public String getKey() {
return key;
}
public String getName() {
return name;
}
public String getQualifier() {
return qualifier;
}
public String getPath() {
return path;
}
public Measure[] getMeasures() {
return measures;
}
}
This Component class also contains an array of Measures which in turn contain an array of periods.
Measure Class:
public class Measure {
#SerializedName("metric")
#Expose
private String metric;
#SerializedName("value")
#Expose
private String value;
#SerializedName("periods")
#Expose
private Period[] periods = null;
public String getMetric() {
return metric;
}
public String getValue() {
return value;
}
public Period[] getPeriods() {
return periods;
}
}
Period class:
public class Period {
#SerializedName("index")
#Expose
private Integer index;
#SerializedName("value")
#Expose
private String value;
public Integer getIndex() {
return index;
}
public String getValue() {
return value;
}
}
When I run this code, the deserialized component is null. Any ideas on anything that I may be doing wrong here? Note that there is an extra parameter in the Component class, "path", that is null in the JSON. This is optional and exists in other classes which contain a collection of Component objects. In those cases, this Component object and JSON deserialize fine. I've compared the JSON side-by-side and they are identical. I only seem to have the issue when trying to deserialize a standalone component object. Any help would be greatly appreciated!
Note that your JSON document is a JSON object with a single property (the path: $.component) with a nested component, however you're trying to deserialize it as if it were the top-most object:
Component component = gson.fromJson(componenta, Component.class);
Just create another class to match the top-most single property object, say something like:
final class Response {
#SerializedName("component")
#Expose
final Component component = null;
}
And then sample code like
final Response response = gson.fromJson(componenta, Response.class);
for ( final Measure measure : response.component.measures ) {
System.out.println(measure.metric + " " + measure.value);
}
will print the following output:
coverage 19.9
overall_coverage 55.7
ncloc 1089127
Sonar has an SDK for their API that encapsulates all of this and you don't have to create your own classes, etc. I used it to get info out like you're doing. See https://docs.sonarqube.org/display/SONARQUBE45/Using+the+Web+Service+Java+client and my use of it: http://myvogonpoetry.com/wp/2013/02/21/using-the-sonar-rest-api-for-weekly-emails/
I am using Gson to get convert the object to json string, and its working fine but when I am sending that json to a webservice method using post, I have to add the post method's parameter name in the string.
Example:
jsonString I get from Gson new Gson().toJson(requestDataDTO) :
{
"req": {
"AppId": "2",
"ThirdParty": "3",
"UserId": "1",
"UserToken": "4"
},
"req1": {
"AppId": "-33",
"ThirdParty": "3",
"UserId": "1",
"UserToken": "4"
}
}
jsonString I want :
{
"requestDataDTO": {
"req": {
"AppId": "2",
"ThirdParty": "3",
"UserId": "1",
"UserToken": "4"
},
"req1": {
"AppId": "-33",
"ThirdParty": "3",
"UserId": "1",
"UserToken": "4"
}
}
}
for now I am adding this "requestDataDTO" string at the start of json string I got from Gson.
is there a way to achieve this ?
Assuming you have an object which looks somehow like this:
package com.dominikangerer.q25077756;
import com.google.gson.annotations.SerializedName;
public class RequestDataDTO {
// {"AppId":"2","ThirdParty":"3","UserId":"1","UserToken":"4"}
#SerializedName("AppId")
private String appId;
#SerializedName("ThirdParty")
private String thirdParty;
#SerializedName("UserId")
private String userId;
#SerializedName("UserToken")
private String userToken;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getThirdParty() {
return thirdParty;
}
public void setThirdParty(String thirdParty) {
this.thirdParty = thirdParty;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserToken() {
return userToken;
}
public void setUserToken(String userToken) {
this.userToken = userToken;
}
}
The easiest and also for me most readable solution would be to create an wrapper/container Class which contains a HashMap (key/value) like this:
package com.dominikangerer.q25077756;
import java.util.HashMap;
public class RequestDataDTOContainer {
private HashMap<String, RequestDataDTO> requestDataDTO = new HashMap<String, RequestDataDTO>();
public HashMap<String, RequestDataDTO> getRequestDataDTO() {
return requestDataDTO;
}
public void setRequestDataDTO(HashMap<String, RequestDataDTO> requestDataDTO) {
this.requestDataDTO = requestDataDTO;
}
public void putRequestDataDTO(String key, RequestDataDTO value){
this.requestDataDTO.put(key, value);
}
}
To run it simply test it with a main like this:
// enable pretty printing
Gson gson = new GsonBuilder().setPrettyPrinting().create();
// too lazy to fill the objects by hand
String reqJson = "{\"AppId\":\"2\",\"ThirdParty\":\"3\",\"UserId\":\"1\",\"UserToken\":\"4\"}";
String req1Json = "{\"AppId\":\"-33\",\"ThirdParty\":\"3\",\"UserId\":\"1\",\"UserToken\":\"4\"}";
// deserialize it with gson
RequestDataDTO req = gson.fromJson(reqJson, RequestDataDTO.class);
RequestDataDTO req1 = gson.fromJson(req1Json, RequestDataDTO.class);
// initiliaze the container
RequestDataDTOContainer container = new RequestDataDTOContainer();
// adding the 2 req objects with the certain key
container.putRequestDataDTO("req", req);
container.putRequestDataDTO("req1", req1);
// Print it as pretty json
System.out.println(gson.toJson(container));
You are now more flexibility if you want to add more meta information like a whole meta object or similar without adding a hardcoded String to that json.
You can find the whole Example in this github repository: Java Stackoverflow Answers by DominikAngerer