在spring-boot项目

时间:2016-04-20 14:57:17

标签: java spring spring-mvc gradle spring-boot

我有我创建的这个测试项目,由2个项目组成:一个使用spring-boot,另一个使用spring-mvc。他们每个人都很好地独立工作。 我想要做的是运行spring-boot并通过加载其上下文来访问spring-mvc项目的网页。 该项目非常简单,因为我只想测试如何进行混合。

问题在于,当我运行spring-boot应用程序时,spring-mvc中的页面无法访问,因为它不会在构建中添加webbapp文件夹(包含WEB-INF)。 我可以在spring-boot应用程序中从spring-mvc自动装配服务。

树看起来如下:

enter image description here

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);
    }
}
}

root 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
}

弹簧核-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>

弹簧-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,HelloWorldService和WelcomeController中的HelloController是简单的bean。我没有在这里粘贴他们的内容,因为问题已经太长了,但如果需要我可以添加它们。

2 个答案:

答案 0 :(得分:3)

我已将组合项目导入到我的IDE中,我发现很难将两个项目合并为一个并保持原始状态。真正的困难是spring无法知道位于spring-mvc的子项目lib/spring-mvc.jar jar内的资源。如果我将其提取到子项目spring-boot中,它仍然无效。

之后,我在spring-boot中找到了关于JSP limitations的文档,其中说:

  

由于Tomcat中的硬编码文件模式,可执行jar将无法工作

更重要的是,我的建议是将您的应用程序转换为现代弹簧启动形式,如下所示:

  

Convert an existing application to Spring Boot

在这种情况下,您只需要将web.xml中定义的servlet和过滤器转换为spring bean,如文档所述。此外,spring-core-config.xmlspring-mvc-config.xml可以保持不变,因为它们可以直接导入,即使它们位于嵌入式jar中。应该很容易。

将应用程序转换为弹簧启动后,您也可以对Web容器进行全部控制。

最后,如果你真的想一起使用它们,那么下面的文档可能很有用:

  

Deploying a WAR in an Old (Servlet 2.5) Container

这一次,您可以在SpringBootContextLoaderListener指定web.xml作为您的听众。它可以帮助您配置您的应用程序。但是,正如Spring所说,它只对将应用程序部署到旧容器中有用。

但是,如果我是你,我会将其转换为spring-boot格式。因为它可以简化维护工作。

默认情况下,spring boot仅允许目录/META-INF/resourcesresourcespublicstatic作为资源加载路径。从这个角度来看,如果所有资源都位于这些目录下,它应该可以工作。当然,specifying document root是必需的。如果您能够容忍提取spring-mvc,我认为这将是解决方案。

如果您想要的是在嵌入式jar中定义的弹簧上下文,则可以在classpath之后添加一个星标,例如classpath*:WEB-INF/applicationContext.xml。这将在任何lib jar中添加任何WEB-INF/applicationContext.xml。换句话说,您只需要在classpath表达式@ImportResource之后添加星标。如果一切顺利,你就在那里。

答案 1 :(得分:2)

我对您的github project尝试了这些小改动:

弹簧引导/的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")
    ..
}

弹簧引导/ SRC /主/ JAVA /你好/ 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模块

跑步:

  • spring-boot / java -jar build / libs / testSpringXMLAndBoot-0.1.0.war

spring-mvc上下文包含到spring-boot并在嵌入式Tomcat上运行它们。