在 spring-boot 项目中使用 spring mvc xml 项目
Posted
技术标签:
【中文标题】在 spring-boot 项目中使用 spring mvc xml 项目【英文标题】:Use spring mvc xml project inside spring-boot project 【发布时间】:2016-08-13 08:42:55 【问题描述】:我创建了这个测试项目,由 2 个项目组成:一个使用 spring-boot,一个使用 spring-mvc。它们中的每一个都可以独立工作。 我想要做的是运行 spring-boot 并能够通过加载它的上下文来访问 spring-mvc 项目的网页。 这个项目很简单,我只是想测试一下如何混音。
问题是,当我运行 spring-boot 应用程序时,无法访问 spring-mvc 的页面,因为它没有在构建中添加 webbapp 文件夹(包含 WEB-INF)。 我可以在 spring-boot 应用程序中从 spring-mvc 自动装配服务。
树如下所示:
spring-boot的Application.java类如下:
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import java.util.Arrays;
@SpringBootApplication
@ComponentScan("org.burdu", "hello")
//@ImportResource("classpath:WEB-INF/spring-core-config.xml", "classpath:WEB-INF/spring-mvc-config.xml")
public class Application
public static void main(String[] args)
ApplicationContext ctx = SpringApplication.run(Application.class, args);
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames)
System.out.println(beanName);
根 build.gradle
group 'net.burdu'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'idea'
sourceCompatibility = 1.8
repositories
mavenCentral()
mavenLocal()
dependencies
testCompile group: 'junit', name: 'junit', version: '4.11'
root settings.gradle
rootProject.name = 'testSpringXMLAndBoot'
include 'spring-mvc'
include 'spring-boot'
spring-boot build.gradle
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'war'
apply plugin: 'spring-boot'
sourceCompatibility = 1.8
repositories
jcenter()
mavenCentral()
buildscript
repositories
mavenCentral()
dependencies
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE")
dependencies
compile("org.springframework.boot:spring-boot-starter-web")
compile project(':spring-mvc')
spring-mvc build.gradle
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'war'
apply plugin: 'jetty'
sourceCompatibility = 1.8
repositories
mavenCentral()
mavenLocal()
dependencies
compile 'ch.qos.logback:logback-classic:1.1.3'
compile 'org.springframework:spring-webmvc:4.1.6.RELEASE'
compile 'javax.servlet:jstl:1.2'
jettyRun
contextPath = ""
httpPort = 8080
jettyRunWar
contextPath = ""
httpPort = 8080
spring-core-config.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd ">
<context:component-scan base-package="org.burdu.web" />
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:annotation-driven />
</beans>
spring-mvc-config.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd ">
<context:component-scan base-package="org.burdu.service" />
</beans>
spring-mvc 项目中的 web.xml
<web-app 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_2_5.xsd"
version="2.5">
<display-name>Gradle + Spring MVC Hello World + XML</display-name>
<description>Spring MVC web application</description>
<!-- For web context -->
<servlet>
<servlet-name>hello-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- For root context -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-core-config.xml</param-value>
</context-param>
</web-app>
spring-boot 中的 HelloController、HelloWorldService 和 WelcomeController 都是简单的 bean。我没有在这里粘贴他们的内容,因为问题已经太长了,但如果需要我可以添加它们。
【问题讨论】:
我想肯定还需要一些配置。您能否将您的项目发布到 github 或直接邮寄给我?如果我实现了,我将对此进行更多研究并发布任何有用的信息。 github.com/Burdu/testSpringXMLAndBoot 【参考方案1】:我尝试对您的github project 进行这些小改动:
spring-boot/build.gradle:
// This will include files and settings from spring-mvc
war
baseName = 'testSpringXMLAndBoot'
version = '0.1.0'
from '../spring-mvc/src/main/webapp'
// tomcat-embed-jasper is for jsp support
dependencies
..
compile("org.apache.tomcat.embed:tomcat-embed-jasper")
..
spring-boot/src/main/java/hello/Application.java:
@SpringBootApplication
@ComponentScan("org.burdu", "hello")
@ImportResource("classpath:WEB-INF/spring-mvc-config.xml") // added this resource back
public class Application
public static void main(String[] args)
ApplicationContext ctx = SpringApplication.run(Application.class, args);
..
正在运行:
spring-mvc/gradle jettyRun仍将在 Jetty 服务器上独立运行 spring-mvc
module
并运行:
spring-boot/java -jar build/libs/testSpringXMLAndBoot-0.1.0.war将在spring-boot
中包含spring-mvc
上下文并在嵌入式Tomcat 上运行它们。
【讨论】:
但你仍然无法使用 Spring Boot 中的 Application.main 运行它 你能澄清一下这是什么意思吗?你是如何运行它的? 我的意思是你可以通过简单地运行 Application.main 类从你的 IDE 运行 spring 应用程序。在您提供的替代方案中,您无法做到这一点。【参考方案2】:我已将合并后的项目导入到我的 IDE 中,但我发现很难将两个项目集成为一个并保持它们的原始性。真正的困难是spring不知道位于lib/spring-mvc.jar
的子项目spring-mvc
的jar里面的资源。如果我把它解压到子项目spring-boot
,还是不行。
后来,我在 spring-boot 中找到了这个关于 JSP limitations
的文档,上面写着:
由于 Tomcat 中的硬编码文件模式,可执行 jar 将无法工作
此外,我的建议是将您的应用程序转换为现代 spring-boot 形式,如下所示:
Convert an existing application to Spring Boot
在这种情况下,您只需按照文档所述将web.xml
中定义的servlet 和过滤器转换为spring bean。此外,spring-core-config.xml
和spring-mvc-config.xml
可以保持不变,因为即使它们在嵌入的 jar 中也可以直接导入。这应该很容易。
将应用程序转换为 Spring Boot 后,您也可以完全控制 Web 容器。
最后,如果您真的想一起使用它们,以下文档可能会很有用:
Deploying a WAR in an Old (Servlet 2.5) Container
这一次,您可以在您的web.xml
指定SpringBootContextLoaderListener
作为您的监听器。它可以帮助配置您的应用程序。但是,正如 spring 所说,它仅对将应用程序部署到旧容器中有用。
但是,如果我是你,我会将其转换为 spring-boot 格式。因为它可以简化维护工作。
spring boot默认只允许/
,META-INF/resources
,resources
,public
,static
目录作为资源加载路径。从这个角度来看,如果您的所有资源都位于这些目录下,它应该可以工作。当然,specifying document root 是必需的。如果您可以容忍提取spring-mvc
,我认为这将是解决方案。
如果嵌入jar中定义的spring上下文是你想要的,你可以在classpath
之后加一个星号,比如classpath*:WEB-INF/applicationContext.xml
。这将在任何 lib jar 中添加任何 WEB-INF/applicationContext.xml
。换句话说,您只需在@ImportResource
表达式中的classpath
之后添加一个星号。如果一切顺利,你就在那里。
【讨论】:
谢谢。您可以删除 jsp 部分。想象一下 spring-mvc 应用程序只是 REST 并且在 webapp 中你有 javascript 前端。这可行吗? 我试图将spring-mvc
提取到spring-boot
中,这使它成为spring-boot
的一部分(如果您将spring-mvc
保留为嵌入式jar,File
无法识别资源在spring-mvc
)。后来我调试了spring-boot
,发现它只允许目录/
,META-INF/resources
,resources
,public
,static
作为资源加载路径。
我最后改进了我的答案,请看看!
如果你的项目没有web.xml,比如只是一个用于持久化的子项目怎么办?它只有 applicationContext.xml。所以我们会有 spring-mvc、spring-boot 和 spring-persistance。我知道这不是主要问题,但我认为它不会归结为 web.xml。
如果只需要集成嵌入jar中定义的spring上下文,则需要在classpath
后面加星号,如classpath*:WEB-INF/applicationContext.xml
。这将在任何 lib jar 中添加任何 WEB-INF/applicationContext.xml
。您只需在 @ImportResource
表达式中的 classpath
之后添加一个星号。如果一切顺利,你就在那里。以上是关于在 spring-boot 项目中使用 spring mvc xml 项目的主要内容,如果未能解决你的问题,请参考以下文章
spring-boot结合maven配置不同环境的profile
无法将 spring-boot 2 服务连接到不同容器中的 mysql
让 oauth2 与 spring-boot 和 rest 一起工作