使用单例存储来自servlet的数据(使用码头)

时间:2018-07-20 14:09:00

标签: java singleton jetty

我正在实施服务器客户端项目。

我正在服务器端使用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;
    }
}

1 个答案:

答案 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内置概念?