根据请求域(vhost)嵌入式jetty和guice Handler servlet

时间:2016-02-12 13:57:07

标签: java servlets guice embedded-jetty guice-servlet

详细说明, 我通过java嵌入使用一个单一的jetty服务器来处理多个请求。我正在使用guice注入事件监听器和安全过滤器。但我需要服务器servlet请求domian。我正在尝试使用虚拟主机,但由于我没有使用基于xml的配置,因此没有太多文档可以获得帮助。

所以我正在努力的是 -

如果域名a.b.c - >处理程序AHandler和过滤器应用AFilter,

如果域名b.b.c - >处理程序BHandler和过滤器应用了BFilter。

我的Contex初始化是这样的:

getHandler(server) {
        ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        handler.setVirtualHosts(new String[]{HOST});
        handler.setClassLoader(Thread.currentThread().getContextClassLoader());
        handler.setServer(server);
        handler.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
        handler.setContextPath("/");
        handler.addEventListener(new ServerContextListener());
}

听众类

class ServerContextListener extends GuiceServletContextListener {
  private ServletContext servletContext;

  public ServletContext getServletContext() {
    return servletContext;
  }

  @Override
  public void contextInitialized(ServletContextEvent servletContextEvent) {
    this.servletContext = checkNotNull(servletContextEvent.getServletContext(), "servletContext");
    super.contextInitialized(servletContextEvent);
  }

  @Override
  protected Injector getInjector() {
    return Guice.createInjector(getModules());
  }

  private Iterable<Module> getModules() {
    return ImmutableList.of(
        new SecurityModule(getServletContext()),
        new ResourceModule());
  }
}

安全模块:

class SecurityModule extends ShiroWebModule {

  public SecurityModule(ServletContext servletContext) {
    super(servletContext);
  }

  @SuppressWarnings("unchecked")
  @Override
  protected void configureShiroWeb() {
    addFilterChain("/**", AUTHC_BASIC);
  }
}


class ResourceModule extends ServletModule {

  @Override
  protected void configureServlets() {
    serve("/*").with(AServlet.class);
  }
}

在服务器中就像这样:

Server server = new Server(new InetSocketAddress("0.0.0.0", 8585));

HandlerCollection handler = new HandlerCollection();
handler.addHandler(AContext.getHandler(server));
handler.addHandler(BContext.getHandler(server));

server.setHandler(handler);
server.start();

并且AServlet和BServlet是常规servlet,带有post post put方法。

但我的实施工作没有按预期进行。它将所有请求发送到最后一个已注册的处理程序。

需要一些帮助才能完成我的需要。我做错了什么?

1 个答案:

答案 0 :(得分:1)

无论为这两次调用返回Handler实现是什么......

handler.addHandler(AContext.getHandler(server));
handler.addHandler(BContext.getHandler(server));

他们应该有ContextHandler包装它们,因为这是为特定的Handler实现配置和控制虚拟主机的方式。

VirtualHostsExample.java添加到jetty-project/embedded-jetty-cookbook

package org.eclipse.jetty.cookbook;

import java.io.IOException;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.IO;

public class VirtualHostsExample
{
    public static void main(String[] args)
    {
        VirtualHostsExample example = new VirtualHostsExample();
        try
        {
            example.startServer();
            example.testRequest("a.company.com","/hello");
            example.testRequest("b.company.com","/hello");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            example.stopServer();
        }
    }

    private Server server;

    private void stopServer()
    {
        try { server.stop(); }
        catch (Exception ignore) { }
    }

    private void startServer() throws Exception
    {
        server = new Server(8080);
        HandlerCollection handlers = new HandlerCollection();
        server.setHandler(handlers);

        handlers.addHandler(createContext("/", "a.company.com"));
        handlers.addHandler(createContext("/", "b.company.com"));

        server.start();
    }

    private ContextHandler createContext(String contextPath, final String host)
    {
        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath(contextPath);
        @SuppressWarnings("serial")
        ServletHolder helloholder = new ServletHolder(new HttpServlet()
        {
            @Override
            protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
            {
                resp.setContentType("text/plain");
                resp.getWriter().printf("Hello from [%s] context%n",host);
            }
        });
        context.addServlet(helloholder, "/hello");
        context.addServlet(DefaultServlet.class,"/");
        ContextHandler vhwrapper = new ContextHandler();
        vhwrapper.setHandler(context);
        vhwrapper.setVirtualHosts(new String[]{host});
        return vhwrapper;
    }

    private void testRequest(String host, String path)
    {
        try(Socket client = new Socket("localhost",8080);)
        {
            System.out.printf("-- testRequest [%s] [%s] --%n",host,path);
            String req = String.format("GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",path,host);
            System.out.print(req);
            client.getOutputStream().write(req.getBytes(StandardCharsets.UTF_8));
            String response = IO.toString(client.getInputStream());
            System.out.print(response);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

这样的输出......

2016-02-13 08:33:29.142:INFO::main: Logging initialized @130ms
2016-02-13 08:33:29.197:INFO:oejs.Server:main: jetty-9.3.7.v20160115
2016-02-13 08:33:29.221:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@12bb4df8{/,null,AVAILABLE}
2016-02-13 08:33:29.221:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@4cc77c2e{/,null,AVAILABLE,a.company.com}
2016-02-13 08:33:29.221:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@71bc1ae4{/,null,AVAILABLE}
2016-02-13 08:33:29.222:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@6ed3ef1{/,null,AVAILABLE,b.company.com}
2016-02-13 08:33:29.233:INFO:oejs.ServerConnector:main: Started ServerConnector@1babf7a6{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2016-02-13 08:33:29.234:INFO:oejs.Server:main: Started @225ms
-- testRequest [a.company.com] [/hello] --
GET /hello HTTP/1.1
Host: a.company.com
Connection: close

HTTP/1.1 200 OK
Date: Sat, 13 Feb 2016 15:33:29 GMT
Content-Type: text/plain;charset=iso-8859-1
Connection: close
Server: Jetty(9.3.7.v20160115)

Hello from [a.company.com] context
-- testRequest [b.company.com] [/hello] --
GET /hello HTTP/1.1
Host: b.company.com
Connection: close

HTTP/1.1 200 OK
Date: Sat, 13 Feb 2016 15:33:29 GMT
Content-Type: text/plain;charset=iso-8859-1
Connection: close
Server: Jetty(9.3.7.v20160115)

Hello from [b.company.com] context
2016-02-13 08:33:29.340:INFO:oejs.ServerConnector:main: Stopped ServerConnector@1babf7a6{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2016-02-13 08:33:29.342:INFO:oejsh.ContextHandler:main: Stopped o.e.j.s.ServletContextHandler@71bc1ae4{/,null,UNAVAILABLE}
2016-02-13 08:33:29.342:INFO:oejsh.ContextHandler:main: Stopped o.e.j.s.h.ContextHandler@6ed3ef1{/,null,UNAVAILABLE,b.company.com}
2016-02-13 08:33:29.342:INFO:oejsh.ContextHandler:main: Stopped o.e.j.s.ServletContextHandler@12bb4df8{/,null,UNAVAILABLE}
2016-02-13 08:33:29.342:INFO:oejsh.ContextHandler:main: Stopped o.e.j.s.h.ContextHandler@4cc77c2e{/,null,UNAVAILABLE,a.company.com}