在Jackson / Jersey JAVA上发布带有多个参数JSON和String的请求

我用Jersey / Jackson创建了一个restapi,效果很好。 我想调整我的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。 这是我写的发送post请求的客户端代码:

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

任何帮助将不胜感激。

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

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

示例 – 选项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); // ... } 

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

至少有两个优点:

  1. 您不需要使用包装器对象来发布多个参数
  2. 参数在body中发送而不是在url中发送(与@QueryParam@PathParam一样

检查此示例:

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