[英]MultivaluedMap in RESTEasy and square brackets
我正在使用JAX-RS构建某种中继服务器。 我需要能够从GET请求中提取所有查询参数,然后将它们重新包装到另一个请求中,以传递给另一个服务器。 我不熟悉MultivaluedMap
,但我只是想知道正在发生什么。 UriInfo
类的getQueryParameters
方法返回UriInfo
MultivaluedMap<String, String>
。 出乎我意料的是,每个参数的值都是List
值,即使它们声称是String
值(通过我阅读JavaDoc的方式)。
换句话说,如果我有一个键值对foo=bar
,那么在URL查询字符串中,当我提取参数时,它会以foo=[bar]
。 当我尝试重新包装参数并将其发送到另一台服务器时,这完全使我陷入了循环(实际上是500服务器错误)。
还有另一种方法来处理从请求中解包查询字符串,然后将其重新打包以用于另一个请求吗? 我包含一些代码来说明我的问题:
@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为我指出正确的方向而值得称赞,我将他的回答标记为正确,但这就是我正在努力的地方。
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();
这是因为MultivaluedMap接口。
public interface MultivaluedMap<K, V> extends Map<K, List<V>> {
它将值返回为List
。
代替parameters.get(key)
尝试parameters.getFirst(key)
请注意,这将删除同一参数的其他值。 在进行诸如blahblah:8080?foo=bar1&foo=bar2
类的rest调用时,可以为同一参数发送多个值。 通过getFirst()
调用,您将仅获得bar1
值。 如果您确定不会接到多个电话,可以使用getFirst(key)
方法
--- 更新 ---根据您的评论,似乎您需要遍历多值映射并在WebTarget实例上调用queryParam。 我了解您正在寻找一种图书馆/直接的方式来做到这一点。 我没有尝试过RESTEasy。 但是我认为代码应该足够简单。
multiValuesMap?.each { key, values->
webTargetInstance = webTargetInstance.queryParam(key, values as Object[])
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.