我正在使用 JAX-RS 构建中继服务器。我需要能够从 GET 请求中提取任何查询参数,然后将它们重新包装到另一个请求中,以传递到另一个服务器。我不熟悉 MultivaluedMap
,但我刚刚弄清楚发生了什么。 UriInfo
类(class)的getQueryParameters
方法返回 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();
}
所以,总而言之,如果请求有查询参数,从上面的代码打印出来的是这样的:
参数:
- key1: [value1]
- 键2:[值2]
- 键3:[值3]
有没有另一种解包/重新打包的方法,也许可以完全避免这整个问题?谢谢。
完整答案
@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();
最佳答案
这是因为 MultivaluedMap 接口(interface)。
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[])
}
关于java - RESTEasy 和方括号中的 MultivaluedMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24833004/