2012-12-28 10 views
21

Stworzyłem api odpoczynku za pomocą Jersey/Jackson i działa dobrze. Chcę dostosować moje metody POST do odbierania tokenu ciągu oprócz POJO, które odbierają jako JSON. Mam regulować jeden z moich metod tak:po żądaniu z wieloma parametrami JSON i String na Jackson/Jersey JAVA

@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(); 

} 

Chcę wywołanie tej metody, ale z jakiegoś powodu symboliczne druki null bez względu na to, co staram. Oto kod klienta, który napisałem, aby wysłać prośbę o wpis:

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(); 
    } 

} 

Każda pomoc zostanie bardzo doceniona.

Odpowiedz

38

Nie działa tak, jak działa JAX-RS. Treść Twojego żądania POST zostanie przekazana do pierwszego argumentu metody z adnotacjami zasobów (w tym przypadku do argumentu User). Masz kilka opcji obejścia tego:

  1. Utwórz obiekt opakowania zawierający zarówno obiekt użytkownika, jak i token. Wysyłaj te wiadomości między klientem a serwerem.
  2. Określ token jako parametr zapytania na swoim adresie URL i uzyskaj dostęp do niego po stronie serwera jako @QueryParam.
  3. Dodaj token jako parametr nagłówka i uzyskaj dostęp po stronie serwera jako @HeaderParam.

Przykład - Opcja 1

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

    // Constructors, getters/setters 
} 

Przykład - Opcja 2

klienta:

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

serwera:

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

Przykład - Wariant 3

klienta:

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

serwera:

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

wolałbym uniknąć opcję 1 jeśli to możliwe bo wtedy doda więcej złożoności, niż chcę. Próbowałem opcji 2 i 3, ale token zwraca wartość null. Zmęczony to tak: JSONObject j = new JSONObject (c); \t \t \t Objectperper mapper = new ObjectMapper(); \t \t \t Żądanie ciągu = mapper.writeValueAsString (c) + "& token = '12345'"; \t \t \t \t \t System.out.println ("request:" + request); \t \t Odpowiedź ClientResponse = webResource.type ("application/json") – sgoldberg

+3

Dodałem przykłady jak zaimplementować opcje 2 i 3 – Perception

+0

Dziękujemy! To działało idealnie! Opcja 3. Dziękujemy! – sgoldberg

0

Jeśli używasz Jersey 1.x, najlepszym rozwiązaniem jest, aby opublikować wiele obiektów jak @FormParam

Przynajmniej dwie zalety:

  1. Nie trzeba użyć obiektu otoki odpowiedzieć wielu parametrów
  2. parametry są wysłane w organizmie niż w adresie URL (jak @QueryParam i @PathParam)

Sprawdź ten przykład:

Klient: (pure Java):

public Response testPost(String param1, String param2) { 
    // Build the request string in this format: 
    // String request = "param1=1&param2=2"; 
    String request = "param1=" + param1+ "&param2=" + param2; 
    WebClient client = WebClient.create(...); 
    return client.path(CONTROLLER_BASE_URI + "/test") 
      .post(request); 
} 

Serwer:

@Path("/test") 
@POST 
@Produces(MediaType.APPLICATION_JSON) 
public void test(@FormParam("param1") String param1, @FormParam("param2") String param2) { 
    ... 
}