org.atmosphere.cpr.AtmosphereMappingException 在 Spring 引导可执行文件 war 文件中
org.atmosphere.cpr.AtmosphereMappingException in Spring Boot executable war file
我有一个 Spring 引导应用程序,我在其中集成了 Atmosphere Framework.
这是 Application.java
文件:
package com.myproject.something;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.core.env.SimpleCommandLinePropertySource;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
addDefaultProfile(app, new SimpleCommandLinePropertySource(args));
app.run(args);
}
private static void addDefaultProfile(SpringApplication app, SimpleCommandLinePropertySource source) {
if (!source.containsProperty("spring.profiles.active")
&& !System.getenv().containsKey("SPRING_PROFILES_ACTIVE")) {
app.setAdditionalProfiles("dev");
}
}
}
为了将 Atmosphere Framework 集成 到我的 Spring 引导应用程序中,我一直在松散地关注 this resource combining elements from the official Atmosphere Documentation。
我最终得到了 类 MyAtmosphereConfig.java
和 MyAtmosphereManagedService.java
:
package com.myproject.something.atmosphere;
import java.util.Collections;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.atmosphere.cpr.AtmosphereServlet;
import org.atmosphere.cpr.ContainerInitializer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@Configuration
public class MyAtmosphereConfig {
@Bean
public EmbeddedAtmosphereInitializer atmosphereInitializer() {
return new EmbeddedAtmosphereInitializer();
}
@Bean
public ServletRegistrationBean atmosphereServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(new AtmosphereServlet(), "/myAtmosphereUrl");
registration.addInitParameter("org.atmosphere.cpr.packages", "com.myproject.something.atmosphere");
registration.setLoadOnStartup(1);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registration;
}
private static class EmbeddedAtmosphereInitializer extends ContainerInitializer
implements ServletContextInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
onStartup(Collections.<Class<?>>emptySet(), servletContext);
}
}
}
package com.myproject.something.atmosphere;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Inject;
import org.atmosphere.config.service.Disconnect;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Ready;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceFactory;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ManagedService(path = "/myAtmosphereUrl")
public class MyAtmosphereManagedService {
private final Logger log = LoggerFactory.getLogger(MyAtmosphereManagedService.class);
@Inject
public static AtmosphereResourceFactory factory;
@Inject
public AtmosphereResource resource;
@Ready
public void onReady() throws JSONException {
String atmosJSessionId = resource.getRequest().getRequestedSessionId();
log.info("Initiating Atmosphere client connection with jsession = " + atmosJSessionId);
}
@Disconnect
public void onDisconnect() {
String atmosJSessionId = resource.getRequest().getRequestedSessionId();
log.info("Unregistering Atmosphere client connection with jsession = " + atmosJSessionId);
}
}
我一直在 Eclipse IDE 中开发,将我的 Spring 引导应用程序作为 Java 应用程序执行。 (右键单击 Application.java -> 运行 As -> Java Application)
运行按照上述方式将其设置为来自 Eclipse IDE 的 Java 应用程序- 前面-我的应用程序的结束部分可以 成功访问 Atmosphere Framework 公开的 URL ,如下所示:
(function() {
'use strict';
setTimeout(function() {
// Setup Atmosphere client
var myAtmosphereUrl = 'http://localhost:8080/myAtmosphereUrl';
var socket = atmosphere;
var subSocket;
var transport = 'sse';
var request = {
url : myAtmosphereUrl,
contentType : "application/json",
logLevel : 'debug',
transport : transport,
trackMessageLength : true,
reconnectInterval : 5000
};
request.onOpen = function(response) {
transport = response.transport;
request.uuid = response.request.uuid;
console.log("onOpen called!");
};
request.onMessage = function(response) {
transport = response.transport;
request.uuid = response.request.uuid;
console.log("onMessage called!");
};
subSocket = socket.subscribe(request);
}, 1000);
})();
在 浏览器控制台 的前端,我看到 HTTP 200
状态代码,在 Eclipse IDE 的后端] 控制台 ,它给我日志消息 Initiating Atmosphere client connection with jsession = A4A8790C27D531FE7B2CD82B5B9C9447
。
不幸的是,在打包我的项目到可执行war文件并将其作为服务部署在Debian服务器上之后,它不再工作了,在后端的日志中留下一条错误消息:
2017-10-16 10:51:11.143 ERROR 21296 --- [http-nio-8080-exec-2] o.atmosphere.cpr.AsynchronousProcessor : No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @___Service
2017-10-16 10:51:11.146 ERROR 21296 --- [http-nio-8080-exec-2] o.a.c.c.C.[.[.[/].[atmosphereServlet] : Servlet.service() for servlet [atmosphereServlet] in context with path [] threw exception
org.atmosphere.cpr.AtmosphereMappingException: No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @___Service
at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:147) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:115) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:68) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2287) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:191) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.cpr.AtmosphereServlet.doGet(AtmosphereServlet.java:177) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) ~[spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:105) ~[spring-boot-actuator-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
...
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:107) ~[spring-boot-actuator-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:677) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]
浏览器控制台给了我一个 HTTP 500 - Internal Server Error
状态码。
可执行文件war的创建由Maven命令maven package
触发,并以这种方式在pom.xml
中配置:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myproject</groupId>
<artifactId>something</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>MySomething</name>
<description>My Something Description</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
...
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-core</artifactId>
<version>2.6.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-spring</artifactId>
<version>2.4.4</version>
</dependency>
</dependencies>
</project>
我已经尝试将 atmosphere.xml
文件放入 war 文件 的 WEB-INF
文件夹中,但似乎仍然未拾取带有 @ManagedService
注释的 Servlet。
这是atmosphere.xml
的内容,没有解决错误:
<atmosphere-handlers>
<atmosphere-handler support-session="true"
context-root="/"
broadcaster="org.atmosphere.cpr.DefaultBroadcaster"
class-name="com.myproject.something.atmosphere.MyAtmosphereManagedService">
</atmosphere-handler>
</atmosphere-handlers>
谁能告诉我我的配置有什么问题,或者这可能是与嵌入式 Tomcat、Atmosphere 和 Spring Boot 的次要版本相关的错误?
编辑:
可以通过克隆 official Atmosphere-Spring-Boot Sample project 并更改 pom.xml
将项目打包到 war
文件来重现此错误:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.atmosphere.samples</groupId>
<artifactId>atmosphere-samples</artifactId>
<version>2.5.0-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-atmosphere</artifactId>
<name>Spring Boot Atmosphere Sample</name>
<description>Spring Boot Atmosphere Sample</description>
<url>http://projects.spring.io/spring-boot/</url>
<packaging>war</packaging>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot-version}</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>${atmosphere-version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>atmosphere-javascript</artifactId>
<version>2.2.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot-version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
我找到了两个修复程序。
第一次修复:
1. 将 pom.xml
中的 Spring 引导版本更改为:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
</parent>
2。完成!
第二次修复:(如果不能更改版本)
- 将您的项目打包成一个
jar
文件,然后@ManagedServices
被识别。
注意:您可能需要在打包前将静态文件(js和html)复制到您的pom.xml
中。
如果您正在使用 Spring boot 2 然后使用下面的配置测试。
@Bean
public ServletRegistrationBean < HttpServlet > PushServlet() {
ServletRegistrationBean pushServlet = new ServletRegistrationBean(new org.primefaces.push.PushServlet(), "/primepush/*");
pushServlet.addInitParameter("org.atmosphere.annotation.packages", "org.primefaces.push");
pushServlet.addInitParameter("org.atmosphere.cpr.packages", "com.ik");
pushServlet.setAsyncSupported(true);
pushServlet.setLoadOnStartup(0);
pushServlet.setOrder(Ordered.HIGHEST_PRECEDENCE);
return pushServlet;
}
com.ik
是你的工程包名,就是scan
我有一个 Spring 引导应用程序,我在其中集成了 Atmosphere Framework.
这是 Application.java
文件:
package com.myproject.something;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.core.env.SimpleCommandLinePropertySource;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
addDefaultProfile(app, new SimpleCommandLinePropertySource(args));
app.run(args);
}
private static void addDefaultProfile(SpringApplication app, SimpleCommandLinePropertySource source) {
if (!source.containsProperty("spring.profiles.active")
&& !System.getenv().containsKey("SPRING_PROFILES_ACTIVE")) {
app.setAdditionalProfiles("dev");
}
}
}
为了将 Atmosphere Framework 集成 到我的 Spring 引导应用程序中,我一直在松散地关注 this resource combining elements from the official Atmosphere Documentation。
我最终得到了 类 MyAtmosphereConfig.java
和 MyAtmosphereManagedService.java
:
package com.myproject.something.atmosphere;
import java.util.Collections;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.atmosphere.cpr.AtmosphereServlet;
import org.atmosphere.cpr.ContainerInitializer;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@Configuration
public class MyAtmosphereConfig {
@Bean
public EmbeddedAtmosphereInitializer atmosphereInitializer() {
return new EmbeddedAtmosphereInitializer();
}
@Bean
public ServletRegistrationBean atmosphereServlet() {
ServletRegistrationBean registration = new ServletRegistrationBean(new AtmosphereServlet(), "/myAtmosphereUrl");
registration.addInitParameter("org.atmosphere.cpr.packages", "com.myproject.something.atmosphere");
registration.setLoadOnStartup(1);
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
return registration;
}
private static class EmbeddedAtmosphereInitializer extends ContainerInitializer
implements ServletContextInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
onStartup(Collections.<Class<?>>emptySet(), servletContext);
}
}
}
package com.myproject.something.atmosphere;
import java.util.concurrent.ConcurrentHashMap;
import javax.inject.Inject;
import org.atmosphere.config.service.Disconnect;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Ready;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceFactory;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ManagedService(path = "/myAtmosphereUrl")
public class MyAtmosphereManagedService {
private final Logger log = LoggerFactory.getLogger(MyAtmosphereManagedService.class);
@Inject
public static AtmosphereResourceFactory factory;
@Inject
public AtmosphereResource resource;
@Ready
public void onReady() throws JSONException {
String atmosJSessionId = resource.getRequest().getRequestedSessionId();
log.info("Initiating Atmosphere client connection with jsession = " + atmosJSessionId);
}
@Disconnect
public void onDisconnect() {
String atmosJSessionId = resource.getRequest().getRequestedSessionId();
log.info("Unregistering Atmosphere client connection with jsession = " + atmosJSessionId);
}
}
我一直在 Eclipse IDE 中开发,将我的 Spring 引导应用程序作为 Java 应用程序执行。 (右键单击 Application.java -> 运行 As -> Java Application)
运行按照上述方式将其设置为来自 Eclipse IDE 的 Java 应用程序- 前面-我的应用程序的结束部分可以 成功访问 Atmosphere Framework 公开的 URL ,如下所示:
(function() {
'use strict';
setTimeout(function() {
// Setup Atmosphere client
var myAtmosphereUrl = 'http://localhost:8080/myAtmosphereUrl';
var socket = atmosphere;
var subSocket;
var transport = 'sse';
var request = {
url : myAtmosphereUrl,
contentType : "application/json",
logLevel : 'debug',
transport : transport,
trackMessageLength : true,
reconnectInterval : 5000
};
request.onOpen = function(response) {
transport = response.transport;
request.uuid = response.request.uuid;
console.log("onOpen called!");
};
request.onMessage = function(response) {
transport = response.transport;
request.uuid = response.request.uuid;
console.log("onMessage called!");
};
subSocket = socket.subscribe(request);
}, 1000);
})();
在 浏览器控制台 的前端,我看到 HTTP 200
状态代码,在 Eclipse IDE 的后端] 控制台 ,它给我日志消息 Initiating Atmosphere client connection with jsession = A4A8790C27D531FE7B2CD82B5B9C9447
。
不幸的是,在打包我的项目到可执行war文件并将其作为服务部署在Debian服务器上之后,它不再工作了,在后端的日志中留下一条错误消息:
2017-10-16 10:51:11.143 ERROR 21296 --- [http-nio-8080-exec-2] o.atmosphere.cpr.AsynchronousProcessor : No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @___Service
2017-10-16 10:51:11.146 ERROR 21296 --- [http-nio-8080-exec-2] o.a.c.c.C.[.[.[/].[atmosphereServlet] : Servlet.service() for servlet [atmosphereServlet] in context with path [] threw exception
org.atmosphere.cpr.AtmosphereMappingException: No AtmosphereHandler found. Make sure you define it inside WEB-INF/atmosphere.xml or annotate using @___Service
at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:147) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:115) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:68) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2287) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.cpr.AtmosphereServlet.doPost(AtmosphereServlet.java:191) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at org.atmosphere.cpr.AtmosphereServlet.doGet(AtmosphereServlet.java:177) ~[atmosphere-runtime-2.4.5.jar!/:2.4.5]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-embed-websocket-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) ~[spring-boot-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:105) ~[spring-boot-actuator-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
...
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:89) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:107) ~[spring-boot-actuator-1.4.1.RELEASE.jar!/:1.4.1.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.3.3.RELEASE.jar!/:4.3.3.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) ~[tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:677) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_111]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_111]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.5.jar!/:8.5.5]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]
浏览器控制台给了我一个 HTTP 500 - Internal Server Error
状态码。
可执行文件war的创建由Maven命令maven package
触发,并以这种方式在pom.xml
中配置:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myproject</groupId>
<artifactId>something</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>MySomething</name>
<description>My Something Description</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
...
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-rest-core</artifactId>
<version>2.6.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-spring</artifactId>
<version>2.4.4</version>
</dependency>
</dependencies>
</project>
我已经尝试将 atmosphere.xml
文件放入 war 文件 的 WEB-INF
文件夹中,但似乎仍然未拾取带有 @ManagedService
注释的 Servlet。
这是atmosphere.xml
的内容,没有解决错误:
<atmosphere-handlers>
<atmosphere-handler support-session="true"
context-root="/"
broadcaster="org.atmosphere.cpr.DefaultBroadcaster"
class-name="com.myproject.something.atmosphere.MyAtmosphereManagedService">
</atmosphere-handler>
</atmosphere-handlers>
谁能告诉我我的配置有什么问题,或者这可能是与嵌入式 Tomcat、Atmosphere 和 Spring Boot 的次要版本相关的错误?
编辑:
可以通过克隆 official Atmosphere-Spring-Boot Sample project 并更改 pom.xml
将项目打包到 war
文件来重现此错误:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.atmosphere.samples</groupId>
<artifactId>atmosphere-samples</artifactId>
<version>2.5.0-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-sample-atmosphere</artifactId>
<name>Spring Boot Atmosphere Sample</name>
<description>Spring Boot Atmosphere Sample</description>
<url>http://projects.spring.io/spring-boot/</url>
<packaging>war</packaging>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot-version}</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>${atmosphere-version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>atmosphere-javascript</artifactId>
<version>2.2.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot-version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
我找到了两个修复程序。
第一次修复:
1. 将 pom.xml
中的 Spring 引导版本更改为:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
</parent>
2。完成!
第二次修复:(如果不能更改版本)
- 将您的项目打包成一个
jar
文件,然后@ManagedServices
被识别。
注意:您可能需要在打包前将静态文件(js和html)复制到您的pom.xml
中。
如果您正在使用 Spring boot 2 然后使用下面的配置测试。
@Bean
public ServletRegistrationBean < HttpServlet > PushServlet() {
ServletRegistrationBean pushServlet = new ServletRegistrationBean(new org.primefaces.push.PushServlet(), "/primepush/*");
pushServlet.addInitParameter("org.atmosphere.annotation.packages", "org.primefaces.push");
pushServlet.addInitParameter("org.atmosphere.cpr.packages", "com.ik");
pushServlet.setAsyncSupported(true);
pushServlet.setLoadOnStartup(0);
pushServlet.setOrder(Ordered.HIGHEST_PRECEDENCE);
return pushServlet;
}
com.ik
是你的工程包名,就是scan