How to obtain the query string in a GET with Java HttpServer/HttpExchange?

前端 未结 4 1267
孤独总比滥情好
孤独总比滥情好 2021-02-05 06:27

I am trying to create a simple HttpServer in Java to handle GET requests, but when I try to get the GET parameters for a request I noticed the HttpExchange class does not have a

相关标签:
4条回答
  • 2021-02-05 06:48

    This answer, contrary to annon01's, properly decodes the keys and values. It does not use String.split, but scans the string using indexOf, which is faster.

    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;
    }
    
    0 讨论(0)
  • 2021-02-05 06:51

    The following: httpExchange.getRequestURI().getQuery()

    will return string in format similar to this: "field1=value1&field2=value2&field3=value3..."

    so you could simply parse string yourself, this is how function for parsing could look like:

    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;
    }
    

    And this is how you could use it:

    Map<String, String> params = queryToMap(httpExchange.getRequestURI().getQuery()); 
    System.out.println("param A=" + params.get("A"));
    
    0 讨论(0)
  • 2021-02-05 07:01

    Stumbled across this, and figured I'd toss a Java 8 / Streams implementation out here, whilst adding a few extra bits (not in previous answers).

    Extra 1: I've added a filter to avoid processing any empty params. Something that should not happen, but it allows a cleaner implementation vs. not handling the issue (and sending an empty response). An example of this would look like ?param1=value1&param2=

    Extra 2: I've leveraged String.split(String regex, int limit) for the second split operation. This allows a query parameter such as ?param1=it_has=in-it&other=something to be passed.

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

    Imports

    import java.util.Map;
    import java.util.Collections;
    import java.util.stream.Stream;
    import java.util.stream.Collectors;
    
    0 讨论(0)
  • 2021-02-05 07:02

    Building on the answer by @anon01, this is how to do it in 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]): ""]
            }
        }
    }
    

    And this is how to use it:

    def queryParameters = getQueryParameters( httpExchange )
    def parameterA = queryParameters['A']
    
    0 讨论(0)
提交回复
热议问题