2016-09-10 7 views
2

私はサーブレットでServer(メインメソッドでサーバを起動する)とStartPageServletという2つのクラスを持っています。Jetty:mainメソッドからサーブレットにオブジェクトを渡す

コードの最も重要な部分である:

public class Server { 
    public static void main(String[] args) throws Exception { 
     // some code 

     // I want to pass "anObject" to every Servlet. 
     Object anObject = new Object(); 

     Server server = new Server(4000); 
     ServletContextHandler context = 
      new ServletContextHandler(ServletContextHandler.SESSIONS); 
     context.addServlet(StartPageServlet.class, "/"); 
     // more code 
} 

そしてStartPageServlet:

public class StartPageServlet extends HttpServlet { 

    @Override 
    public void doGet(HttpServletRequest request, 
         HttpServletResponse response) 
      throws ServletException, IOException 
    { 
     // Here I want to access "anObject" 
    } 

私はこれをどのように行うのですか?

+0

必要に応じてサーブレットに 'Object'インスタンスを作成するだけではどうですか?オブジェクトにグローバルな値/メソッドが必要な場合は、 'static'キーワードを使うだけで、インスタンス化する必要はありません。 – Mike

+0

このオブジェクトにはサーブレットで取得できない値が含まれているためです。代わりにグローバルな静的変数がありますが、これがどうなるかは不思議です... – Freddy

答えて

6

ここに埋め込み桟橋は素晴らしいです。

あなたはいくつかの一般的なオプションがあります:追加

  • (任意の値またはオブジェクト型であることができます)、その後ServletHolderを経由して桟橋にそれを引き渡す、サーブレット、使用コンストラクタやセッターの

    1. 直接インスタンス化をそれをメインのServletContextに転送してから、アプリケーションのServletContext(任意の値またはオブジェクトタイプ)にアクセスしてください。

    例:

    package jetty; 
    
    import java.io.IOException; 
    
    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.servlet.ServletContextHandler; 
    import org.eclipse.jetty.servlet.ServletHolder; 
    
    public class ObjectPassingExample 
    { 
        public static void main(String args[]) throws Exception 
        { 
         Server server = new Server(8080); 
    
         ServletContextHandler context = new ServletContextHandler(); 
         context.setContextPath("/"); 
    
         // Option 1: Direct servlet instantiation and ServletHolder 
         HelloServlet hello = new HelloServlet("everyone"); 
         ServletHolder helloHolder = new ServletHolder(hello); 
         context.addServlet(helloHolder, "/hello/*"); 
    
         // Option 2: Using ServletContext attribute 
         context.setAttribute("my.greeting", "you"); 
         context.addServlet(GreetingServlet.class, "/greetings/*"); 
    
         server.setHandler(context); 
         server.start(); 
         server.join(); 
        } 
    
        public static class HelloServlet extends HttpServlet 
        { 
         private final String hello; 
    
         public HelloServlet(String greeting) 
         { 
          this.hello = greeting; 
         } 
    
         @Override 
         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
         { 
          resp.setContentType("text/plain"); 
          resp.getWriter().println("Hello " + this.hello); 
         } 
        } 
    
        public static class GreetingServlet extends HttpServlet 
        { 
         private String greeting; 
    
         @Override 
         public void init() throws ServletException 
         { 
          this.greeting = (String) getServletContext().getAttribute("my.greeting"); 
         } 
    
         @Override 
         protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
         { 
          resp.setContentType("text/plain"); 
          resp.getWriter().println("Greetings to " + this.greeting); 
         } 
        } 
    } 
    
  • +0

    オーバーライドされた 'init'メソッドは完全に機能します!ありがとう。 – Freddy

    1

    シングルトン

    同じ単一インスタンスを各サーブレットに渡したいとしますか?

    Singleton patternを使用して、グローバルに使用できる単一のインスタンスを作成します。

    Javaでこれを行う最も単純な方法は、Enumです。 Oracle Tutorialを参照してください。 this articleと書籍有効Java:プログラミング言語ガイド第2版(ISBN 978-0-321-35668-0,2008)のDr. Joshua Blochを参照してください。

    オブジェクトを渡す必要はありません。各サーブレットは、enumを介して同じ単一のインスタンスにアクセスできます。ウェブアプリ

    パー

    あなたのWebアプリが最初に起動されたときには、そのWebアプリケーション内のすべてのサーブレットがすべての要求を処理した前に、いくつかの作業を行いたい場合は、ServletContextListenerインタフェースを実装するクラスを記述します。

    @WebListenerアノテーションを使用してクラスにマークを付けると、Webコンテナが自動的にインスタンス化されて呼び出されます。

    0

    私は似たような状況があったが(再)突堤コンテナに配備熱い戦争を経て展開されたサーブレットとシングルトンを共有する必要がありました。受け入れられた答えは、サーブレットがデプロイヤーによって管理されたライフサイクルとコンテキストを持っているため、私の場合に必要なものではありませんでした。

    私は、コンテナの寿命の間持続するserverコンテキストにオブジェクトを追加してから、サーブレット内からオブジェクトを取得していました。これにより、親(システム)クラスローダーにオブジェクトのクラスをロードする必要があったため、war webappは独自のクラスローダーにクラスの独自のバージョンをロードしませんでした。キャスト例外の原因となるのはhereです。

    組み込みJettyのサーバコード:

    Server server = new Server(8090); 
    
        // Add all classes related to the object(s) you want to share here. 
        WebAppContext.addSystemClasses(server, "my.package.MyFineClass", ...); 
    
        // Handler config 
        ContextHandlerCollection contexts = new ContextHandlerCollection(); 
        HandlerCollection handlers = new HandlerCollection(); 
        handlers.setHandlers(new Handler[] { contexts }); 
        server.setHandler(handlers); 
    
        // Deployer config (hot deploy) 
        DeploymentManager deployer = new DeploymentManager(); 
        DebugListener debug = new DebugListener(System.err,true,true,true); 
        server.addBean(debug); 
        deployer.addLifeCycleBinding(new DebugListenerBinding(debug)); 
        deployer.setContexts(contexts); 
        deployer.setContextAttribute(
          "org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", 
          ".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$"); 
    
        WebAppProvider webapp_provider = new WebAppProvider(); 
        webapp_provider.setMonitoredDirName("/.../webapps"); 
        webapp_provider.setScanInterval(1); 
        webapp_provider.setExtractWars(true); 
        webapp_provider.setConfigurationManager(new PropertiesConfigurationManager()); 
    
        deployer.addAppProvider(webapp_provider); 
        server.addBean(deployer); 
    
        // Other config... 
    
        // Tuck any objects/data you want into the root server object. 
        server.setAttribute("my.package.MyFineClass", myFineSingleton); 
    
        server.start(); 
        server.join(); 
    

    例サーブレット:サーブレット(SBT)のための私のビルドファイルが "提供" 範囲にmy.package.MyFineClass依存を配置

    public class MyFineServlet extends HttpServlet 
    { 
        MyFineClass myFineSingleton; 
    
        @Override 
        public void init() throws ServletException 
        { 
         // Sneak access to the root server object (non-portable). 
         // Not possible to cast this to `Server` because of classloader restrictions in Jetty. 
         Object server = request.getAttribute("org.eclipse.jetty.server.Server"); 
    
         // Because we cannot cast to `Server`, use reflection to access the object we tucked away there. 
         try { 
          myFineSingleton = (MyFineClass) server.getClass().getMethod("getAttribute", String.class).invoke(server, "my.package.MyFineClass"); 
         } catch (Exception ex) { 
          throw new ServletException("Unable to reflect MyFineClass instance via Jetty Server", ex); 
         } 
        } 
    
        @Override 
        protected void doGet(HttpServletRequest request, 
          HttpServletResponse response) throws ServletException, IOException 
        { 
         response.setContentType("text/html"); 
         response.setStatus(HttpServletResponse.SC_OK); 
         response.getWriter().println("<h1>Hello from MyFineServlet</h1>"); 
         response.getWriter().println("Here's: " + myFineSingleton.toString()); 
        } 
    } 
    

    そうすでにJettyサーバーにロードされているので、戦争にパッケージ化されません。

    関連する問題