我正在使用JAX-RS构建中继服务器。我需要能够从GET请求中提取任何查询参数,然后将它们重新包装到另一个请求中,以传递给另一个服务器。我不熟悉MultivaluedMap
,但我只知道发生了什么。 UriInfo
类getQueryParameters
方法返回MultivaluedMap<String, String>
。令我意外的是,每个参数的值都是List
值,即使它们声称是String
值(通过我读取JavaDoc的方式)。
换句话说,如果我有一个foo=bar
的键值对,则在URL查询字符串中,当我提取参数时,它会显示为foo=[bar]
。当我尝试重新包装参数并将其发送到另一台服务器时,这完全抛出了一个循环(实际上是500服务器错误)。
是否有另一种方法来处理从Request中解包查询字符串,然后将其重新打包为另一个请求?我包含了一些代码来说明我的问题:
@GET
@Path("parameters")
public Response showParameters(@Context UriInfo uriInfo) {
MultivaluedMap<String, String> parameters = uriInfo.getQueryParameters();
StringBuffer sb = new StringBuffer();
sb.append("<h4>Parameters:</h4>");
if (parameters != null) {
sb.append("<ul>");
Iterator it = parameters.keySet().iterator();
while (it.hasNext()) {
String key = (String)it.next();
sb.append("<li>")
.append(key)
.append(": ")
.append(parameters.get(key))
.append("</li>");
}
sb.append("</ul>");
}
else {
sb.append("<p>None</p>");
}
return Response.ok(sb.toString()).build();
}
因此,总而言之,如果请求具有查询参数,从上面的代码中打印出来的内容是这样的:
参数:
还有其他方法可以解压缩/重新包装,也许可以完全避免这个问题吗?感谢。
@Jack值得赞扬,因为我指的是正确的方向,我正在标记his answer是正确的,但这就是我的工作。
Client client = ClientBuilder.newClient();
// Assume instance variable providing URI (without query string).
WebTarget target = client.target(theRequestUri);
// Instance variable uriInfo.
MultivaluedMap<String, String> parameters = uriInfo.getQueryParameters();
if (parameters != null && parameters.size() > 0) {
Iterator it = parameters.keySet().iterator();
String key = null;
StringTokenizer st = null;
while (it.hasNext()) {
key = (String)it.next();
// RESTEasy API is quirky, here. It wraps the values in square
// brackets; moreover, each value is separated by a comma and
// padded by a space as well. ([one, two, three, etc])
st = new StringTokenizer(parameters.get(key).toString(), "[,]");
while (st.hasMoreTokens()) {
target = target.queryParam(key, st.nextToken().trim());
}
}
}
// Instance method: getContentType.
Response response = target.request().accept(getContentType()).get();
答案 0 :(得分:3)
它因为MultivaluedMap接口。
public interface MultivaluedMap<K, V> extends Map<K, List<V>> {
它返回值List
。
而不是parameters.get(key)
尝试parameters.getFirst(key)
请注意,这将删除同一参数的其他值。在进行休息调用(例如blahblah:8080?foo=bar1&foo=bar2
)时,可以为同一参数发送多个值。通过getFirst()
电话,您只会获得bar1
值。如果您确定无法接听多个电话,则可以使用getFirst(key)
方法
--- 更新 --- 根据您的评论,您似乎需要遍历多值映射并在WebTarget实例上调用queryParam。我知道你正在寻找一个图书馆/直接的方式来做到这一点。我没有尝试RESTEasy。但我认为代码应该足够简单。
multiValuesMap?.each { key, values->
webTargetInstance = webTargetInstance.queryParam(key, values as Object[])
}