繁体   English   中英

RESTEasy中的MultivaluedMap和方括号

[英]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();
}

因此,总而言之,如果请求具有查询参数,则从上面的代码中打印出来的内容是这样的:

参数:

  • key1:[value1]
  • key2:[value2]
  • key3:[value3]

还有另一种解包/重新打包的方法,也许可以完全避免整个问题? 谢谢。

完整答案

@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM