2016-02-12 73 views
1

詳細信息, 我使用一個單一的碼頭服務器通過Java嵌入,將處理多個請求。我正在用guice注入事件監聽器和安全過濾器。但我需要服務器servlet的請求domian。我嘗試使用虛擬主機,但由於我沒有使用基於xml的配置,因此沒有太多文檔可以獲得幫助。嵌入式jetty和guice處理程序servlet根據請求域(虛擬主機)

,所以我想是 -

如果域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()); 
} 

Listener類

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方法。

但是我的執行沒有按預期工作。它將所有請求發送到註冊的最後處理程序。

需要一些幫助來完成我所需要的。我做錯事的地方在哪裏?

回答

1

無論Handler實現返回這兩個電話...

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

他們應該有一個包裹ContextHandler他們,因爲這是主機如何虛擬配置和控制特定處理程序實現。

增加VirtualHostsExample.javajetty-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 [email protected]{/,null,AVAILABLE} 
2016-02-13 08:33:29.221:INFO:oejsh.ContextHandler:main: Started [email protected]{/,null,AVAILABLE,a.company.com} 
2016-02-13 08:33:29.221:INFO:oejsh.ContextHandler:main: Started [email protected]{/,null,AVAILABLE} 
2016-02-13 08:33:29.222:INFO:oejsh.ContextHandler:main: Started [email protected]{/,null,AVAILABLE,b.company.com} 
2016-02-13 08:33:29.233:INFO:oejs.ServerConnector:main: Started [email protected]babf7a6{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 [email protected]{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} 
2016-02-13 08:33:29.342:INFO:oejsh.ContextHandler:main: Stopped [email protected]{/,null,UNAVAILABLE} 
2016-02-13 08:33:29.342:INFO:oejsh.ContextHandler:main: Stopped [email protected]{/,null,UNAVAILABLE,b.company.com} 
2016-02-13 08:33:29.342:INFO:oejsh.ContextHandler:main: Stopped [email protected]{/,null,UNAVAILABLE} 
2016-02-13 08:33:29.342:INFO:oejsh.ContextHandler:main: Stopped [email protected]{/,null,UNAVAILABLE,a.company.com} 
+0

AContext.getHandler(服務器)返回第一限定的ServletContextHandler。這不夠嗎? HOST是一個格式化爲a.test.com的字符串,我想處理它。如果AServlet的overriden方法需要設置request.setHandled(true)? – sadlil

+0

看起來像這不工作。 ContextHandler vhwrapper = new ContextHandler(handler); – sadlil

+0

用上下文處理程序不工作來包裝ServletContextHandler。仍然是註冊的最後一個人收到了請求。 – sadlil