【问题标题】:Using a singleton to store data from servlets (using jetty)使用单例存储来自 servlet 的数据(使用码头)
【发布时间】: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 方法。

标签: java singleton jetty


【解决方案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 概念?

【讨论】:

    猜你喜欢
    • 2020-08-19
    • 2019-12-25
    • 2014-05-08
    • 1970-01-01
    • 2019-08-31
    • 2013-04-10
    • 2015-05-30
    • 1970-01-01
    相关资源
    最近更新 更多