I recently started an Android Project (native shopping app) for practice.
My problem is saving the customers order data with Volley. I first did it with Maps and it only saved the customer's details, but not what the customer ordered, that is, products.
I then imported an external jar file for javax.json to build a JsonArray; I received the following error in Java (I am using netbeans and consuming restful web services in Android):
2017-12-14 09:01:44.914 WARN 5888 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize instance of com.picknpay.onlineshop.entity.CustomerOrderDetail out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.picknpay.onlineshop.entity.CustomerOrderDetail out of START_ARRAY token
at [Source: java.io.PushbackInputStream@2b67b6c9; line: 1, column: 1]
2017-12-14 09:01:44.914 WARN 5888 --- [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize instance of com.picknpay.onlineshop.entity.CustomerOrderDetail out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.picknpay.onlineshop.entity.CustomerOrderDetail out of START_ARRAY token
at [Source: java.io.PushbackInputStream@2b67b6c9; line: 1, column: 1]
And in Android Studio (error):
E/Volley: [385] BasicNetwork.performRequest: Unexpected response code 400 for http://URL:8080/saveOrder
My JSON should look like this when I call customer ordered data web service:
[
{
"cusEmail":"...",
"totalQuantity":2,
"totalCost":29.48,
"phoneNumber":"...",
"address":"...",
"closeShop":"...",
"contact":"By email:: and SMS:",
"status":"ordered",
"orderDate":"2017-12-14",
"deliveryDate":"2017-12-22",
"orderedItems":
[
{
"name":"Blue Ribbon",
"manufacture":"Blue Ribbon Brown Plus Low Gi Bread 700g",
"price":13.99,
"image":"data:image/jpeg;base64,/9j/...
"quantity":1
}
]
}
]
In Java I have the following entities:
@Entity
public class CustomerOrderDetail implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String cusEmail;
private int totalQuantity;
private Double totalCost;
private String phoneNumber;
private String address;
private String closeShop;
private String contact;
private String status;
private String orderDate;
@Temporal(TemporalType.DATE)
private Date deliveryDate;
@ManyToMany(cascade = CascadeType.ALL )//, orphanRemoval = true, fetch = FetchType.LAZY)
private Collection<OrderedItem> orderedItems = new ArrayList<OrderedItem>();
// plus constructors, and get and setters
And
@Entity
public class OrderedItem implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
private String name;
@NotNull
private String manufacture;
@NotNull
private Double price;
@NotNull
private String image;
@NotNull
private Integer quantity;
My Volley call code:
JsonArray jsonParams = Json.createArrayBuilder()
.add(Json.createObjectBuilder()
.add("cusEmail", email)
.add("totalQuantity", quantity)
.add("totalCost", totalCost)
.add("phoneNumber", phoneNumber)
.add("address", address)
.add("closeShop", closeShop)
.add("contact", contact)
.add("status", "ordered")
.add("orderDate", dateFormat.format(orderDate))
.add("deliveryDate", delDate)
.add("orderedItems", Json.createArrayBuilder()
.add(Json.createObjectBuilder()
.add("name", nameString)
.add("manufacture", manufactureString)
.add("price", priceDouble)
.add("image", imageString)
.add("quantity", qauntityInteger)))
).build();
Log.d("--------> ", jsonParams.toString());
JsonArrayRequest postRequest = new JsonArrayRequest(Request.Method.POST, URL, jsonParams.toString(),
new Response.Listener<ExtendedJsonArray>() {
@Override
public void onResponse(ExtendedJsonArray response) {
String status = null;
String message = null;
try {
status = (String) response.get("status");
message = (String) response.get("message");
if (status.equals("success")) {
// will be implemented when data is saved
}
}
catch (JSONException e ) {
Log.d("JsonException Error: : ", e.getMessage() );
}
}},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error" + error + "\nmessage" + error.getMessage());
}
});
queue.add(postRequest);
}
The volley call uses the following class:
public class JsonArrayRequest extends JsonRequest<ExtendedJsonArray> {
public JsonArrayRequest(int method, String url, String requestBody, Response.Listener<ExtendedJsonArray> listener, Response.ErrorListener errorListener) {
super(method, url, requestBody, listener, errorListener);
}
@Override
protected Response<ExtendedJsonArray> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
return Response.success( new ExtendedJsonArray(jsonString), HttpHeaderParser.parseCacheHeaders(response) );
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
}