web-dev-qa-db-fra.com

poste de demande avec plusieurs paramètres JSON et String sur Jackson/Jersey JAVA

J'ai créé une api de repos avec Jersey/Jackson et cela fonctionne bien. Je souhaite ajuster mes méthodes POST pour recevoir un jeton de chaîne en plus du POJO reçu en tant que JSON. J'ai ajusté une de mes méthodes comme ceci: 

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

}

Je veux appeler cette méthode, mais pour quelque raison que ce soit, le jeton est imprimé en null, peu importe ce que j'essaie. Voici le code client que j'ai écrit pour envoyer la demande de publication: 

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

}

Toute aide serait grandement appréciée. 

22
sgoldberg

Ce n'est pas ainsi que JAX-RS fonctionne. Le corps de votre demande POST sera marshalé au premier argument de votre méthode de ressource annotée (dans ce cas, dans l'argument User). Vous avez plusieurs options pour contourner cela:

  1. Créez un objet wrapper contenant à la fois un objet utilisateur et un jeton. Envoyez-le entre votre client et votre serveur.
  2. Spécifiez le jeton en tant que paramètre de requête sur votre URL et accédez-y côté serveur en tant que @QueryParam.
  3. Ajoutez le jeton en tant que paramètre d'en-tête et accédez-y côté serveur en tant que @HeaderParam.

Exemple - Option 1

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

    // Constructors, getters/setters
}

Exemple - Option 2

Client:

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

Serveur:

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

Exemple - Option 3

Client:

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

Serveur:

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

Si vous utilisez Jersey 1.x, la meilleure approche consiste à publier plusieurs objets sous la forme @FormParam

Au moins deux avantages:

  1. Vous n'avez pas besoin d'utiliser un objet wrapper pour publier plusieurs paramètres
  2. Les paramètres sont envoyés dans le corps plutôt que dans l'URL (comme avec@QueryParamet@PathParam)

Vérifiez cet exemple: 

Client: (Java pur):

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

Serveur:

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