我试图为单元测试编写一个模拟HTTP服务器,为此我使用了com.sun.net.httpserver类。我对URL的编码有问题:查询参数是ISO8859-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;
}
}发布于 2015-03-20 12:54:49
HttpExchange.getQueryString()的javadoc表示它返回“未解码的请求URI查询字符串,如果请求URI没有,则为null。”
如果它没有被解码,并且由于http头必须在7位ASCII (ietf.org/rfc/rfc 2616.txt)中,那么您以后可以用URLDecoder.decode(."ISO-8859-1");
https://stackoverflow.com/questions/29166178
复制相似问题