我正在实施服务器客户端项目。
我正在服务器端使用Jetty。
每当客户端通过某种共享位置连接到服务器时,我想存储每个客户端的连接时间。
我选择了map
<clientID, ClinetInfo>
,然后使用singelton存储了所有数据。
不幸的是,这不起作用。每次客户端发送http请求并触发码头手柄时,都会创建新的单例对象。
为什么?
如何实现所有客户信息的持久化?
我附加了代码(请忽略处理reuqest的逻辑。它不是相对的)。
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();
}
}
RequestsHandler
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;
}
}
答案 0 :(得分:1)
为什么不只是...
ClientsVisitsSingleton singleton = new ClientVisitsSingleton();
context.setHandler(new RequestsHandler(singleton));
,然后在您的RequestsHandler
中...
public class RequestsHandler extends AbstractHandler {
final ClientsVisitsSingleton singleton;
public RequestsHandler(ClientsVisitsSingleton singleton) {
this.singleton = singleton;
}
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
{
// ... use singleton as any other object here
但是最终,我不得不问,为什么不仅仅使用ServletContextHandler(SESSIONS)
并使用Jetty中已经内置的HttpSession
内置概念?