在 Jackson/Jersey JAVA 上发布带有多个参数 JSON 和 String 的请求
Posted
技术标签:
【中文标题】在 Jackson/Jersey JAVA 上发布带有多个参数 JSON 和 String 的请求【英文标题】:post request with multiple parameters JSON and String on Jackson/Jersey JAVA 【发布时间】:2012-12-14 01:37:40 【问题描述】:我使用 Jersey/Jackson 创建了一个 rest api,它运行良好。除了他们作为 JSON 接收的 POJO 之外,我想调整我的 POST 方法以接收字符串令牌。我已经调整了我的一种方法,如下所示:
@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();
我想调用该方法,但无论出于何种原因,无论我尝试什么,token 都会打印为 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();
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:这不是 JAX-RS 的工作方式。您的 POST 请求的正文将被编组到带注释的资源方法的第一个参数(在本例中,为 User
参数)。你有几个选择来解决这个问题:
-
创建一个包含用户对象和令牌的包装对象。在客户端和服务器之间来回发送。
将令牌指定为 URL 上的查询参数,并在服务器端以
@QueryParam
的形式访问它。
将令牌添加为标头参数,并在服务器端以@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);
// ...
【讨论】:
如果可能的话,我宁愿避免使用选项 1,因为它会增加我想要的复杂性。我尝试了选项 2 和 3,但令牌返回 null。我厌倦了它: JSONObject j = new JSONObject(c); ObjectMapper 映射器 = 新 ObjectMapper();字符串请求 = mapper.writeValueAsString(c) + "&token='12345'"; System.out.println("请求:" + 请求); ClientResponse response = webResource.type("application/json") 我添加了如何实现选项 2 和 3 的示例 @Perception 如果两个参数都是复杂类型怎么办?那么我们应该只使用选项1还是2,3选项有一些技巧?【参考方案2】:如果您使用 Jersey 1.x,最好的方法是将多个对象发布为 @FormParam
至少有两个优点:
-
您不需要使用包装对象来发布多个参数
参数在正文中而不是在 url 中发送(如 @QueryParam 和 @PathParam)
检查这个例子:
客户端:(纯 Java):
public Response testPost(String param1, String param2)
// Build the request string in this format:
// String request = "param1=1¶m2=2";
String request = "param1=" + param1+ "¶m2=" + 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)
...
【讨论】:
以上是关于在 Jackson/Jersey JAVA 上发布带有多个参数 JSON 和 String 的请求的主要内容,如果未能解决你的问题,请参考以下文章