3

I am trying to create a web service which will taken in JSON response and then query the DB with it to return store details (JSON response).

I intend to use this with a mobile app later on. But during the development I am testing using AJAX calls. I am using a @GET request at the moment. I was able to successfully return a JSON response. I am now facing a problem with passing the JSON Object to the @GET method. On debugging, I see that there is a null value in my input parameter. Can somebody take a look at my code and advise what I am doing wrong?

import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PUT;

import java.util.Iterator;

import org.json.simple.JSONObject;
import org.json.simple.JSONArray;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

/**
 * REST Web Service
 *
 * @author Aj
 *
 * This service will return the offers valid for the IMSI number passed
*/
@Path("getOffers")
public class GetOffersResource {

    @Context
    private UriInfo context;

    /**
    * Creates a new instance of GetOffersResource
     */
    public GetOffersResource() {
    }

    @GET
    @Consumes("application/json")
    @Produces("application/json")
    public String getJson(final String input) {

        JSONParser parser = new JSONParser();
        String[] response = new String[5];

        try {
            Object obj = parser.parse(input);
            JSONObject jsonObject = (JSONObject) obj;
            offerProcess ofc = new offerProcess();
            ofc.setLatitude((double) jsonObject.get("latitude"));
            ofc.setLongitude((double) jsonObject.get("longitude"));
            ofc.setIMSI((long) jsonObject.get("IMSI"));

            response = ofc.fetchOffers();

        } catch (ParseException e) {
            JSONObject ser = new JSONObject();

            ser.put("status", "error");
            ser.put("reason", "Bad request");

            return ser.toJSONString();
        }

        //TODO return proper representation object
        JSONObject ser = new JSONObject();
        JSONArray arr = new JSONArray();

        arr.add("456TYU");
        arr.add("OLED TV");
        arr.add("24-JUL-2014");
        arr.add("XYZ Enterprises");
        arr.add("Gachibowli");
        arr.add("9911278366");

        ser.put("status", "success");
        ser.put("Offers", arr);

        System.out.println(ser);

        return ser.toJSONString();
    }

    /**
     * PUT method for updating or creating an instance of GetOffersResource
     *
     * @param content representation for the resource
     * @return an HTTP response with content of the updated or created resource.
     */
    @PUT
    @Consumes("application/json")
    public void putJson(String content) {
    }
}

Here is the offerProcess class -

public class offerProcess {

    private double longitude;
    private double latitude;
    private long IMSI;

    public double getLongitude() {
        return longitude;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public long getIMSI() {
        return IMSI;
    }

    public void setIMSI(long IMSI) {
        this.IMSI = IMSI;
    }

    public String[] fetchOffers(){
        String[] response = new String[5];

        response[0] = "456TYU";
        response[1] = "OLED TV";
        response[2] = "24-JUL-2014";
        response[3] = "XYZ Enterprises";
        response[4] = "Gachibowli";
        response[5] = "9980556990";

        return response;
    }
}

For what it's worth, I am using the JSON.Simple library.

Thilina Sampath
  • 3,615
  • 6
  • 39
  • 65
Ajay Kelkar
  • 144
  • 1
  • 5
  • 20
  • May be problem on client-side. Please, add code with ajax call – Ilya Sep 01 '14 at 06:28
  • I'm unable to submit an edit to my original post so here goes - `code var requestData = {"longitude" : "77.681307", "latitude" : "12.8250278", "IMSI" : "404490585029957"}; $.ajax({ type: "POST", contentType: "application/json", url: url1, async: true, data: requestData, success: function(response) { console.log(response.status); } ` – Ajay Kelkar Sep 01 '14 at 07:57

4 Answers4

4

Assuming your input paramter is a query parameter for the GET request, then you need to add @QueryParam annotation to the parameter:

    @GET
    @Consumes("application/json")
    @Produces("application/json")
    public String getJson(@QueryParam("input") final String input) {
          ...
    }

Edit:

However, like @troylshields mentioned, if you are attempting to send a JSON object, you must use POST or PUT (depending on the circumstances). GET request only support query parameter, and trying to send a JSON string via a query parameter is not a good idea.

Ricardo Veguilla
  • 3,107
  • 1
  • 18
  • 17
  • Alright, thanks - I've noted! I am trying out by modifying to a POST request. I am tweaking the code and will post in a bit. Also, is there any link that you are aware of where I can read up on these request types? – Ajay Kelkar Sep 01 '14 at 07:12
  • Using POST now. I now understand that the string fails to parse in the web service. This is what I pass in the POST request - `code requestData = {"longitude":"77.681307","latitude":"12.8250278","IMSI":"404490585029957"}`. But for some reason the parameter input contains this - "longitude=77.681307&latitude=12.8250278&IMSI=404490585029957" and hence parsing fails as clearly this isn't JSON. Should I be changing the parameter signature from String? – Ajay Kelkar Sep 01 '14 at 08:47
  • Could you update the question with the code you are using now? I'll like to see the signature on the method you are calling. – Ricardo Veguilla Sep 01 '14 at 08:51
  • Like @Ilya mentioned, make sure you changed the `@GET` annotation to `@POST` on the web service method. Also, since you now using `POST`, you won't need the `@QueryParam` annotation on `input`. – Ricardo Veguilla Sep 01 '14 at 09:23
  • Sorry, but I get an error while trying to edit my question. I have changed the AJAX call type to POST and changed the annotation in the WS code to @POST. I also added - "import javax.ws.rs.POST;". There is an exception at this line - "Object obj = parser.parse(input);". This is because the input is not JSON and can't be parsed. The input arg as seen in the console - "longitude=77.681307&latitude=12.8250278&IMSI=404490585029957". I then tried as suggested at the post [link] (http://stackoverflow.com/questions/14600510/how-to-send-and-receive-json-data-from-a-restful-webservice-using-jersey-api) – Ajay Kelkar Sep 01 '14 at 10:30
1

Try changing to a POST. You don't pass a JSON body to the server with a GET request.

shieldstroy
  • 1,307
  • 1
  • 10
  • 24
1

I was able to resolve my problem by doing the same as in the following question - Json parameters are passed as null. Also as suggested, I changed from @GET request to @POST.

I created a new class called jsonFormat which will take in the 3 parameters passed in the @POST request.

Here is my final code which works -

    import javax.ws.rs.core.Context;
    import javax.ws.rs.core.UriInfo;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.Produces;
    import javax.ws.rs.Consumes;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.PUT;
    import javax.ws.rs.POST;

    import java.util.Iterator;

    import org.json.simple.JSONObject;
    import org.json.simple.JSONArray;
    import org.json.simple.JSONValue;
    import org.json.simple.parser.JSONParser;
    import org.json.simple.parser.ParseException;

    /**
     * REST Web Service
     *
     * @author Aj
     *
     * This service will return the offers valid for the IMSI number passed
     */
    @Path("getOffers")
    public class GetOffersResource {

        @Context
        private UriInfo context;

        /**
         * Creates a new instance of GetOffersResource
         */
        public GetOffersResource() {
        }

        @POST
        @Consumes("application/json")
        @Produces("application/json")
        public String getJson(jsonFormat jsonObj) {

            String[] response = new String[5];

            offerProcess ofc = new offerProcess();

            try {

                ofc.setLatitude(jsonObj.latitude);
                ofc.setLongitude(jsonObj.longitude);
                ofc.setIMSI(jsonObj.IMSI);

            } catch (Exception e) {
                JSONObject ser = new JSONObject();

                ser.put("status", "error");
                ser.put("reason", jsonObj.latitude);

                return ser.toJSONString();
            }

            //TODO return proper representation object
            JSONObject ser = new JSONObject();
            JSONArray arr = new JSONArray();

            arr.add("456TYU");
            arr.add("OLED TV");
            arr.add("24-JUL-2014");
            arr.add("XYZ Enterprises");
            arr.add("Gachibowli");
            arr.add("9911278366");

            ser.put("status", "success");
            ser.put("Offers", ofc.getIMSI());

            System.out.println(ser);

            return ser.toJSONString();
        }

        /**
         * PUT method for updating or creating an instance of GetOffersResource
         *
         * @param content representation for the resource
         * @return an HTTP response with content of the updated or created resource.
         */
        @PUT
        @Consumes("application/json")
        public void putJson(String content) {
        }
    }

Here is the jsonFormat class I created -

    import javax.xml.bind.annotation.XmlRootElement;

    /**
     *
     * @author Aj
     * This class forms the format of the JSON request which will be recieved from the App
     */
    @XmlRootElement
    public class jsonFormat {
        public double longitude;
        public double latitude;
        public long IMSI;

        jsonFormat(){}

        jsonFormat(double longitude,double latitude, long IMSI){
            this.longitude = longitude;
            this.latitude = latitude;
            this.IMSI = IMSI;
        }

    }

Lastly, the AJAX code -

    <script type="text/javascript">

        var url1 = "http://localhost:8080/Offers/webresources/getOffers";

        var requestData = {"longitude": "77.681307",
            "latitude": "12.8250278",
            "IMSI": "404490585029957"};

        var jsonObj = JSON.stringify(requestData);

        $.ajax({
            type: "POST",
            contentType: "application/json",
            url: url1,
            async: true,
            data: jsonObj,
            success: function(response) {

                //var obj = JSON.parse(response);
                console.log(response.status);
                console.log(response.reason);
                console.log(response.Offers);
            }
        });
    </script>

Thank You for all your help and time! I hope this can be useful to somebody.

Ajay Kelkar
  • 144
  • 1
  • 5
  • 20
0

Your client code is incorrect. You should send request as

var requestData = {"longitude" : "77.681307",  "latitude"  : "12.8250278", "IMSI": "404490585029957"};    
// ...  
$.ajax({
// ...
   data: {input : requestData}  // 'input' should be the root element  
// ...
)}; 

In this case on your server part input string will be correct.

Also, as I see you send POST request, but GET request is expected on server side

Ilya
  • 29,135
  • 19
  • 110
  • 158