在Jackson / Jersey JAVA上使用多个参数JSON和String发布请求

时间:2012-12-28 20:33:13

标签: java json post jersey jackson

我使用Jersey / Jackson创建了一个休息api,效果很好。我想调整我的POST方法以接收除了作为JSON接收的POJO之外的字符串标记。我已经调整了我的一个方法:

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

}

我想调用该方法,但无论出于何种原因,无论我尝试什么,令牌都会打印为null。这是我写的发送帖子请求的客户端代码:

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

}

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:39)

这不是JAX-RS的工作方式。 POST请求的主体将被封送到带注释的资源方法的第一个参数(在这种情况下,进入User参数)。你有两个选择来解决这个问题:

  1. 创建一个包含User对象和令牌的包装器对象。在客户端和服务器之间来回发送。
  2. 将您的令牌指定为您网址上的查询参数,并将其作为@QueryParam在服务器端进行访问。
  3. 将标记添加为标头参数,并在服务器端以@HeaderParam
  4. 的形式访问它

    示例 - 选项1

    class UserTokenContainer implements Serializable {
        private User user;
        private String token;
    
        // Constructors, getters/setters
    }
    

    示例 - 选项2

    客户端

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

    服务器

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

    示例 - 选项3

    客户端

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

    服务器

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

答案 1 :(得分:0)

如果您使用Jersey 1.x,最好的方法是将多个对象发布为 @FormParam

至少有两个好处:

  1. 您不需要使用包装器对象发布多个参数
  2. 参数在正文中而不是在网址中发送(与 @QueryParam @PathParam
  3. 检查此示例:

    客户端:(纯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);
    }
    

    <强> 服务器:

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