我有一个由@ManagedService注释的类,它没有被调用。 Servlet容器是Jetty9.2.3.v20140905,大气运行时2.3.1,AtomsphereServlet。 AtmosphereServlet已成功加载,浏览器端请求可以到达AtmosphereServlet,但不会调用带注释的类。 警告是服务器端:
WARN org.atmosphere.websocket.DefaultWebSocketProcessor - No AtmosphereHandler or WebSocketHandler installed. Adding a default one.
这是Jetty web.xml中的配置
<servlet>
<description>AtmosphereServlet</description>
<servlet-name>AtmosphereServlet</servlet-name>
<servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
<!-- List of init-param -->
<init-param>
<param-name>org.atmosphere.cpr.broadcaster.shareableThreadPool</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcaster.maxProcessingThreads</param-name>
<param-value>10</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcaster.maxAsyncWriteThreads</param-name>
<param-value>10</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!-- If you want to use Servlet 3.0 -->
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>AtmosphereServlet</servlet-name>
<!-- Any mapping -->
<url-pattern>/pusher/*</url-pattern>
</servlet-mapping>
以下是代码:此处不使用断点:
@ManagedService(path = "/test")
public class SubscribeRequest {
private Logger log = Logger.getLogger(this.getClass().getName());
@Get
public void onGet(AtmosphereResource r) {
String channel=r.getRequest().getParameter("channel");
if(channel == null) {
return;
}
if(channel.startsWith("/project/")) {
BroadcasterFactory f = r.getAtmosphereConfig().getBroadcasterFactory();
f.lookup(channel, true).addAtmosphereResource(r);
log.log(Level.INFO, "Subscribe for " + channel + "\n");
r.suspend();
}else{
//not support other channel yet
log.log(Level.INFO, "Subscribe for NOT-SUPPORT channel:" + channel + "\n");
}
}
@Message
public String onMessage(AtmosphereResource r, String message) throws IOException {
log.log(Level.INFO,message);
return message;
}
}
这里是JS请求:
var request = {
url: '/pusher/test?channel=/project/201',
contentType: 'application/json',
logLevel: 'debug',
transport: 'websocket',
trackMessageLength: true,
reconnectInterval: 5000,
enableXDR: true,
timeout: 60000
};
我使用嵌入式jetty,这是startjetty的功能:
private void startJetty(String workingDir, String baseDir, String configDir, String contextPath, String warFile) throws Exception {
Server server = new Server();
.....
WebAppContext webapp = new WebAppContext();
webapp.setContextPath(contextPath);
if(runInsideIntelliJ) { // Allows running/debugging from within e.g. IntelliJ
log.fine("Running project from inside IDE environment. Running directly from source web files.");
webapp.setWar(workingDir+"/web/src/main/webapp/");
String extraClasspath = workingDir + "/web/target/classes/";
extraClasspath += ";" + new String(Files.readAllBytes(Paths.get(workingDir + "/web/web.debug.classpath")));
webapp.setExtraClasspath(extraClasspath);
webapp.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");
webapp.addFilter("com.teb.web.CorsDebugFilter", "/protected/rest/*", EnumSet.allOf(DispatcherType.class));
} else {
webapp.setWar(warFile);
}
ServletHolder defaultServlet = new ServletHolder(DefaultServlet.class);
defaultServlet.setInitParameter("cacheControl", "max-age=0,public");
defaultServlet.setName("default");
webapp.addServlet(defaultServlet, "/");
org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");
webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");
HandlerCollection handlers = new HandlerCollection();
RequestLogHandler requestLogHandler = new RequestLogHandler();
handlers.setHandlers(new Handler[]{webapp, /*rootContextHandler,*/ requestLogHandler});
server.setHandler(handlers);
...
// Start the server
server.start();
server.join();
}
这是Atmosphere框架启动打印日志,它看起来已经扫描了带注释的托管服务类:
2015-05-16 00:04:33,954 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using org.atmosphere.cpr.DefaultAnnotationProcessor for processing annotation
2015-05-16 00:04:33,955 [main] INFO org.atmosphere.cpr.DefaultAnnotationProcessor - AnnotationProcessor class org.atmosphere.cpr.DefaultAnnotationProcessor$ServletContainerInitializerAnnotationProcessor being used
2015-05-16 00:04:33,956 [main] WARN org.atmosphere.cpr.DefaultAnnotationProcessor - Unable to detect annotations. Application may fail to deploy.
2015-05-16 00:04:33,957 [main] INFO org.atmosphere.cpr.AnnotationHandler - Found Annotation in class com.teb.ea.web.webpush.SubscribeRequest being scanned: interface org.atmosphere.config.service.ManagedService
2015-05-16 00:04:33,959 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Auto detecting atmosphere handlers /WEB-INF/classes/
2015-05-16 00:04:33,960 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Auto detecting WebSocketHandler in /WEB-INF/classes/
2015-05-16 00:04:33,963 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed WebSocketProtocol org.atmosphere.websocket.protocol.SimpleHttpProtocol
2015-05-16 00:04:34,003 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installing Default AtmosphereInterceptors
2015-05-16 00:04:34,004 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.CorsInterceptor : CORS Interceptor Support
2015-05-16 00:04:34,005 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.CacheHeadersInterceptor : Default Response's Headers Interceptor
2015-05-16 00:04:34,006 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.PaddingAtmosphereInterceptor : Browser Padding Interceptor Support
2015-05-16 00:04:34,007 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.AndroidAtmosphereInterceptor : Android Interceptor Support
2015-05-16 00:04:34,009 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.HeartbeatInterceptor : Heartbeat Interceptor Support
2015-05-16 00:04:34,010 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.SSEAtmosphereInterceptor : SSE Interceptor Support
2015-05-16 00:04:34,011 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.JSONPAtmosphereInterceptor : JSONP Interceptor Support
2015-05-16 00:04:34,012 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.JavaScriptProtocol : Atmosphere JavaScript Protocol
2015-05-16 00:04:34,012 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.WebSocketMessageSuspendInterceptor : org.atmosphere.interceptor.WebSocketMessageSuspendInterceptor
2015-05-16 00:04:34,013 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.OnDisconnectInterceptor : Browser disconnection detection
2015-05-16 00:04:34,013 [main] INFO org.atmosphere.cpr.AtmosphereFramework - org.atmosphere.interceptor.IdleResourceInterceptor : org.atmosphere.interceptor.IdleResourceInterceptor
2015-05-16 00:04:34,013 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Set org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults to disable them.
2015-05-16 00:04:34,014 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor CORS Interceptor Support with priority FIRST_BEFORE_DEFAULT
2015-05-16 00:04:34,015 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Default Response's Headers Interceptor with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Browser Padding Interceptor Support with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Android Interceptor Support with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.interceptor.HeartbeatInterceptor - HeartbeatInterceptor configured with padding value 'X', client frequency 60 seconds and server frequency 0 seconds
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Heartbeat Interceptor Support with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor SSE Interceptor Support with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor JSONP Interceptor Support with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Atmosphere JavaScript Protocol with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor org.atmosphere.interceptor.WebSocketMessageSuspendInterceptor with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor Browser disconnection detection with priority AFTER_DEFAULT
2015-05-16 00:04:34,016 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Installed AtmosphereInterceptor org.atmosphere.interceptor.IdleResourceInterceptor with priority BEFORE_DEFAULT
2015-05-16 00:04:34,017 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Using EndpointMapper class org.atmosphere.util.DefaultEndpointMapper
2015-05-16 00:04:34,017 [main] WARN org.atmosphere.cpr.AtmosphereFramework - No BroadcasterCache configured. Broadcasted message between client reconnection will be LOST. It is recommended to configure the org.atmosphere.cache.UUIDBroadcasterCache
2015-05-16 00:04:34,017 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Default Broadcaster Class: org.atmosphere.cpr.DefaultBroadcaster
2015-05-16 00:04:34,017 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Broadcaster Shared List Resources: false
2015-05-16 00:04:34,017 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Broadcaster Polling Wait Time 100
2015-05-16 00:04:34,017 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Shared ExecutorService supported: true
2015-05-16 00:04:34,018 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Messaging Thread Pool Size: 10
2015-05-16 00:04:34,018 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Async I/O Thread Pool Size: 10
2015-05-16 00:04:34,018 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Using BroadcasterFactory: org.atmosphere.cpr.DefaultBroadcasterFactory
2015-05-16 00:04:34,018 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Using AtmosphereResurceFactory: org.atmosphere.cpr.DefaultAtmosphereResourceFactory
2015-05-16 00:04:34,018 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Using WebSocketProcessor: org.atmosphere.websocket.DefaultWebSocketProcessor
2015-05-16 00:04:34,018 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Invoke AtmosphereInterceptor on WebSocket message true
2015-05-16 00:04:34,019 [main] INFO org.atmosphere.cpr.AtmosphereFramework - HttpSession supported: false
2015-05-16 00:04:34,019 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using org.atmosphere.inject.InjectableObjectFactory for dependency injection and object creation
2015-05-16 00:04:34,019 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Atmosphere is using async support: org.atmosphere.container.Jetty9AsyncSupportWithWebSocket running under container: jetty/9.2.3.v20140905 with WebSocket enabled.
2015-05-16 00:04:34,020 [main] INFO org.atmosphere.cpr.AtmosphereFramework - Atmosphere Framework 2.3.1 started.
2015-05-16 00:04:34,020 [main] INFO org.atmosphere.cpr.AtmosphereFramework -
到目前为止,尝试了以下内容:
1 add the follow init-param
<init-param>
<param-name>org.atmosphere.cpr.packages</param-name>
<param-value>com.mobilaris.ea.web.webpush</param-value>
</init-param>
2 set annotated class path same as servlet mapping in web.xml, it is /pusher/test
3用AtmosphereHandler替换@ManagedService,得到 同样的警告和我的处理程序没有被调用。它与managedservice注释完全相同。
奇怪的是客户端请求没有调用我的带注释的类,但websocket仍然连接成功打印在浏览器控制台中。在wireshark中也证明了,websocket连接确实建立了。看起来Atmosphere框架正在使用默认的东西来处理请求并建立我不想拥有的websocket连接,我希望请求应该在我的注释类中进行控制,以便我的类(在onready / on上) get)可以检查并决定是否conn。
这是浏览器端控制台日志:
atmosphere.js:3221 Invoking executeWebSocket
atmosphere.js:3221 Using URL: ws://localhost:9999/pusher/test?channel=201&X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.2.11-javascript&X-Atmosphere-Transport=websocket&X-Atmosphere-TrackMessageSize=true&Content-Type=application/json&X-atmo-protocol=true
...
atmosphere.js:3221 Sat May 16 2015 08:03:50 GMT+0200 (CEST) Atmosphere: websocket.onopen
atmosphere.js:3221 Websocket successfully opened
...
atmosphere.js:3221 Sat May 16 2015 08:04:50 GMT+0200 (CEST) Atmosphere: Firing closedByClient
angular-1.3.14.js:11607 ReferenceError: author is not defined
at Object.request.onClientTimeout (http://localhost:9999/authedfolder/js/my.js:41:57)
at http://spyboost.github.io/angular-atmosphere/service/angular-atmosphere-service.js:16:30
at Scope.$get.Scope.$eval (http://localhost:9999/authedfolder/components/angularjs/angular-1.3.14.js:14401:28)
at Scope.$get.Scope.$apply (http://localhost:9999/authedfolder/components/angularjs/angular-1.3.14.js:14500:23)
at Object.subscribe.angular.forEach.result.(anonymous function) [as onClientTimeout] (http://spyboost.github.io/angular-atmosphere/service/angular-atmosphere-service.js:15:28)
at _f (http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:2767:31)
at _invokeFunction (http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:2721:17)
at _invokeCallback (http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:2850:21)
at _onClientTimeout (http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:1636:17)
at http://localhost:9999/authedfolder/components/atmosphere/atmosphere.js:1623:25(anonymous function) @ angular-1.3.14.js:11607$get @ angular-1.3.14.js:8557$get.Scope.$apply @ angular-1.3.14.js:14502subscribe.angular.forEach.result.(anonymous function) @ angular-atmosphere-service.js:15_f @ atmosphere.js:2767_invokeFunction @ atmosphere.js:2721_invokeCallback @ atmosphere.js:2850_onClientTimeout @ atmosphere.js:1636(anonymous function) @ atmosphere.js:1623
atmosphere.js:3221 Sat May 16 2015 08:04:50 GMT+0200 (CEST) Atmosphere: Firing closedByClient
atmosphere.js:3221 Sat May 16 2015 08:04:50 GMT+0200 (CEST) Atmosphere: websocket.onclose
atmosphere.js:3221 Websocket closed, reason: Unknown: no status code was provided even though one was expected.
atmosphere.js:3221 Websocket closed, wasClean: true
答案 0 :(得分:2)
最后找到原因和解决方案。
根本原因:
atmosphere-runtime.jar不在WEB-INF / lib文件夹中。 如果通过在web应用程序pom中添加依赖项将它放入WEB-INF / lib文件夹没有任何问题,那就去做吧。
在我的情况下,我得到了“slf4j java.lang.LinkageError加载器约束违规”,因为两个pom模块(其中一个是webapp模块)都将氛围依赖放在他们的pom文件中。然后Jetty类加载器和默认的类加载器都加载了氛围类。
解决方案:
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
如果您仍想将amb-runtime.jar保留在除WEB-INF / lib之外的其他文件夹中,您可以将以下内容添加到您的web.xml中,它会调用我的带注释的类,但我不确定它是否合适溶液
<init-param>
<param-name>org.atmosphere.cpr.AtmosphereHandler</param-name>
<param-value>com.teb.web.webpush.SubscribeRequest</param-value>
</init-param>
答案 1 :(得分:0)
您是否正在使用Jetty 9嵌入式界面?无论如何只需添加你的web.xml
<init-param>
<param-name>org.atmosphere.cpr.packages</param-name>
<param-value>your package name</param-value>
</init-param>
并确保您的班级定义一个包: - )