6
votes

I'm trying to make a small REST service with Jersey 2.13 as the server, Vaadin 7.3.3 as the "client" but the idea is that the request can come from anywhere (not just Vaadin, this is why I don't use a bean at request time). Suppose that the user is already registered and the request just checks if he exists, and returns the token. I have a POST URL, https://localhost:8443/logins, that receives

{ 
    "login-request": 
    { 
        "username":<insert username>,
        "password":<insert password> 
    }
}

And returns:

{ 
    "login-token": 
    { 
        "token":<insert token>
    }
}

My client request code is:

Client client = ClientBuilder.newClient();

    WebTarget target = client.target("https://127.0.0.1:8443/").path(appName + "/logins");

    //build JSON Object
    HashMap<String, String> userMap = new HashMap<>();
    userMap.put("username", user.getUsername());
    userMap.put("password", user.getPassword());

    //JSON logins request!
    JSONObject jsonLoginRequest = new JSONObject();
    try {
        jsonLoginRequest.put("login-request", userMap);
    } catch (JSONException e) {
        e.printStackTrace();
    }

    return target.request(MediaType.APPLICATION_JSON_TYPE).post(Entity.json(jsonLoginRequest.toString()));

Server processing code is:

    @POST
@Path("logins")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response generateToken(@Context HttpServletRequest request) {

    if (request != null) {
        User user;

        DBHandshaker handshaker = DBHandshaker.getInstance();
        user = handshaker.logUser(request.getParameter("username"), request.getParameter("password"));

        if (user != null) {
            StringUtil stringUtil = StringUtil.getInstance();
            String tokenString = stringUtil.encryptForToken(user.getUsername(), user.getPassword());

            HashMap<String, String> tokenMap = new HashMap<>();
            tokenMap.put("token", tokenString);

            JSONObject jsonLoginResponse = new JSONObject();
            try {
                jsonLoginResponse.put("login-token", tokenMap);
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return Response.ok(jsonLoginResponse.toString(), MediaType.APPLICATION_JSON).build();

        } else {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }

    } else {
        return Response.status(Response.Status.NO_CONTENT).build();
    }

}

And my client response "catcher" is:

            LoginParser loginParser = new LoginParser();
        Response response = loginParser.parseRequest(username, password);

        boolean isValidLogin = Response.Status.OK.getStatusCode() == response.getStatusInfo().getStatusCode();

        if (isValidLogin) {

            // Store the current username in the service session
            getSession().setAttribute("user", username);

            HttpEntity entity = (HttpEntity) response.getEntity();
            try {
                String retSRc = EntityUtils.toString(entity);
                JSONObject jsonObject = new JSONObject(retSRc);

                System.out.println(jsonObject);

            } catch (IOException | JSONException e) {
                e.printStackTrace();
            }

            // Navigate to main view
            getUI().getNavigator().navigateTo(LoginMainView.NAME);//

        }

I'm having problems on response.getEntity() because it is neither JSON or an HttpEntity, but org.glassfish.jersey.client.HttpUrlConnector. Where is my mistake?

2
My first suggestion is to use JAXB/JSON annotated classes and Jackson to clean up the code - you could simply pass username and password to an constructor and have the token property set accordingly. Simply set the entity on the server side to the instance of the JAXB annotated class and you'll have much cleaner code. And in general, you might rather want to use Response.ok().entity(jsonObject).build(), since jersey already knows from the annotation that Json is to be produced. Depending on your setup, an according ResponseWriter may already be registered.Markus W Mahlberg
Has this been resolved successfully? If so, where was the problem?ulrich
@manuel-santiago-yépez see answer below, does response.readEntity(String.class) fix this for you?javabrett

2 Answers

10
votes

Instead of response.getEntity(), use response.readEntity(String.class) or response.readEntity(HttpEntity.class).

2
votes

Client Processing code

package net.test;

import java.util.HashMap;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

public class Consumer {
    public static void main(String[] args) {
        Client client = Client.create();
        ClientResponse clientResponse = null;

        User u = new User();
        u.setUsername("hello");
        u.setPassword("hello");
        WebResource webResource = client
            .resource("http://localhost:8080/"+appName"+/logins");
        HashMap<String, String> userMap = new HashMap<String, String>();
        userMap.put("username", u.getUsername());
        userMap.put("password", u.getPassword());
        // JSON logins request!
        JSONObject jsonLoginRequest = new JSONObject();
        try {
            jsonLoginRequest.put("login-request", userMap);
            System.out.println(jsonLoginRequest.get("login-request"));
            System.out.println(jsonLoginRequest.getJSONObject("login-request")
                .get("username"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
       // POST Operation
       clientResponse = webResource.post(ClientResponse.class,
            jsonLoginRequest);
       System.out.println(jsonLoginRequest);
    // Send the return value in object
       String result = clientResponse.getEntity(String.class);
       System.out.println(result);
 }
}

Server Processing Code

package net.test;
//Server Processing code
import java.util.HashMap;
import java.util.Random;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

@Path("/")
public class Producer {
   @POST
   @Path("logins")
   @Consumes(MediaType.APPLICATION_JSON)
   @Produces(MediaType.APPLICATION_JSON)
   public Response generateToken(String objInputData) {

    JSONObject jsonObject = null;
    User user = null;
    String username = null;
    String password = null;
    try {
        jsonObject = new JSONObject(objInputData);
        user = new User();
        username = jsonObject.getJSONObject("login-request")
                .get("username").toString();
        password = jsonObject.getJSONObject("login-request")
                .get("password").toString();
        // Your business logic goes here
        // DBHandshaker handshaker = DBHandshaker.getInstance();
        // user = handshaker.logUser(username, password);
        System.out.println(username+password);
        if (user != null) {
            // write your logic to generate token
            // StringUtil stringUtil = StringUtil.getInstance();
            // String tokenString =
            // stringUtil.encryptForToken(user.getUsername(),
            // user.getPassword());
            // dummy string to test
            String tokenString = "Helllllllllgjdkg";

            HashMap<String, String> tokenMap = new HashMap<String, String>();
            tokenMap.put("token", tokenString);

            JSONObject jsonLoginResponse = new JSONObject();
            try {
                jsonLoginResponse.put("login-token", tokenMap);
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return Response.ok(jsonLoginResponse.toString(),
                    MediaType.APPLICATION_JSON).build();

        } else {
            return Response.status(Response.Status.UNAUTHORIZED).build();
        }
    } catch (Exception e1) {
        return Response.status(Response.Status.NO_CONTENT).build();
    }
}
}

Write catcher logic after getting the response

hope this answer is helpful for you