将REST调用中的@PathParam值存储在列表或数组中
我的function看起来像这样:
@PUT @Path("property/{uuid}/{key}/{value}") @Produces("application/xml") public Map updateProperty(@Context HttpServletRequest request, @PathParam("key") String key, @PathParam("value") String value, @PathParam("uuid") String uuid) throws Exception { ... }
我必须修改它,因此它接受来自REST调用的无限(或许多)键值对列表,例如
@Path("property/{uuid}/{key1}/{value1}/{key2}/{value2}/{key3}/{value3}/...")
是否可以将它们存储在数组或列表中,所以我没有列出几十个@PathParams和参数,以避免这种情况:
@PathParam("key1") String key1, @PathParam("key2") String key2, @PathParam("key3") String key3,
可能是重新思考这种设计的好机会。 通过使用/
s,我们在某种程度上表示,每个/
我们正试图找到不同的资源。 键/值对(在URL的上下文中)主要用于查询参数或矩阵参数。
如果/property/{uuid}
是主资源的路径,并且我们只想向客户端提供一些参数来访问该资源,那么我们可以允许矩阵参数或查询参数
矩阵参数 (在请求URL中)看起来像
/12345;key1=value1;key2=value2;key3=value3
获取值的资源方法可能类似于
@GET @Path("/property/{uuid}") public Response getMatrix(@PathParam("uuid") PathSegment pathSegment) { StringBuilder builder = new StringBuilder(); // Get the {uuid} value System.out.println("Path: " + pathSegment.getPath()); MultivaluedMap matrix = pathSegment.getMatrixParameters(); for (Object key : matrix.keySet()) { builder.append(key).append(":") .append(matrix.getFirst(key)).append("\n"); } return Response.ok(builder.toString()).build(); }
- 请参见
PathSegment
查询参数 (在请求URL中)可能看起来像
/12345?key1=value1&key2=value2&key3=value3
获取值的资源方法可能类似于
@GET @Path("/property/{uuid}") public Response getQuery(@PathParam("uuid") String uuid, @Context UriInfo uriInfo) { MultivaluedMap params = uriInfo.getQueryParameters(); StringBuilder builder = new StringBuilder(); for (Object key : params.keySet()) { builder.append(key).append(":") .append(params.getFirst(key)).append("\n"); } return Response.ok(builder.toString()).build(); }
- 见
UriInfo
不同之处在于Matrix参数可以嵌入到路径段中,而查询参数必须放在URL的末尾。 您还可以注意到语法上的一些差异。
一些资源
- 查询字符串(维基百科)
- 何时使用查询参数与矩阵参数?
- URL矩阵参数与请求参数
UPDATE
同时查看方法签名中的PUT
,您似乎正在尝试使用路径更新资源作为您尝试更新的值,因为我没有在您的方法中看到实体主体的任何参数。 在PUTting时,您应该在实体主体中发送表示,而不是路径段或参数。
解决方法:
@Path("/foo/bar/{other: .*} public Response foo(@PathParam("other") VariableStrings vstrings) { String[] splitPath = vstrings.getSplitPath(); }
VariableStrings类:
public class VariableStrings { private String[] splitPath; public VariableStrings(String unparsedPath) { splitPath = unparsedPath.split("/"); } }
路径段序列到JAX-RS / Jersey中的vararg数组?
将可选参数映射到Map的另一个示例:
@GET @ Produces({"application/xml", "application/json", "plain/text"}) @ Path("/location/{locationId}{path:.*}") public Response getLocation(@PathParam("locationId") int locationId, @PathParam("path") String path) { Map < String, String > params = parsePath(path); String format = params.get("format"); if ("xml".equals(format)) { String xml = " parsePath(String path) { if (path.startsWith("/")) { path = path.substring(1); } String[] pathParts = path.split("/"); Map < String, String > pathMap = new HashMap < String, String > (); for (int i = 0; i < pathParts.length / 2; i++) { String key = pathParts[2 * i]; String value = pathParts[2 * i + 1]; pathMap.put(key, value); } return pathMap; }