如何将 HttpServlet 和 WebSocketServlet 放在 Jetty 9 的同一个 WAR 文件中?
How to put HttpServlet and WebSocketServlet in same WAR file for Jetty 9?
这是我的自定义 HttpServlet
实现:
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>
当我启动独立的 Jetty 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 o.e.j.s.h.ContextHandler@783e6358{/words,null,AVAILABLE}
2016-11-28 09:59:41.165:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@7dc7cbad{/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 o.e.j.w.WebAppContext@5f2108b5{/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.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.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)
我的问题是:
如何使 AdminServlet
和 WsServlet
在同一个 WAR 文件中共存?
当我评论两者之一时,一切都按预期工作。
如果您查看 servlet-mapping
部分,您的两个 servlet 都映射到相同的 URL。如果是这样,容器就不知道应该将您的请求路由到给定 URL(在您的情况下为 / - root)的哪个 servlet。
将 <url-pattern>/</url-pattern>
的 URL 更改为至少一个 servlet 的另一个 URL,例如,如果您将后者更改为
<servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/AdminServlet</url-pattern>
</servlet-mapping>
例如,您的应用程序应该启动并且两个 servlet 都可用,但在不同的 URLs 上。
在你的扩展WebSocketServlet
中实现doGet
方法即可,毕竟只是一个普通的HttpServlet
,有WebSocket升级知识。
这是一个工作示例...
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并使用ws://localhost:8080/multi
的"Location"来测试websocket连接。
这是我的自定义 HttpServlet
实现:
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>
当我启动独立的 Jetty 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 o.e.j.s.h.ContextHandler@783e6358{/words,null,AVAILABLE}
2016-11-28 09:59:41.165:INFO:oejsh.ContextHandler:main: Started o.e.j.s.h.ContextHandler@7dc7cbad{/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 o.e.j.w.WebAppContext@5f2108b5{/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.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.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)
我的问题是:
如何使 AdminServlet
和 WsServlet
在同一个 WAR 文件中共存?
当我评论两者之一时,一切都按预期工作。
如果您查看 servlet-mapping
部分,您的两个 servlet 都映射到相同的 URL。如果是这样,容器就不知道应该将您的请求路由到给定 URL(在您的情况下为 / - root)的哪个 servlet。
将 <url-pattern>/</url-pattern>
的 URL 更改为至少一个 servlet 的另一个 URL,例如,如果您将后者更改为
<servlet-mapping>
<servlet-name>AdminServlet</servlet-name>
<url-pattern>/AdminServlet</url-pattern>
</servlet-mapping>
例如,您的应用程序应该启动并且两个 servlet 都可用,但在不同的 URLs 上。
在你的扩展WebSocketServlet
中实现doGet
方法即可,毕竟只是一个普通的HttpServlet
,有WebSocket升级知识。
这是一个工作示例...
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并使用ws://localhost:8080/multi
的"Location"来测试websocket连接。