Spring 4 + 嵌入式 Tomcat 7
Spring 4 + Embedded Tomcat 7
我尝试使用 Spring Web MVC 4.3.2 和嵌入式 Tomcat 7.0.64.
构建网络应用程序
我没能写出正确的 main 方法来启动嵌入式 Tomcat。它适用于 Spring 控制器发送 @ResponseBody
内容(JSON)但对于 JSP 视图失败。
public static void main(String[] args) throws Exception {
String appBase = ".";// What to put here ?
Tomcat tomcat = new Tomcat();
String contextPath = "";
String port = System.getProperty("server.port");
tomcat.setPort(port == null ? 8080 : Integer.valueOf(port));
tomcat.getHost().setAppBase(appBase);
Context context = tomcat.addWebapp(contextPath, appBase);
// So that it works when in it's launched from IntelliJ or Eclipse
// Also need that a folder named "META-INF" exists in build/classes/main
// https://bz.apache.org/bugzilla/show_bug.cgi?id=52853#c19
((StandardJarScanner) context.getJarScanner()).setScanAllDirectories(true);
tomcat.start();
tomcat.getServer().await();
}
对于 JSP 查看它说:请求的资源不可用 (WEB-INF/views/home.jsp) HTTP 404
如果我将 appBase
变量设置为 JSP 所在的绝对路径,它就可以工作。但是,当然,这不是解决方案,因为它不能在另一台机器上运行。我需要一个相对路径。
如果我将 appBase
varibale 设置为 "src/main/webapp"
,则 Tomcat 无法启动并出现以下错误:java.lang.IllegalArgumentException: Document base C:\blabla\spring-jsp-embedded-tomcat\tomcat.8080\src\main\webapp\src\main\webapp does not exist or is not a readable directory
.
此外,使用Gradle fat jar 技术构建的jar 不包含WEB-INF 目录。
我怎样才能制作一个简单的 Spring MVC 应用程序,使用嵌入式 Tomcat 和 JSPs(将与 java -cp path/to/my/jar com.app.Launcher
一起启动)?
build.gradle :
apply plugin: 'java'
sourceCompatibility = 1.7
version = '1.0'
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
repositories {
maven { url "http://repo1.maven.org/maven2" }
}
dependencies {
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.6.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.6.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.6.2'
compile 'org.springframework:spring-webmvc:4.3.2.RELEASE'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0'
compile 'javax.servlet:javax.servlet-api:3.0.1'
compile 'javax.servlet.jsp:jsp-api:2.2'
compile 'javax.servlet:jstl:1.2'
// Embedded Tomcat
// 2 mandatory libs
compile 'org.apache.tomcat.embed:tomcat-embed-core:7.0.64'
compile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:7.0.64'
// To enable JSPs
compile 'org.apache.tomcat.embed:tomcat-embed-jasper:7.0.64'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
Tomcat 发射器:
public class Launcher {
public static void main(String[] args) throws Exception {
String contextPath = "";
// String appBase = "C:/absolute/path/to/webapp/dir"; // It works but of course I need a relative path
// String appBase = "."; // Works only for Controller sending back ResponseBody (JSON) but fail to find jsp files
String appBase = "src/main/webapp"; // Tomcat does not start properly
Tomcat tomcat = new Tomcat();
String port = System.getProperty("server.port");
tomcat.setPort(port == null ? 8080 : Integer.valueOf(port));
tomcat.getHost().setAppBase(appBase);
Context context = tomcat.addWebapp(contextPath, appBase);
// So that it works when in it's launched from IntelliJ or Eclipse
// Also need that a folder named "META-INF" exists in build/classes/main
// https://bz.apache.org/bugzilla/show_bug.cgi?id=52853#c19
((StandardJarScanner) context.getJarScanner()).setScanAllDirectories(true);
tomcat.start();
tomcat.getServer().await();
}
}
Spring 网络应用初始化程序:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
}
网络配置:
@Configuration
@EnableWebMvc
@ComponentScan("com.app")
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
文件夹结构:
显然,嵌入式 Tomcat 期望静态资源位于 META-INF/resources
目录中。我遵循了这个:tutorial 并检查了最终 jar 的结构。
所以我修改了 Gradle 构建脚本以将 JSP 放在那里。
sourceSets {
main {
resources.srcDirs = ["src/main/webapp"]
output.resourcesDir = "$buildDir/classes/main/META-INF/resources"
}
}
现在可以了。但是,我觉得这是一项临时工作。如果有人有更令人满意和更有教育意义的答案,我会很高兴。
我尝试使用 Spring Web MVC 4.3.2 和嵌入式 Tomcat 7.0.64.
构建网络应用程序我没能写出正确的 main 方法来启动嵌入式 Tomcat。它适用于 Spring 控制器发送 @ResponseBody
内容(JSON)但对于 JSP 视图失败。
public static void main(String[] args) throws Exception {
String appBase = ".";// What to put here ?
Tomcat tomcat = new Tomcat();
String contextPath = "";
String port = System.getProperty("server.port");
tomcat.setPort(port == null ? 8080 : Integer.valueOf(port));
tomcat.getHost().setAppBase(appBase);
Context context = tomcat.addWebapp(contextPath, appBase);
// So that it works when in it's launched from IntelliJ or Eclipse
// Also need that a folder named "META-INF" exists in build/classes/main
// https://bz.apache.org/bugzilla/show_bug.cgi?id=52853#c19
((StandardJarScanner) context.getJarScanner()).setScanAllDirectories(true);
tomcat.start();
tomcat.getServer().await();
}
对于 JSP 查看它说:请求的资源不可用 (WEB-INF/views/home.jsp) HTTP 404
如果我将 appBase
变量设置为 JSP 所在的绝对路径,它就可以工作。但是,当然,这不是解决方案,因为它不能在另一台机器上运行。我需要一个相对路径。
如果我将 appBase
varibale 设置为 "src/main/webapp"
,则 Tomcat 无法启动并出现以下错误:java.lang.IllegalArgumentException: Document base C:\blabla\spring-jsp-embedded-tomcat\tomcat.8080\src\main\webapp\src\main\webapp does not exist or is not a readable directory
.
此外,使用Gradle fat jar 技术构建的jar 不包含WEB-INF 目录。
我怎样才能制作一个简单的 Spring MVC 应用程序,使用嵌入式 Tomcat 和 JSPs(将与 java -cp path/to/my/jar com.app.Launcher
一起启动)?
build.gradle :
apply plugin: 'java'
sourceCompatibility = 1.7
version = '1.0'
jar {
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
repositories {
maven { url "http://repo1.maven.org/maven2" }
}
dependencies {
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.6.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.6.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.6.2'
compile 'org.springframework:spring-webmvc:4.3.2.RELEASE'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0'
compile 'javax.servlet:javax.servlet-api:3.0.1'
compile 'javax.servlet.jsp:jsp-api:2.2'
compile 'javax.servlet:jstl:1.2'
// Embedded Tomcat
// 2 mandatory libs
compile 'org.apache.tomcat.embed:tomcat-embed-core:7.0.64'
compile 'org.apache.tomcat.embed:tomcat-embed-logging-juli:7.0.64'
// To enable JSPs
compile 'org.apache.tomcat.embed:tomcat-embed-jasper:7.0.64'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
Tomcat 发射器:
public class Launcher {
public static void main(String[] args) throws Exception {
String contextPath = "";
// String appBase = "C:/absolute/path/to/webapp/dir"; // It works but of course I need a relative path
// String appBase = "."; // Works only for Controller sending back ResponseBody (JSON) but fail to find jsp files
String appBase = "src/main/webapp"; // Tomcat does not start properly
Tomcat tomcat = new Tomcat();
String port = System.getProperty("server.port");
tomcat.setPort(port == null ? 8080 : Integer.valueOf(port));
tomcat.getHost().setAppBase(appBase);
Context context = tomcat.addWebapp(contextPath, appBase);
// So that it works when in it's launched from IntelliJ or Eclipse
// Also need that a folder named "META-INF" exists in build/classes/main
// https://bz.apache.org/bugzilla/show_bug.cgi?id=52853#c19
((StandardJarScanner) context.getJarScanner()).setScanAllDirectories(true);
tomcat.start();
tomcat.getServer().await();
}
}
Spring 网络应用初始化程序:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
}
网络配置:
@Configuration
@EnableWebMvc
@ComponentScan("com.app")
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
文件夹结构:
显然,嵌入式 Tomcat 期望静态资源位于 META-INF/resources
目录中。我遵循了这个:tutorial 并检查了最终 jar 的结构。
所以我修改了 Gradle 构建脚本以将 JSP 放在那里。
sourceSets {
main {
resources.srcDirs = ["src/main/webapp"]
output.resourcesDir = "$buildDir/classes/main/META-INF/resources"
}
}
现在可以了。但是,我觉得这是一项临时工作。如果有人有更令人满意和更有教育意义的答案,我会很高兴。