while using Postman to test the #POST method of RESTEasy, I got the error MalformedJsonException
My #POST method
#POST
#Path("service/product")
#Consumes("application/json")
public Object setProductData(Product product) {
String result = product.toString().trim();
Gson gson = new Gson();
Data.addProduct(gson.fromJson(result, Product.class));
return Response.status(200).entity(result).build();
}
My model
public class Product {
private String id;
private String name;
private String image;
private double price;
private String catalogId;
public Product(String id, String name, String image, double price, String catalogId) {
this.id = id;
this.name = name;
this.image = image;
this.price = price;
this.catalogId = catalogId;
}
public Product() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
#Override
public String toString() {
return "{" +
"id='" + id + ',' +
"name='" + name + ',' +
"image='" + image + ',' +
"price='" + price + ',' +
"catalogId='" + catalogId + ',' + "}";
}
}
This is what I want to add:
https://i.imgur.com/XACBopY.png
The data is in json format, {"id":"band1","name":"Mi Band 4","image":"https://i.imgur.com/7MLMnhW.jpg","price":30.0,"catalogId":"abc1"} for examle
The error:
https://i.imgur.com/8suya35.png
Earlier I got the error Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ but then I realized toString() method in Product class was the problem, I fixed it and it produced the error in the question.
Please help me to fix this error.
Your toString() is faulty to begin with - the Json formulation isn't correct.
If you want to use toString() anyways to convert your POJO into JSON, use apache commons lang3's JSON style in the toString().
import com.google.gson.Gson;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
public class Test1 {
public static void main(String[] args) {
Product product = new Product("1", "someone", "https://url", 1.23, "11");
System.out.println(product);
Gson gson = new Gson();
Product product1 = gson.fromJson(product.toString().trim(), Product.class);
System.out.println(product1);
}
private static class Product {
private String id;
private String name;
private String image;
private double price;
private String catalogId;
public Product() {
}
public Product(String id, String name, String image, double price, String catalogId) {
this.id = id;
this.name = name;
this.image = image;
this.price = price;
this.catalogId = catalogId;
}
#Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
.append("id", id)
.append("name", name)
.append("image", image)
.append("price", price)
.append("catalogId", catalogId)
.toString();
}
public String getId() {
return id;
}
public Product setId(String id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public Product setName(String name) {
this.name = name;
return this;
}
public String getImage() {
return image;
}
public Product setImage(String image) {
this.image = image;
return this;
}
public double getPrice() {
return price;
}
public Product setPrice(double price) {
this.price = price;
return this;
}
public String getCatalogId() {
return catalogId;
}
public Product setCatalogId(String catalogId) {
this.catalogId = catalogId;
return this;
}
}
}
The output is as follows:-
{"id":"1","name":"someone","image":"https://url","price":1.23,"catalogId":"11"}
{"id":"1","name":"someone","image":"https://url","price":1.23,"catalogId":"11"}
Now, coming to the usage. If you are taking the object as an input itself as a POST request body, then why not simply use 'Data.addProduct(product);'?
Related
I would like to iterate Products and get the list of name,code and price and set in my Model class. Any help would be really appreciated - how can I iterate this. When I use obj.get("Products") - it just printing as string - got stuck to iterate.
{
"id": "skd3303ll333",
"Products": [{
"name": "apple",
"code": "iphone-393",
"price": "1939"
},
{
"name": "ipad",
"code": "ipad-3939",
"price": "900"
}
]
}
#PostMapping(path="/create", consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> create(#RequestBody Map<String, Object> obj ) {
System.out.println("Products :" + obj.get("Products"));
}
There are two ways to do this,
1) By type casting (personally i will not prefer this)
List<Map<Object,Object>> productslist = (List<Map<Object, Object>>) obj.get("products");
for(Map entry: productslist) {
for(Object s: entry.keySet()) {
System.out.println(s.toString());
System.out.println(entry.get(s).toString());
}
}
2) Mapping directly to Model class, for this approach you need Jackson library in buildpath
#JsonIgnoreProperties(unknown =true)
public class Customer {
#JsonProperty("id")
private String id;
#JsonProperty("products")
private List<Products> products;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Products> getProducts() {
return products;
}
public void setProducts(List<Products> products) {
this.products = products;
}
}
#JsonIgnoreProperties(unknown =true)
class Products{
#JsonProperty("name")
private String name;
#JsonProperty("code")
private String code;
#JsonProperty("price")
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
Controller
public ResponseEntity<Object> create(#RequestBody Customer obj ) {
You need POJO structure with two classes:
public class Product {
private String name;
private String code;
private int price;
}
public class ProductsGroup {
private long id;
private List<Product> products;
// getters/setters
}
And change your method signature to:
#PostMapping(path="/create", consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ProductsGroup> create(#RequestBody ProductsGroup productGroup)
{
System.out.println("Products :" + productGroup.getProducts());
}
You are trying to process the json using a Map<String, Object> obj, which could be possible in some way, but mostly what you want to do is define a single or multiple POJO classes. These represent the json.
public class IdWrapper {
private String id;
#JsonProperty("Products")
private List<Product> products;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Product> getProducts() {
return products;
}
}
public class Product {
private String name;
private String code;
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
And in you controller like this:
#RestController
#RequestMapping("test")
public class DemoController {
#PostMapping()
public void test(#RequestBody IdWrapper productsWrapper) {
System.out.println();
}
}
I have initialized the arraylist globally(mDataset). I'm trying to populate the arraylist based on some conditions.
code snippet in which error is occurring.
Error is occurring when i try to initialize object product with the value received from the fire.getValue() in for loop
mProductReference.child("Electronics").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot fire : dataSnapshot.getChildren())
{
Product product = fire.getValue(Product.class);
if(product.getId().equals(key)) {
mDataSet.add(product);
}
//Toast.makeText(MyProduct.this,mDataSet.size()+ "", Toast.LENGTH_SHORT).show();
}
mAdapter.refresh(mDataSet);
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
POJO(Product.java)
public class Product {
String name,desc,image,id,userid,category;
long price,quantity,noOfRating;
long rating;
ArrayList<Review> review;
public Product() {
}
public Product(String name, String desc, String image, String id, String userid, String category, long price, long quantity, long noOfRating, long rating, ArrayList<Review> review) {
this.name = name;
this.desc = desc;
this.image = image;
this.id = id;
this.userid = userid;
this.category = category;
this.price = price;
this.quantity = quantity;
this.noOfRating = noOfRating;
this.rating = rating;
this.review = review;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public long getPrice() {
return price;
}
public void setPrice(long price) {
this.price = price;
}
public long getQuantity() {
return quantity;
}
public void setQuantity(long quantity) {
this.quantity = quantity;
}
public long getNoOfRating() {
return noOfRating;
}
public void setNoOfRating(long noOfRating) {
this.noOfRating = noOfRating;
}
public long getRating() {
return rating;
}
public void setRating(long rating) {
this.rating = rating;
}
public ArrayList<Review> getReview() {
return review;
}
public void setReview(ArrayList<Review> review) {
this.review = review;
}}
It is working in some other activity but causing problem in this one.
The result variable contains corrected parsed JSON.
But after deserialization List contains correct amount of items but all of them are empty.
How to fix it?
Gson gson = new Gson();
List<UnitView> unitViews = new ArrayList<UnitView>();
// https://stackoverflow.com/questions/5554217/google-gson-deserialize-listclass-object-generic-type
Type typeToken = new TypeToken<List<UnitView>>() { }.getType();
unitViews = gson.fromJson(result,typeToken);
Even if I do like
UnitView[] unitViews = gson.fromJson(result, UnitView[].class);
The fields of items are empty as well.
UnitView
public class UnitView implements Serializable {
public String id ;
public String name ;
public String description ;
public String deviceTypeName ;
public String categoryID ;
public String lastOnline ;
public String latitude ;
public String longitude ;
public String atTime ;
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getDeviceTypeName() {
return deviceTypeName;
}
public String getCategoryID() {
return categoryID;
}
public String getLastOnline() {
return lastOnline;
}
public String getLatitude() {
return latitude;
}
public String getLongitude() {
return longitude;
}
public String getAtTime() {
return atTime;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setDeviceTypeName(String deviceTypeName) {
this.deviceTypeName = deviceTypeName;
}
public void setCategoryID(String categoryID) {
this.categoryID = categoryID;
}
public void setLastOnline(String lastOnline) {
this.lastOnline = lastOnline;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public void setAtTime(String atTime) {
this.atTime = atTime;
}
}
JSON DATA
[{"ID":"294","Name":"Foton Tunland № F110","Description":null,"DeviceTypeName":"Техника ТО","CategoryID":"18","LastOnline":"19.12.2017 20:38:04","Latitude":"11,40119","Longitude":"11,42403","AtTime":"19.12.2017 20:38:04"},{"ID":"295","Name":"DML LP1200 № 9793","Description":null,"DeviceTypeName":"Буровой станок дизельный","CategoryID":"15","LastOnline":null,"Latitude":null,"Longitude":null,"AtTime":null}]
Ok , the problem is that the parser is case-sensitive, you can change the name of your attributes to match the name of the json value of you could use the SerializedName annotation like this:
#SerializedName("ID")
public String id ;
#SerializedName("Name")
public String name ;
#SerializedName("Description")
public String description;
...
or
public String ID ;
public String Name ;
public String Description ;
...
I think you're having this problem because of null values in your json.
Check it. Source
I am trying to get some the array of actors from Jira. The code for the wrapper is used in a Gson.fromJson call. I had used something similar with a json string that did not have an array in it that had the information I needed and it worked fine, so the issue seems to do with the array, but I am not 100% sure:
import com.google.gson.annotations.SerializedName;
public class JiraRoleJsonWrapper {
#SerializedName("self")
private String self;
#SerializedName("name")
private String name;
#SerializedName("id")
private int id;
#SerializedName("description")
private String description;
#SerializedName("actors")
private JiraActors[] actors;
public JiraActors[] getActors() {
return actors;
}
public void setActors(JiraActors[] actors) {
this.actors = actors;
}
public String getSelf() {
return self;
}
public void setSelf(String self) {
this.self = self;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String key) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*
public String[] getAvatarUrls() {
return avatarUrls;
}
public void setAvatarUrls(String[] avatarUrls) {
this.avatarUrls = avatarUrls;
}
*/
}
class JiraActors {
#SerializedName("id")
private int id;
#SerializedName("displayNme")
private String displayName;
#SerializedName("type")
private String type;
#SerializedName("name")
private String name;
//#SerializedName("avatarUrl")
//private String avatarUrl;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The json it would receive:
{
"self":"http://someserver.com:8080/apps/jira/rest/api/2/project/10741/role/10002",
"name":"Administrators",
"id":10002,
"description":"A project role",
"actors":[
{
"id":12432,
"displayName":"Joe Smith",
"type":"atlassian-user-role-actor",
"name":"joesmi",
"avatarUrl":"/apps/jira/secure/useravatar?size=xsmall&ownerId=dawsmi&avatarId=12245"
},
{
"id":12612,
"displayName":"Smurfette Desdemona",
"type":"atlassian-user-role-actor",
"name":"smudes",
"avatarUrl":"/apps/jira/secure/useravatar?size=xsmall&ownerId=lamade&avatarId=10100"
},
This shows two actors and the format of the json. Please note I did not put a complete json response. It just shows two actors.
In my code, I tried the following to retrieve the actors:
InputStream is = response.getEntityInputStream();
Reader reader = new InputStreamReader(is);
Gson gson = new Gson();
JiraRoleJsonWrapper[] jiraRoleJsonWrapper = gson.fromJson(reader, JiraRoleJsonWrapper[].class);
for (JiraRoleJsonWrapper w : jiraRoleJsonWrapper) {
JiraActors[] a = w.getActors();
String name = a.getName();
It does not find getName for some reason. I am not sure why.
I figured it out.
I change the setActors to
public void setActors(ArrayList<JiraActors> actors) {
this.actors = actors;
}
Then I was able to get the array list and get access to the getName() method of JiraActors.
data_user = "{"id":1,"lastName":"lastName","name":"name","school":{"id":1}}"
public class School {
private int id;
private String name;
}
public class User {
private int id;
private String lastName;
private String name;
private School school;
}
How to deserialize Json data_user to java object User?
I tried with Gson :
Gson gson = new Gson();
User user = gson.fromJson(data_user, User.class)
But I have an error with this code because the Json contains a school which hasn't the school's name.
How Can I serialize the Json to java Object?
School.java
public class School {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "School [id=" + id + ", name=" + name + "]";
}
}
User.java
public class User {
private int id;
private String lastName;
private String name;
private School school;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
#Override
public String toString() {
return "User [id=" + id + ", lastName=" + lastName + ", name=" + name
+ ", school=" + school + "]";
}
}
Main.java
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.testgson.beans.User;
public class Main {
private static Gson gson;
static {
gson = new GsonBuilder().create();
}
public static void main(String[] args) {
String j = "{\"id\":1,\"lastName\":\"lastName\",\"name\":\"ignacio\",\"school\":{\"id\":1}}";
User u = gson.fromJson(j, User.class);
System.out.println(u);
}
}
Result
User [id=1, lastName=lastName, name=ignacio, school=School [id=1, name=null]]
Try with the Jackson Library. With Gson with should have not any problem, I tried with the code of #Saurabh and it work well