2016-11-28 62 views
-1

這裏是我的自定義HttpServlet實現:如何將HttpServlet和WebSocketServlet放入Jetty 9的WAR文件中?

public class AdminServlet extends HttpServlet 
{ 
    @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 Servlet</h1>"); 
    } 
} 

這裏是我的自定義WebSocketServlet實現:

public class WsServlet extends WebSocketServlet { 
    @Override 
    public void configure(WebSocketServletFactory factory) { 
     factory.register(MyListener.class); 
    } 
} 

這裏是WEB-INF/web.xml文件:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app metadata-complete="false" version="3.1" 
     xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> 

    <servlet> 
     <servlet-name>WsServlet</servlet-name> 
     <servlet-class>de.afarber.websockets.WsServlet</servlet-class> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>WsServlet</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <servlet> 
     <servlet-name>AdminServlet</servlet-name> 
     <servlet-class>de.afarber.websockets.AdminServlet</servlet-class> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>AdminServlet</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 
</web-app> 

下面是$JETTY_BASE/webapps/admin.xml文件:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" 
    "http://www.eclipse.org/jetty/configure_9_0.dtd"> 
<Configure class="org.eclipse.jetty.webapp.WebAppContext"> 

    <Set name="contextPath">/admin</Set> 
    <Set name="war"><SystemProperty name="jetty.base"/>/webapps/ws-servlet-0.1-SNAPSHOT.war</Set> 

</Configure> 

最後,這裏是$JETTY_BASE/webapps/ws.xml文件:

<?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" 
     "http://www.eclipse.org/jetty/configure_9_0.dtd"> 
    <Configure class="org.eclipse.jetty.webapp.WebAppContext"> 

     <Set name="contextPath">/ws</Set> 
     <Set name="war"><SystemProperty name="jetty.base"/>/webapps/ws-servlet-0.1-SNAPSHOT.war</Set> 

    </Configure> 

當我開始獨立碼頭9(與deploy和其他模塊有效),我得到錯誤信息:

2016-11-28 09:59:40.994:INFO:oejs.Server:main: jetty-9.3.12.v20160915 
2016-11-28 09:59:41.023:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///C:/Users/U299FAV/slova/jetty.base/webapps/] at interval 1 
2016-11-28 09:59:41.152:INFO:oejsh.ContextHandler:main: Started [email protected]{/words,null,AVAILABLE} 
2016-11-28 09:59:41.165:INFO:oejsh.ContextHandler:main: Started [email protected]{/twentythirteen-child,null,AVAILABLE} 
2016-11-28 09:59:41.950:INFO:oeja.AnnotationConfiguration:main: Scanning elapsed time=307ms 
2016-11-28 09:59:41.970:INFO:oejw.StandardDescriptorProcessor:main: NO JSP Support for /ws, did not find org.eclipse.jetty.jsp.JettyJspServlet 
2016-11-28 09:59:41.992:WARN:oejw.WebAppContext:main: Failed startup of context [email protected]{/ws,file:///C:/Users/U299FAV/AppData/Local/Temp/jetty-0.0.0.0-8080-ws-servlet-0.1-SNAPSHOT.war-_ws-any-239390 
3927144372923.dir/webapp/,UNAVAILABLE}{/ws-servlet-0.1-SNAPSHOT.war} 
java.lang.IllegalStateException: Multiple servlets map to path: /: AdminServlet,WsServlet 
     at org.eclipse.jetty.servlet.ServletHandler.updateMappings(ServletHandler.java:1504) 
     at org.eclipse.jetty.servlet.ServletHandler.doStart(ServletHandler.java:156) 
     at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 
     at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) 
     at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:105) 
     at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) 
     at org.eclipse.jetty.security.SecurityHandler.doStart(SecurityHandler.java:361) 
     at org.eclipse.jetty.security.ConstraintSecurityHandler.doStart(ConstraintSecurityHandler.java:448) 
     at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 
     at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) 
     at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:105) 
     at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) 
     at org.eclipse.jetty.server.handler.ScopedHandler.doStart(ScopedHandler.java:120) 
     at org.eclipse.jetty.server.session.SessionHandler.doStart(SessionHandler.java:116) 
     at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 
     at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) 
     at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:105) 
     at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) 
     at org.eclipse.jetty.server.handler.ScopedHandler.doStart(ScopedHandler.java:120) 
     at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:809) 
     at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:345) 
     at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1404) 
     at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1366) 
     at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:778) 
     at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262) 
     at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:520) 
     at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 
     at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:41) 
     at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:188) 
     at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:499) 
     at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:147) 
     at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:180) 
     at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:458) 
     at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:64) 
     at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:610) 
     at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:529) 
     at org.eclipse.jetty.util.Scanner.scan(Scanner.java:392) 
     at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:313) 
     at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 
     at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:150) 
     at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 
     at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:561) 
     at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:236) 
     at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 
     at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) 
     at org.eclipse.jetty.server.Server.start(Server.java:411) 
     at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:113) 
     at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61) 
     at org.eclipse.jetty.server.Server.doStart(Server.java:378) 
     at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) 
     at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1516) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1441) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at org.eclipse.jetty.start.Main.invokeMain(Main.java:214) 
     at org.eclipse.jetty.start.Main.start(Main.java:457) 
     at org.eclipse.jetty.start.Main.main(Main.java:75) 

我的問題是請:

如何使AdminServletWsServlet共存於同一個WAR文件中?

當我評論其中一個,一切都按預期工作。

回答

1

只需在您的擴展WebSocketServlet中實施doGet方法,畢竟這只是一個正常的使用WebSocket升級知識的HttpServlet

下面是這個工作的例子...

package jetty.websocket; 

import java.io.IOException; 

import javax.servlet.ServletException; 
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.websocket.api.Session; 
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; 
import org.eclipse.jetty.websocket.api.annotations.WebSocket; 
import org.eclipse.jetty.websocket.servlet.WebSocketServlet; 
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; 

public class MultiPurposeServletExample 
{ 
    public static void main(String[] args) 
    { 
     try 
     { 
      Server server = new Server(8080); 

      ServletContextHandler context = new ServletContextHandler(); 
      context.setContextPath("/"); 
      context.addServlet(MultiPurposeServlet.class, "/multi"); 

      server.setHandler(context); 

      server.start(); 
      server.join(); 
     } 
     catch (Throwable t) 
     { 
      t.printStackTrace(); 
     } 
    } 

    @WebSocket 
    public static class MultiPurposeSocket 
    { 
     @OnWebSocketMessage 
     public void onMessage(Session session, String msg) 
     { 
      session.getRemote().sendStringByFuture("'" + msg + "' echo from " + this.getClass().getName()); 
     } 
    } 

    public static class MultiPurposeServlet extends WebSocketServlet 
    { 
     @Override 
     public void configure(WebSocketServletFactory factory) 
     { 
      factory.register(MultiPurposeSocket.class); 
     } 

     @Override 
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
     { 
      resp.setContentType("text/plain"); 
      resp.getWriter().println("Hello from " + this.getClass().getName()); 
     } 
    } 
} 

如果你打這個你得到一個HTTP請求......

$ curl http://localhost:8080/multi 
Hello from jetty.websocket.MultiPurposeServletExample$MultiPurposeServlet 

如果從WebSocket的客戶端連接到它,送你得到一個消息...

'Rock it with HTML5 WebSocket' echo from jetty.websocket.MultiPurposeServletExample$MultiPurposeSocket 

提示:使用http://websocket.org/echo.html和使用的「位置」來測試websocket連接。

1

如果你看看servlet-mapping部分,你的servlets都映射到相同的URL。如果是這樣的話,容器就不知道應該將哪個servlet路由到給定的URL(在你的情況下是/ - root)。

變化<url-pattern>/</url-pattern>的URL的servlet中至少一個的另一個URL,例如,如果你將後者變爲

<servlet-mapping> 
    <servlet-name>AdminServlet</servlet-name> 
    <url-pattern>/AdminServlet</url-pattern> 
</servlet-mapping> 

例如,您的應用程序應該啓動,並在servlets也有,但在不同的網址上。

相關問題