2

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));
        }
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
DESH
  • 530
  • 2
  • 11
  • 29
  • 1
    according to your error: Unexpected response code 400, it means that the error comes from the API itself, not how you handle it because you can't handle your expected json response if the api does not respond it in the first place. Are you sure that the volley request gets the json? – Tenten Ponce Dec 14 '17 at 08:28
  • Well its suppose to post --> send the json data and yes I am sure. – DESH Dec 14 '17 at 08:43
  • https://developer.mozilla.org/it/docs/Web/HTTP/Status/400 error 400 means bad request, can you provide the expected HTTP request from server? – Thecave3 Jul 05 '19 at 21:05

0 Answers0