将来自 REST 调用的 @PathParam 值存储在列表或数组中
Posted
技术标签:
【中文标题】将来自 REST 调用的 @PathParam 值存储在列表或数组中【英文标题】:Store @PathParam values from REST call in a list or array 【发布时间】:2015-01-15 12:25:40 【问题描述】:我的函数如下所示:
@PUT
@Path("property/uuid/key/value")
@Produces("application/xml")
public Map<String,ValueEntity> 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,
【问题讨论】:
【参考方案1】:解决方法:
@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("/");
Path segment sequence to vararg array in JAX-RS / Jersey?
另一个将可选参数映射到 Map 的示例:
@GET
@ Produces("application/xml", "application/json", "plain/text")
@ Path("/location/locationIdpath:.*")
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 = "<location<</location<<id<</id<" + locationId + "";
return Response.status(200).type("application/xml").entity(xml).build();
else if ("json".equals(format))
String json = " 'location' : 'id' : '" + locationId + "' ";
return Response.status(200).type("application/json").entity(json).build();
else
String text = "Location: id=" + locationId;
return Response.status(200).type("text/plain").entity(text).build();
private Map < String, String > 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;
【讨论】:
【参考方案2】:可能是重新思考此设计的好机会。通过使用/
s,我们在某种程度上表示,每个/
都在尝试定位不同的资源。键/值对(在 URL 的上下文中)主要用于查询参数或矩阵参数。
如果/property/uuid
是一个主资源的路径,我们只是想提供一些参数给客户端访问这个资源,那么我们可以允许矩阵参数或查询参数
矩阵参数(在请求网址中)看起来像
/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
查询参数(在请求网址中)可能类似于
/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
不同的是,矩阵参数可以嵌入到路径段中,而查询参数必须放在 URL 的末尾。您还可以注意到语法上的一些差异。
一些资源
Query String (Wikipedia) When to use query parameters versus matrix parameters? URL matrix parameters vs. request parameters更新
同时查看方法签名中的PUT
,您似乎正在尝试使用路径作为您尝试更新的值来更新资源,因为我在您的方法中没有看到任何参数实体体。放置时,您应该在实体主体中发送表示,而不是作为路径段或参数。
【讨论】:
非常感谢。我调整了你的建议,效果很好。以上是关于将来自 REST 调用的 @PathParam 值存储在列表或数组中的主要内容,如果未能解决你的问题,请参考以下文章
在节点中创建 REST API 时,如何将来自对外部网站的请求的 http 响应流式传输到原始 api 调用?