sgoldberg sgoldberg - 6 months ago 53
JSON Question

post request with multiple parameters JSON and String on Jackson/Jersey JAVA

I've created a rest api using Jersey/Jackson and it works well. I want to adjust my POST methods to receive a string token in addition to the POJO they are receiving as JSON. I've adjusted one of my methods like so:

@POST
@Path("/user")
@Consumes(MediaType.APPLICATION_JSON)
public Response createObject(User o, String token) {
System.out.println("token: " + token);
String password = Tools.encryptPassword(o.getPassword());
o.setPassword(password);
String response = DAL.upsert(o);
return Response.status(201).entity(response).build();

}


I want to call that method, but for whatever reason token prints to null no matter what I try. Here is the client code I've written to send the post request:

public String update() {

try {
com.sun.jersey.api.client.Client daclient = com.sun.jersey.api.client.Client
.create();
WebResource webResource = daclient
.resource("http://localhost:8080/PhizzleAPI/rest/post/user");

User c = new User(id, client, permission, reseller, type, username,
password, name, email, active, createddate,
lastmodifieddate, token, tokentimestamp);
JSONObject j = new JSONObject(c);
ObjectMapper mapper = new ObjectMapper();

String request = mapper.writeValueAsString(c) + "&{''token'':,''"
+ "dog" + "''}";
System.out.println("request:" + request);
ClientResponse response = webResource.type("application/json")
.post(ClientResponse.class, request);
if (response.getStatus() != 201) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus());
}

System.out.println("Output from Server .... \n");
String output = response.getEntity(String.class);
setId(UUID.fromString(output));
System.out.println("output:" + output);
return "" + output;
} catch (UniformInterfaceException e) {
return "failue: " + e.getMessage();
} catch (ClientHandlerException e) {
return "failue: " + e.getMessage();
} catch (Exception e) {
return "failure: " + e.getMessage();
}

}


Any help would be greatly appreciated.

Answer

This is not the way JAX-RS works. The body of your POST request will get marshaled to the first argument of your annotated resource method (in this case, into the User argument). You have a couple options to get around this:

  1. Create a wrapper object containing both a User object and token. Send that back and forth between your client and server.
  2. Specify the token as a query parameter on your URL and access it on the server side as a @QueryParam.
  3. Add the token as a header parameter and access it on the server side as a @HeaderParam.

Example - Option 1

class UserTokenContainer implements Serializable {
    private User user;
    private String token;

    // Constructors, getters/setters
}

Example - Option 2

Client:

WebResource webResource = client.
    resource("http://localhost:8080/PhizzleAPI/rest/post/user?token=mytoken");

Server:

@POST
Path("/user")
@Consumes(MediaType.APPLICATION_JSON)
public Response createObject(@QueryParam("token") String token, User o) {
    System.out.println("token: " + token);
    // ...
}

Example - Option 3

Client:

ClientResponse response = webResource
    .type("application/json")
    .header("Token", token)
    .post(ClientResponse.class, request);

Server:

@POST
Path("/user")
@Consumes(MediaType.APPLICATION_JSON)
public Response createObject(@HeaderParam("token") String token, User o) {
    System.out.println("token: " + token);
    // ...
}
Comments