I get some data form JSON. I can't change JSON, it is foreign API. JSON...
"apply" : {
"type" : "submit",
"form" : "#pageForm",
"data" : {
"ctl00$MainContentArea$fld_offerCode" : "%promo"
},
"submit" : "#OfferCodeSubmit",
"response" : {
"type" : "html",
"total" : "#orderItemsDisplay .totals:last"
}
},
or
"apply" : {
"type" : "post",
"url" : "https:\/\/www.4wheelparts.com\/shoppingcart.aspx",
"submit" : "#ctl00_ContentPlaceHolder1_btnCouponCode",
"contentType" : "application\/x-www-form-urlencoded",
"data" : {
"__VIEWSTATE" : "",
"ctl00$ContentPlaceHolder1$tbCouponCode" : "%promo",
"ctl00$ContentPlaceHolder1$btnCouponCode" : "Redeem"
}
}
I want save JSON to database, and use "serialize data". But parameter "data" constantly changing. How can I serialize parameter "type", "url", "submit", and is't serialize parametr "data"?
I want to add to my DB this form...
"type" : "post"
"url" : "https:\/\/www.4wheelparts.com\/shoppingcart.aspx"
"data" : {
"__VIEWSTATE" : "",
"ctl00$ContentPlaceHolder1$tbCouponCode" : "%promo",
"ctl00$ContentPlaceHolder1$btnCouponCode" : "Redeem"
}
So I serialize the data...
public class Apply
{
#SerializedName("type")
#Expose
private String type;
#SerializedName("submit")
#Expose
private String submit;
#SerializedName("timeout")
#Expose
private Long timeout;
....How data should look like???
Or am I going to need to move the another way?
dont add data in your model and that will be ok. i suggest you to use Gson library. and do as below :
Apply apply = (new Gson()).fromJson(jsonString);
jsonString is a string variable containing your json.
you can import Gson library by adding this to your gradle file:
compile 'com.google.code.gson:gson:2.8.0'
If you need only few specific data,Can follow this
jsonObj = new JSONObject(strRequestPacket);
requiredData = jsonObj.getString("requiredData");
If you need to map to your entity class,then follow this
Gson gson = new Gson();
if(mob_farmerStatus !=null){
User user = gson.fromJson(strRequestPacket, User.class);
System.out.println("user:::"+user);
public class Apply
{
#SerializedName("type")
#Expose
private String type;
#SerializedName("submit")
#Expose
private String submit;
#SerializedName("timeout")
#Expose
private Long timeout;
#SerializedName("timeout")
#Expose
private Data data;
// Setter Getters here
}
public class Data
{
private String vIEWSTATE;
private String ctl00$ContentPlaceHolder1$tbCouponCode;
private String ctl00$ContentPlaceHolder1$btnCouponCode;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public String getVIEWSTATE() {
return vIEWSTATE;
}
public void setVIEWSTATE(String vIEWSTATE) {
this.vIEWSTATE = vIEWSTATE;
}
public String getCtl00$ContentPlaceHolder1$tbCouponCode() {
return ctl00$ContentPlaceHolder1$tbCouponCode;
}
public void setCtl00$ContentPlaceHolder1$tbCouponCode(String ctl00$ContentPlaceHolder1$tbCouponCode) {
this.ctl00$ContentPlaceHolder1$tbCouponCode = ctl00$ContentPlaceHolder1$tbCouponCode;
}
public String getCtl00$ContentPlaceHolder1$btnCouponCode() {
return ctl00$ContentPlaceHolder1$btnCouponCode;
}
public void setCtl00$ContentPlaceHolder1$btnCouponCode(String ctl00$ContentPlaceHolder1$btnCouponCode) {
this.ctl00$ContentPlaceHolder1$btnCouponCode = ctl00$ContentPlaceHolder1$btnCouponCode;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
I solved it problem with help:
import okhttp3.ResponseBody;
public interface ConfigsBodyRequest
{
#GET("config.json")
Observable<ResponseBody> getResponse();
}
I get json without serialization, and than parse json
//item - (String) content of json file.
JSONObject jsonObject = new JSONObject(item);
String required = jsonObject.getString("apply");
And now required is equal to String : {"type":"submit","form":"#pageForm","data":{"ctl00$MainContentArea$fld_offerCode":"%promo"}},
And i just save in DB this string, this is what I needed. Thanks all.
Related
I am trying to fetch product data based on some request criteria. When I am converting the productmodel to productdata using convertors and populators i am getting all the product data in response.
I had tried to set the string value while converting & populating the productmodel data to productdata but its not helpful!!
{
"products": [
{
//Getting from Product Model
"name" : "ABC"
"desc" : "abcde"
"Quantity": 2"
//Not from Product Model
"matcode" : "001100"
},
]
}
is it possible to set one more string value(String matcode ="ABC") inside the same response?
Ideally, if you set matcode(a attribute) in ProductData correctly it gets reflected in the response
Decare matcode attribute inside ProducctData by declaring it in your *beans.xml, something like.
<bean class="de.hybris.platform.commercefacades.product.data.ProductData">
<!-- other attributes -->
<property name="matcode" type="java.util.Set<java.lang.String>"/>
</bean>
Now inside populator, set the matcode attribute value and you are done. Debug your controller and see whether you custom attribute value is there in product data. If it's there then it'll get converted to JSON correctly.
#Override
public void populate(final SOURCE productModel, final TARGET productData) throws ConversionException
{
//... other codes
productData.setMatcode("001100"); // add your logic to set this value
}
If you're using hql, you can do it like:
#Entity
#Table(name = "product")
public class Product {
#Column(name = "name")
private String name;
#Column(name = "desc")
private String desc;
#Column(name = "quantity")
private Integer quantity;
#Transient
#Column(name = "quantity")
private String matcode;
public Product(String name, String desc, Integer quantity, String matcode) {
this.name = name;
this.desc = desc;
this.quantity = quantity;
this.matcode = matcode;
}
}
If you want to read more about Transient annotation, please follow Transient Attribute
You can use a library like gson.
Assuming you have model like this:
public class Products
{
private List<Product> products;
}
public class Product
{
private String name;
private String desc;
private String Quantity;
}
Easy way:
Add another attribute to Product model
private String matcode;
Now below code could be used:
Gson gson = new Gson();
String jsonOutput = "{\"products\": [{ \"name\" : \"ABC\" ,\"desc\" : \"abcde\", \"Quantity\": \"2\"}]}";
Products products = gson.fromJson(jsonOutput, Products.class);
System.out.println(products);
for(Product p : products.getProducts()){
p.setMatcode("001100");
}
System.out.println(gson.toJson(products));
Another longer path :
a. read the JSON response
b. convert to object ( which you should be already doing )
c. use gson to convert object to JsonElement as array
d. iterate and update the JsonObject as you require
e. convert the updated JsonElement to String output.
Working code below:
Gson gson = new Gson();
String jsonOutput = "{\"products\": [{ \"name\" : \"ABC\" ,\"desc\" : \"abcde\", \"Quantity\": \"2\"}]}";
Products products = gson.fromJson(jsonOutput, Products.class);
System.out.println(products);
JsonElement jsonElement = gson.toJsonTree(products);
JsonArray jsonArray = jsonElement.getAsJsonObject().get("products").getAsJsonArray();
for (JsonElement ele : jsonArray) {
JsonObject obj = ele.getAsJsonObject();
obj.addProperty("matcode", "001100");
}
String updatedJsonOutput = gson.toJson(jsonElement);
System.out.println("Updated json Object: " + updatedJsonOutput);
I wrote an REST service to ingest metadata from post requests. I am using spring-data-elasticsearch, and I made a custom Metadata Object to deserialize Json into that looks like this:
#Document(indexName = "metadata_v1", type = "metadata")
public class Metadata {
#Id
private String id;
#Field(type = FieldType.String)
private String uuid;
#Field(type = FieldType.String)
private String userId;
#Field(type = FieldType.Date, format = DateFormat.basic_date_time)
private Date date = null;
#Field(type = FieldType.String)
private String classification;
#Field(type = FieldType.Nested)
private List<NumericKeyValue> numericKeyValue;
#Field(type = FieldType.Nested)
private List<TextKeyValue> textKeyValue;
with a bunch of getters and setters.
It works fine for all of its fields except numericKeyValue and textKeyValue Json Arrays. I couldn't send those in via post request, and realized I needed to write a deserializer. I did that for numericKeyValue, and as far as I've read, it's supposed to look like this:
public class NumericKeyValueJsonDeserializer extends JsonDeserializer<List<NumericKeyValue>>{
#Override
public List<NumericKeyValue> deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
TypeReference<List<NumericKeyValue>> typeRef = new TypeReference<List<NumericKeyValue>>(){};
ObjectMapper mapper = new ObjectMapper();
JsonNode root = jp.getCodec().readTree(jp);
String numericKeyValue = root.get("numericKeyValue").asText();
return mapper.readValue( numericKeyValue, typeRef);
}
}
And I added
#JsonDeserialize(using = NumericKeyValueJsonDeserializer.class)
to the field declaration in my Metadata class.
However, after a lot of testing, I have come to realize that the JsonNode root not only doesn't contain "numericKeyValue", but gives me a completely empty string when I invoke root.asText().
I have been using Postman to send in a post request to my endpoint
#RequestMapping(value="/metadata_v1/ingest", method=RequestMethod.POST, consumes="application/json")
public #ResponseBody Metadata createEntry(#RequestBody Metadata entry){
repository.save(entry);
return entry;
}
containing the following Json:
{
"numericKeyValue":
[
{
"key": "velocity",
"value": 55.5
},
{
"key": "angle",
"value": 90
}
]
}
My mapping looks like this:
"numericKeyValue" : {
"type" : "nested",
"properties" : {
"key" : {"type" : "string"},
"value" : {"type" : "double"}
}
}
I can show more things if needed. I think I will be fine if I can just get the JSON I send in Java somehow, perhaps as a String. I've been getting empty Strings that result in null pointer exceptions and when I tried String numericKeyValue = jp.getText() the String was just the current token of "[", which I guess at least isn't an empty String, but still doesn't help me.
Any help or advice is much appreciated.
In your case the value for numericKeyValue is an array. You should replace the following line:
String numericKeyValue = root.get("numericKeyValue").asText();
with:
if ( root.isArray() ){
// loop trough array
for (final JsonNode node : root){
String numericKeyValue = node.get("numericKeyValue").asText();
// then build the list to be returned
}
}
I am Using GSON and Volley library for networking in my android application but while converting the Json response to Model classes using Gson i am getitng the following error:
88-2006/ E/Volley﹕ [121] NetworkDispatcher.run: Unhandled exception java.lang.RuntimeException: Unable to invoke no-args constructor for class [Lcom.example.model.Product;. Register an InstanceCreator with Gson for this type may fix this problem.
java.lang.RuntimeException: Unable to invoke no-args constructor for class [Lcom.example.model.Product;. Register an InstanceCreator with Gson for this type may fix this problem.
these are my POJO classes i am using :
Product.java
public class Product {
private String status;
private List<Result> results = new ArrayList<Result>();
private Pagination pagination;
public Product(){}
// getters and setters
}
Pagination.java
public class Pagination {
private String first;
private String previous;
private String next;
private String last;
public Pagination(){}
}
Result.java
public class Result {
private String id;
private Properties properties;
public Result{}
}
Properties.java
public class Properties {
private String qbcode;
private String name;
private String purchasedate;
private String vendor;
private String thumbnail;
public Properties(){}
}
I have gone through the existing questions which are same like this , as per answers i have found i added the no arg constructor to all the classes but still i am getting the error please help me in solving this issue
The Json String:
{
"status" : "OK",
"results" : [ {
"id" : "IzIzOjE=",
"properties" : {
"qbcode" : "IN-1-1",
"name" : "Test Name",
"purchasedate" : "2015-05-21",
"vendor" : "Test Vendor",
"thumbnail" : "http://en.wikipedia.org/static/images/project-logos/enwiki.png"
}
}, {
"id" : "IzIzOjI=",
"properties" : {
"qbcode" : "IN-1-2",
"name" : "Test Name",
"purchasedate" : "2015-05-21",
"vendor" : "Test Vendor",
"thumbnail" : "http://en.wikipedia.org/static/images/project-logos/enwiki.png"
}
}, {
"id" : "IzIzOjM=",
"properties" : {
"qbcode" : "IN-1-3",
"name" : "Test Name",
"purchasedate" : "2015-05-21",
"vendor" : "Test Vendor",
"thumbnail" : "http://en.wikipedia.org/static/images/project-logos/enwiki.png"
}
},{
"id" : "IzIzOjU=",
"properties" : {
"qbcode" : "IN-1-5",
"name" : "Test Name",
"purchasedate" : "2015-05-21",
"vendor" : "Test Vendor",
"thumbnail" : "http://en.wikipedia.org/static/images/project-logos/enwiki.png"
}
} ],
"pagination" : {
"first" : "/list?size=20",
"previous" : "/list?start=IzIzOjE=&size=20",
"next" : "/list?start=IzIzOjQx&size=20",
"last" : "/list?start=IzIzOjYx&size=20"
}
}
Add default constructor for all classes. Example:
public class Product{
public Product(){
}
}
problem solved, I am doing a foolish call To Gson because i am obtaining a Product class that contains list of other Classes(Result.class etc) but i am sending Product[].class to Gson to convert Hence it thrown exception.
Your model having private attribute you must create setter for the same or create constructor with all parameter like below:
public class Product {
private String status;
private List<Result> results = new ArrayList<Result>();
private Pagination pagination;
public void setStatus(String status) {
this.status = status;
}
public void setResults(List<Result> results) {
this.results = results;
}
public void setPagination(Pagination pagination) {
this.pagination = pagination;
}
}
or
public class Product {
private String status;
private List<Result> results = new ArrayList<Result>();
private Pagination pagination;
public Product(String status, List<Result> results, Pagination pagination) {
this.status = status;
this.results = results;
this.pagination = pagination;
}
}
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
How to get this string and put into String Array or HashMap? Any reference?
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"location" : "Authorization",
"locationType" : "header",
"message" : "The domain policy has disabled third-party Drive apps",
"reason" : "domainPolicy"
} ],
"message" : "The domain policy has disabled third-party Drive apps"
}
====
This is my solution for Jackson:
public class TheErrorModel {
public int code;
public Collection<Error> errors;
public String message;
public TheErrorModel() {
}
public TheErrorModel(String json)
throws Exception {
ObjectMapper mapper = new ObjectMapper();
TheErrorModelother = mapper.readValue(json, TheErrorModel.class);
this.code = other.code;
this.errors = other.errors;
this.message = other.message;
}
}
class Error {
public String domain;
public String location;
public String locationType;
public String message;
public String reason;
}
TheErrorModel theErrorModel = new TheErrorModel(json);
So I get something like theErrorModel.message :D
You can try to use GSON http://code.google.com/p/google-gson/ , It is pretty simple to use. You should just create class structure for this json schema.
import com.google.gson.Gson;
class YourErrorsJSON{
private String domain
private String location;
private String locationType;
private String message;
private String reason
}
class YourJSON {
private int code;
private YourErrorsJSON[] errors;
private String message;
}
Gson gson = new Gson();
YourJSON obj = gson.fromJson(json, YourJSON.class);
Try this ::
JSONObject yourObj = JSONObject.fromString(input_string);
String code = yourObj.get("code"); // code will have a value 403