首先是一些(非常基本的)示例代码来说明我的问题:
final java.util.concurrent.atomic.AtomicLong previousId = new java.util.concurrent.atomic.AtomicLong();
final com.sun.net.httpserver.HttpServer server = com.sun.net.httpserver.HttpServer.create(new java.net.InetSocketAddress(8666), 0);
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
server.createContext("/", exchange -> {
final long id = previousId.incrementAndGet();
System.out.println(String.format("#%s: id attribute=%s", id, exchange.getAttribute("id")));
exchange.setAttribute("id", id);
while (true) {
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
System.out.println(String.format("#%s: id attribute=%s", id, exchange.getAttribute("id")));
}
});
server.start();
在运行此程序时(在Java SE 1.8.0_171上),如果我连续两次向
http://localhost:8666
请求,则会得到以下日志:#1: id attribute=null
#1: id attribute=1
#1: id attribute=1
#2: id attribute=1
#1: id attribute=2
#2: id attribute=2
#1: id attribute=2
#2: id attribute=2
对于请求#1,属性最初是
null
,如预期的那样。对于请求2,该属性最初是1
,这似乎意味着初始值是从其他请求继承的。如您所见,更糟糕的是,将请求2的值更改为2
还将请求1的值更改为2
。似乎属性在HttpExchange
实例之间共享,这不是我期望的。我缺少什么还是
HttpExchange
属性损坏了吗? 最佳答案
从the source code看,很显然,HttpExchange
属性由同一HttpContext
上的所有实例共享。尽管在setAttribute
上定义了getAttribute
和HttpExchange
方法,但我发现它具有误导性。我认为Javadoc没有帮助:
筛选器模块可以将带有HttpExchange实例的任意对象存储为带外通信机制。
我有sent an email to the net-dev mailing list和filed a bug。收到一些消息后,我将立即更新此答案。