如何使用Java HttpServer / HttpExchange在GET中获取查询字符串?

时间:2012-07-24 22:05:22

标签: java get query-string httpserver

我正在尝试用Java创建一个简单的HttpServer来处理GET请求, 但是当我尝试获取请求的GET参数时,我注意到HttpExchange类没有相应的方法。

有人知道一种简单的方法来读取GET参数(查询字符串)吗?

这就是我的处理程序的样子:

public class TestHandler{
  @Override
  public void handle(HttpExchange exc) throws IOxception {
    String response = "This is the reponse";
    exc.sendResponseHeaders(200, response.length());

    // need GET params here

    OutputStream os = exc.getResponseBody();
    os.write(response.getBytes());
    os.close();
  } 
}

..和主要方法:

public static void main(String[] args) throws Exception{
  // create server on port 8000
  InetSocketAddress address = new InetSocketAddress(8000);
  HttpServer server = new HttpServer.create(address, 0);

  // bind handler
  server.createContext("/highscore", new TestHandler());
  server.setExecutor(null);
  server.start();
}

4 个答案:

答案 0 :(得分:36)

以下内容:httpExchange.getRequestURI().getQuery()

将返回与此类似的格式的字符串:"field1=value1&field2=value2&field3=value3..."

所以你可以自己简单地解析字符串,这就是解析函数的样子:

public Map<String, String> queryToMap(String query) {
    Map<String, String> result = new HashMap<>();
    for (String param : query.split("&")) {
        String[] entry = param.split("=");
        if (entry.length > 1) {
            result.put(entry[0], entry[1]);
        }else{
            result.put(entry[0], "");
        }
    }
    return result;
}

这就是你如何使用它:

Map<String, String> params = queryToMap(httpExchange.getRequestURI().getQuery()); 
System.out.println("param A=" + params.get("A"));

答案 1 :(得分:1)

在@ anon01的答案的基础上,这是如何在Groovy中做到的:

Map<String,String> getQueryParameters( HttpExchange httpExchange )
{
    def query = httpExchange.getRequestURI().getQuery()
    return query.split( '&' )
            .collectEntries {
        String[] pair = it.split( '=' )
        if (pair.length > 1)
        {
            return [(pair[0]): pair[1]]
        }
        else
        {
            return [(pair[0]): ""]
        }
    }
}

这是如何使用它:

def queryParameters = getQueryParameters( httpExchange )
def parameterA = queryParameters['A']

答案 2 :(得分:1)

与annon01相反,这个答案正确解码了键和值。它不使用indexOf,而是使用public static Map<String, String> parseQueryString(String qs) { Map<String, String> result = new HashMap<>(); if (qs == null) return result; int last = 0, next, l = qs.length(); while (last < l) { next = qs.indexOf('&', last); if (next == -1) next = l; if (next > last) { int eqPos = qs.indexOf('=', last); try { if (eqPos < 0 || eqPos > next) result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), ""); else result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); // will never happen, utf-8 support is mandatory for java } } last = next + 1; } return result; } 扫描字符串,这更快。

{{1}}

答案 3 :(得分:0)

偶然发现这一点,并认为我会在这里扔一个Java 8 / Streams实现,同时添加一些额外的位(以前的答案中没有)。

额外1 :我添加了一个过滤器,以避免处理任何空参数。某些不应该发生的事情,但是可以实现更清洁的实现,而不是不处理问题(并发送空响应)。例如:?param1=value1&param2=

额外2 :我利用String.split(String regex, int limit)进行了第二次拆分操作。这样可以传递诸如?param1=it_has=in-it&other=something之类的查询参数。

public static Map<String, String> getParamMap(String query) {
    // query is null if not provided (e.g. localhost/path )
    // query is empty if '?' is supplied (e.g. localhost/path? )
    if (query == null || query.isEmpty()) return Collections.emptyMap();

    return Stream.of(query.split("&"))
            .filter(s -> !s.isEmpty())
            .map(kv -> kv.split("=", 2)) 
            .collect(Collectors.toMap(x -> x[0], x-> x[1]));

}

进口

import java.util.Map;
import java.util.Collections;
import java.util.stream.Stream;
import java.util.stream.Collectors;
相关问题