【发布时间】:2018-07-20 14:08:59
【问题描述】:
我正在实现一个服务器客户端项目。
我在服务器端使用 Jetty。
每当客户端(通过 http)连接到某种共享位置的服务器时,我想存储每个客户端的连接时间。
我选择了map<clientID, ClinetInfo>,并使用了单例来存储所有数据。
不幸的是,这不起作用.. 每次客户端发送 http 请求并触发码头句柄时,都会创建新的单例对象。
为什么?
如何实现所有客户信息的这种持久性?
我附上代码(请忽略处理请求的逻辑..它不是相关的)。
package com.server;
import com.server.client.ClientsVisitsSingleton;
import com.server.httphandlers.RequestsHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
public class ProtectingServer
{
public static void main(String[] args) throws Exception
{
org.eclipse.jetty.server.Server server = new org.eclipse.jetty.server.Server(8081);
ContextHandler context = new ContextHandler();
context.setContextPath("/");
context.setResourceBase(".");
context.setClassLoader(Thread.currentThread().getContextClassLoader());
server.setHandler(context);
ClientsVisitsSingleton.getInstance();
context.setHandler(new RequestsHandler());
server.start();
server.join();
System.out.println();
}
}
请求处理程序
package com.server.httphandlers;
import com.server.client.ClientUtils;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestsHandler extends AbstractHandler {
public static final String CONTENT_TYPE = "text/html; charset=utf-8";
@Override
public void handle(String target,
Request baseRequest,
HttpServletRequest request,
HttpServletResponse response) throws IOException
{
if (ClientUtils.isClientRequest(request)) {
ClientHandler clientHandler = new ClientHandler();
//here is where I used the singlton object to store the client access time.. which instantiate an new object instead using the singlton.
clientHandler.handleClientAccess(request, response);
}
else{
response.setContentType(CONTENT_TYPE);
response.setStatus(HttpServletResponse.SC_OK);
}
baseRequest.setHandled(true);
}
}
单例对象
package com.server.client;
import java.util.HashMap;
import java.util.Map;
public class ClientsVisitsSingleton {
private static ClientsVisitsSingleton clientsVisitsSingleton;
private Map<Long, ClientVisitsInfo> clientsVisits;
private ClientsVisitsSingleton() {
clientsVisits = new HashMap<Long, ClientVisitsInfo>();
}
public static synchronized ClientsVisitsSingleton getInstance() {
if (clientsVisitsSingleton == null) {
synchronized (ClientsVisitsSingleton.class) {
if (clientsVisitsSingleton == null) {
clientsVisitsSingleton = new ClientsVisitsSingleton();
}
}
}
return clientsVisitsSingleton;
}
public Map<Long, ClientVisitsInfo> getClientsVisits() {
return clientsVisits;
}
}
【问题讨论】:
-
请发布例外情况
-
更改我的描述。也不例外,但正在创建一个新的单例实例
-
能否请您发帖
ClientHandler。另请注意,您在ClientsVisitsSingleton.getInstance()中两次synchronized一次on 方法一次in 方法。