Lucas Arrefelt
Lucas Arrefelt

Reputation: 3929

Java jersey RESTful webservice requests

I've been following a tutorial about a restful service and it works fine. However there are something I dont quite understand yet. This is how it looks:

@Path("/hello")
public class Hello {

    // This method is called if TEXT_PLAIN is request
    @GET
    @Produces( MediaType.TEXT_PLAIN )
    public String sayPlainTextHello() 
    {
        return "Plain hello!";
    }

    @GET
    @Produces( MediaType.APPLICATION_JSON )
    public String sayJsonTextHello() 
    {
        return "Json hello!";
    }

    // This method is called if XML is request
    @GET
    @Produces(MediaType.TEXT_XML)
    public String sayXMLHello() {
        return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>";
    }

    // This method is called if HTML is request
    @GET
    @Produces(MediaType.TEXT_HTML)
    public String sayHtmlHello() 
    {
        return "<html> " + "<title>" + "Hello fittemil" + "</title>"
                + "<body><h1>" + "Hello!" + "</body></h1>" + "</html> ";
    }
} 

Whats bothering me is that I can't make use of the right operations. When I request the service from a browser the appropriate sayHtmlHello() method gets called. But now I am developing an android application which I want to get the result in Json. But when I call the service from the application, the MediaType.TEXT_PLAIN method gets called. My android code looks similar to this:

Make an HTTP request with android

How can call the method which uses MediaType.APPLICATION_JSON from my android application? Further I would like to make that particular method return an object, would be great if I got some guidance there as well.

Upvotes: 3

Views: 5768

Answers (2)

Giorgio
Giorgio

Reputation: 13529

In the code above you commented

// This method is called if TEXT_PLAIN is request
@GET
@Produces( MediaType.TEXT_PLAIN )...

Please note that the annotation @Produces specify the OUTPUT mimetype. To specify the INPUT mimetype use the @Consumes annotation instead.

Check blog post for more about Jersey annotations:

@Consumes – This annotation specifies the media types that the methods of a resource class can accept. It’s an optional one and by default, the container assumes that any media type is acceptable. This annotation can be used to filter the requests sent by the client. On receiving request with wrong media type, sever throws an error to the client.

@Produces – This annotation defines the media types that the methods of a resource class can produce. Like @Consumes annotation, this is also optional and by default the container assumes that any media type can be sent back to the client.

Upvotes: 1

Ali
Ali

Reputation: 9994

I have personally experience in implementing REST in java (JAX-RS) using Jersey. Then I connected to this RESTful Web Service via an Android application.

In your Android application you can use HTTP Client library. It supports the HTTP commands such as POST, PUT, DELETE, GET. For example to use GET command and trasferring data in JSON format or TextPlain:

public class Client {

    private String server;

    public Client(String server) {
        this.server = server;
    }

    private String getBase() {
        return server;
    }

    public String getBaseURI(String str) {
        String result = "";
        try {
            HttpParams httpParameters = new BasicHttpParams();
            int timeoutConnection = 3000;
            HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
            int timeoutSocket = 5000;
            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
            DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
            HttpGet getRequest = new HttpGet(getBase() + str);
            getRequest.addHeader("accept", "application/json");
            HttpResponse response = httpClient.execute(getRequest);
            result = getResult(response).toString();
            httpClient.getConnectionManager().shutdown();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } 
        return result;
    }

    public String getBaseURIText(String str) {
        String result = "";
        try {
            HttpParams httpParameters = new BasicHttpParams();
            int timeoutConnection = 3000;
            HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
            int timeoutSocket = 5000;
            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
            DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
            HttpGet getRequest = new HttpGet(getBase() + str);
            getRequest.addHeader("accept", "text/plain");
            HttpResponse response = httpClient.execute(getRequest);
            result = getResult(response).toString();
            httpClient.getConnectionManager().shutdown();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return result;
    }

 private StringBuilder getResult(HttpResponse response) throws IllegalStateException, IOException {
            StringBuilder result = new StringBuilder();
            BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())), 1024);
            String output;
            while ((output = br.readLine()) != null) 
                result.append(output);

            return result;      
      }
}

And then in an android class you can:

Client client = new Client("http://localhost:6577/Example/rest/");
String str = client.getBaseURI("Example");    // Json format

Parse the JSON string (or maybe xml) and use it in ListView, GridView and ...

I took a short look on the link which you had provided. There was a good point there. You need to implement your network connection on a separate thread for API level 11 or greater. Take a look on this link: HTTP Client API level 11 or greater in Android.

This is the way that I post an object with HTTP in Client class :

public String postBaseURI(String str, String strUrl) {
        String result = "";
        try {
            HttpParams httpParameters = new BasicHttpParams();
            int timeoutConnection = 3000;
            HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
            int timeoutSocket = 5000;
            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
            DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
            HttpPost postRequest = new HttpPost(getBase() + strUrl);
            StringEntity input = new StringEntity(str);
            input.setContentType("application/json");
            postRequest.setEntity(input);
            HttpResponse response = httpClient.execute(postRequest);
            result = getResult(response).toString();
            httpClient.getConnectionManager().shutdown();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return result;
    }

And in the REST WS, I post the object to the database:

    @POST
    @Path("/post")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_PLAIN)
    public Response addTask(Task task) {        
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        session.save(task);
        session.getTransaction().commit();
        return Response.status(Response.Status.CREATED).build();
    }

Upvotes: 4

Related Questions