java - com.sun.net.httpserver 中的字符编码

标签 java character-encoding httpserver

我正在尝试编写一个模拟 HTTP 服务器用于单元测试,我正在使用 com.sun.net.httpserver 类。 我在 URL 编码方面遇到问题:查询参数是 ISO-8859-1 编码的,但传递到处理程序(通过 HttpExchange)的 URI 不是。 由于我无法更改原始服务器的编码,我想知道是否有办法告诉 HttpServer 在解码 URL 时使用哪种编码。 提前致谢。

这是一个测试程序:

package test34;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {
    public static void main(String[] args) {
        try {
            MockServer mock = new MockServer();
            mock.start(8642);
            URL url = new URL("http://localhost:8642/?p="
                    + URLEncoder.encode("téléphone", "ISO-8859-1"));
            System.out.println(url);
            InputStream in = url.openStream();
            while (in.read() > 0) {
            }
            in.close();
            mock.stop();
            System.out.println(mock.getLastParams().get("p"));
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }    
}

这是模拟服务器的代码:

package test34;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;

import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class MockServer {

    private HttpServer httpServer;
    private Map<String, String> params;

    public void start(int port) {
        if (httpServer == null) {
            try {
                InetSocketAddress addr = new InetSocketAddress(port);
                httpServer = HttpServer.create(addr, 0);
                httpServer.createContext("/", new HttpHandler() {
                    @Override
                    public void handle(HttpExchange exchange) throws IOException {
                        try {
                            handleRoot(exchange);
                        } catch (RuntimeException e) {
                            throw e;
                        } catch (IOException e) {
                            throw e;
                        }
                    }
                });
                httpServer.setExecutor(Executors.newFixedThreadPool(1));
                httpServer.start();
            } catch (IOException e) {
                throw new RuntimeException(e.getMessage());
            }
        }
    }

    public void stop() {
        if (httpServer != null) {
            httpServer.stop(10);
            httpServer = null;
        }
    }

    public Map<String, String> getLastParams() {
        Map<String, String> result = new HashMap<String, String>();
        if (params != null) {
            result.putAll(params);
        }
        return result;
    }

    private void handleRoot(HttpExchange exchange) throws IOException {
        URI uri = exchange.getRequestURI();
        params = parseQuery(uri.getQuery());
        Headers responseHeaders = exchange.getResponseHeaders();
        responseHeaders.set("Content-Type", "text/plain;charset=ISO-8859-1");
        exchange.sendResponseHeaders(200, 0);
        OutputStream stream = exchange.getResponseBody();
        try {
            Writer writer = new OutputStreamWriter(stream, "ISO-8859-1");
            try {
                PrintWriter out = new PrintWriter(writer);
                try {
                    out.println("OK");
                } finally {
                    out.close();
                }
            } finally {
                writer.close();
            }
        } finally {
            stream.close();
        }
    }

    private static Map<String, String> parseQuery(String qry)
            throws IOException {
        Map<String, String> result = new HashMap<String, String>();
        if (qry != null) {
            String defs[] = qry.split("[&]");
            for (String def : defs) {
                int ix = def.indexOf('=');
                if (ix < 0) {
                    result.put(def, "");
                } else {
                    String name = def.substring(0, ix);
                    String value = URLDecoder.decode(
                            def.substring(ix + 1), "ISO-8859-1");
                    result.put(name, value);
                }
            }
        }
        return result;
    }
}

最佳答案

HttpExchange.getQueryString() 的 javadoc 表示它返回“请求 URI 的未解码查询字符串,如果请求 URI 没有,则返回 null”。

如果未解码,并且由于 http header 必须为 7 位 ASCII (ietf.org/rfc/rfc2616.txt) ,那么您可以稍后使用 URLDecoder.decode(... "ISO-8859-1 ”);

关于java - com.sun.net.httpserver 中的字符编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29166178/

相关文章:

java - 如何获取嵌套类型内部结构的所有类型?

java - 从不同类调用方法时出现 NullPointerException

java - Solr vs 文档编码问题

javascript - 设置 img src 不会生成 GET 请求

node.js - 与 Web 服务器相关的 autoIndex 是什么?

java - Jackson 序列化没有属性

Java 8流flatMap允许对嵌套列表中的每个列表进行空检查吗?

character-encoding - 如何将unicode文本转换为可读的utf8文本?

java - 根据编码计算字符字节长度的有效方法

javascript - dlib http 服务器将网站显示为纯 html,没有 javascript/css