我有一个使用spring来设置上下文的JAX应用程序。
我已经设置了一个AppConfig来处理这个...就像这样。
@Configuration
@ComponentScan("com.whatever")
public class AppConfig {... //etc
但是,我一直收到错误,因为应用程序正在寻找applicationContext.xml
。
org.springframework.beans.factory.BeanDefinitionStoreException:
IOException parsing XML document from class path resource [applicationContext.xml];
我相信我必须对我的web.xml文件做些什么...但我无法弄明白。这是我的web.xml
<web-app version="3.1" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd">
<listener>
<listener-class>com.whatever.etc.ApplicationListener</listener-class>
</listener>
<!-- Application -->
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>
io.swagger.jaxrs.listing,
com.shutterstock.media.api
</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.scanning.recursive</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.whatever.etc.MainClass</param-value>
</init-param>
<init-param>
<param-name>dirAllowed</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<!-- used to overwrite default 4xx state pages -->
<param-name>jersey.config.server.response.setStatusOverSendError</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Swagger -->
<servlet>
<servlet-name>Jersey Swagger</servlet-name>
<servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
</web-app>
答案 0 :(得分:1)
我能给你的最佳建议是将你的项目完全转换为弹簧启动,以便充分利用它提供的所有强大功能。
您应该从项目中完全删除所有XML并执行以下步骤:
<强> TL; DR 强>
从spring boot启动的一个简单方法是使用spring initializr(Spring initializr)并开始将代码迁移到新项目。
解释在现有项目中迁移到spring boot的开始步骤:
Maven依赖
添加以下依赖项并删除所有其他相关的spring依赖项。一般情况下,如果您需要任何其他依赖项,请首先检查是否有弹簧启动启动器。 (同时确保您的包装为jar
。如果您需要war
,请访问此链接:convert to war)
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Spring Boot Application
创建一个使用@SpringBootApplication
注释的类,在您的基础包中看起来如下所示。从这一点开始,仅在此包的子包中创建类,因此spring可以自动捕获所有组件:
@SpringBootApplication
public class FooApplication {
public static void main(String[] args) {
SpringApplication.run(FooApplication .class, args);
}
}
Java配置
现在您可以轻松地在您的基础软件包下添加一个名为config
的软件包,并使用您的自定义配置添加@Configuration
带注释的bean。
<强> application.properites / YML 强>
如果您还没有,请将application.properties/yml添加到src/main.resources
,并至少配置以下配置(可在此处找到更多属性:spring boot common properties)
spring.jersey.application-path=/
泽西岛配置
您需要在扩展ResourceConfig
的自定义Java配置类中注册jersey提供程序:
@Configuration
public class JerseyConfiguration extends ResourceConfig {
public JerseyConfiguration() {
register(FooController.class);
register(OtherController.class);
...
}
}
重要提示
执行此转换后,您不再需要web.xml
,因为spring boot负责为您创建servlet。您应该从项目中删除除pom.xml
之外的所有XML并将所有XML转换为java。它可以使用@ImportResource
与您的XML配置共存,但不建议这样做。
现在使用maven使用maven build运行项目时使用以下命令:spring-boot:run
。
如果您有系统提供的任何静态文件,请将其从src/main/webapp
移至src/main/resources/static
(此处提供更多信息:Static Content)
所有这一切都应该让你开始使用spring boot并允许你删除applicationContext.xml
,同时保持spring boot的最佳实践。你可以用一种更简单的方式做到这一点,但我认为从长远来看它会更好地为你服务。
答案 1 :(得分:1)
您收到错误是因为Jersey与Spring集成的默认方式是查找此applicationContext.xml文件。如果你想减少xml,你需要使用WebApplicationInitializer
@Order(1)
public class SpringWebContainerInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerContextLoaderListener(servletContext);
// Set the Jersey used property so it won't load a ContextLoaderListener
// see bug report https://java.net/jira/browse/JERSEY-2038
servletContext.setInitParameter("contextConfigLocation", "");
}
private void registerContextLoaderListener(ServletContext servletContext) {
WebApplicationContext webContext;
webContext = createWebAplicationContext(SpringAnnotationConfig.class);
servletContext.addListener(new ContextLoaderListener(webContext));
}
public WebApplicationContext createWebAplicationContext(Class... configClasses) {
AnnotationConfigWebApplicationContext context;
context = new AnnotationConfigWebApplicationContext();
context.register(configClasses);
return context;
}
}
在此示例中,您可以看到
createWebAplicationContext(SpringAnnotationConfig.class)
只需在那里使用AppConfig
。
我们在这里做的是自己加载Spring上下文,当Jersey查找它时,它会找到它,而不是尝试加载上下文本身(否则它会尝试查找applicationContext.xml)文件)。
另见: