我熟悉Spring Boot JSP sample application
但是该示例使用WAR
包装。是否可以对<packaging>JAR</packaging>
执行相同的操作?
我的目标是将JSP
放在src/main/resources/jsp
下以简化我的应用程序的结构。
答案 0 :(得分:23)
正如@Andy Wilkinson所说,存在与JSP相关的限制。请将您的应用程序打包为war
并执行jar
。这是在春季网站上记录的。
使用Tomcat,如果使用war包装,它应该可以工作,即可执行的战争将起作用(...)。 由于Tomcat中的硬编码文件模式,可执行jar将无法工作。
已弃用,旧答案
是的,Spring Boot可以实现这一点。
请看一下这个例子:https://github.com/mariuszs/spring-boot-web-jsp-example。
为此,请使用spring-boot-maven-plugin或gradle equivalent。
使用这个插件jar是可执行的,可以提供JSP文件。
$ mvn package
$ java -jar target/mymodule-0.0.1-SNAPSHOT.jar
或只是
$ mvn spring-boot:run
答案 1 :(得分:5)
如果springboot正在构建项目并在本地服务器中正确运行,那么是。
您需要做的是使用构建项目
mvn -U clean package
。
然后在目标文件夹中,您拥有可运行的xxxx.jar。现在,您需要将xxxx.jar文件放在服务器中或您想要的位置以及同一层次结构中的src/main/webapp/WEB-INF/jsp/
* .jsp 文件。
然后尝试java -jar xxxx.jar
您的项目将毫无问题地运行。
`
.
├── src
│ └── main
│ └── webapp
│ └── WEB-INF
│ ├── jsp
│ │ ├── default.jsp
│ │ ├── help.jsp
│ │ ├── index.jsp
│ │ ├── insert.jsp
│ │ ├── login.jsp
│ │ ├── modify.jsp
│ │ ├── search.jsp
│ │ └── show.jsp
│ └── web.xml
├── xxx.jar
└── xxx.jar.original`
java -jar xxx.jar
<pre>
$java -jar xxx.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.4.RELEASE)
2017-09-05 19:31:05.009 INFO 10325 --- [ main] com.myapp.app.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT on dipu-HP with PID 10325 (/home/dipu/Documents/workspace-sts/jspjartest/xxx.jar started by dipu in /home/dipu/Documents/workspace-sts/jspjartest)
2017-09-05 19:31:05.014 INFO 10325 --- [ main] com.myapp.app.DemoApplication : No active profile set, falling back to default profiles: default
2017-09-05 19:31:05.138 INFO 10325 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5e91e4: startup date [Tue Sep 05 19:31:05 IST 2017]; root of context hierarchy
2017-09-05 19:31:07.258 INFO 10325 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8090 (http)
2017-09-05 19:31:07.276 INFO 10325 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2017-09-05 19:31:07.278 INFO 10325 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.15
2017-09-05 19:31:08.094 INFO 10325 --- [ost-startStop-1] org.apache.jasper.servlet.TldScanner : At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
2017-09-05 19:31:08.396 INFO 10325 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-09-05 19:31:08.401 INFO 10325 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 3267 ms
2017-09-05 19:31:08.615 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2017-09-05 19:31:08.617 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'loginServlet' to [/loginServlet/]
2017-09-05 19:31:08.618 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'uploadController' to [/uploadController/]
2017-09-05 19:31:08.622 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-09-05 19:31:08.622 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-09-05 19:31:08.623 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-09-05 19:31:08.623 INFO 10325 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-05 19:31:09.137 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5e91e4: startup date [Tue Sep 05 19:31:05 IST 2017]; root of context hierarchy
2017-09-05 19:31:09.286 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/user-management]}" onto java.lang.String com.myapp.app.DemoController.user()
2017-09-05 19:31:09.288 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto java.lang.String com.myapp.app.DemoController.reload()
2017-09-05 19:31:09.290 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/show]}" onto java.lang.String com.myapp.app.DemoController.show()
2017-09-05 19:31:09.292 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/modify]}" onto java.lang.String com.myapp.app.DemoController.modify()
2017-09-05 19:31:09.293 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/admin]}" onto java.lang.String com.myapp.app.DemoController.admin()
2017-09-05 19:31:09.294 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login]}" onto java.lang.String com.myapp.app.DemoController.login()
2017-09-05 19:31:09.294 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/faq-management]}" onto java.lang.String com.myapp.app.DemoController.faq()
2017-09-05 19:31:09.294 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/subject-area]}" onto java.lang.String com.myapp.app.DemoController.subject()
2017-09-05 19:31:09.295 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/Chat]}" onto java.lang.String com.myapp.app.DemoController.index()
2017-09-05 19:31:09.295 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/delete]}" onto java.lang.String com.myapp.app.DemoController.delete()
2017-09-05 19:31:09.296 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/result]}" onto java.lang.String com.myapp.app.DemoController.result()
2017-09-05 19:31:09.296 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/insert]}" onto java.lang.String com.myapp.app.DemoController.insert()
2017-09-05 19:31:09.300 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/fileUpload]}" onto java.lang.String com.myapp.app.DemoController.file()
2017-09-05 19:31:09.301 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/search]}" onto java.lang.String com.myapp.app.DemoController.search()
2017-09-05 19:31:09.301 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/help]}" onto java.lang.String com.myapp.app.DemoController.help()
2017-09-05 19:31:09.312 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/LoginServlet]}" onto public void com.myapp.app.LoginServlet.LoginServlet.doPost(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2017-09-05 19:31:09.313 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/image],methods=[GET],produces=[text/html;charset=UTF-8]}" onto public java.lang.String com.myapp.app.controller.ImageController.image()
2017-09-05 19:31:09.316 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/authenticate],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.authenticate(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.317 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/searchCompany],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.getCompany(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.318 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/executeQuery],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.executeQuery(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.318 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/insertData],methods=[POST]}" onto public int com.myapp.app.controller.AjaxController.insertResources(java.lang.String,java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.319 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/showData],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.showResources(java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.319 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/searchData],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.getSearchData(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.319 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/deleteData],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.deleteData(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.320 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/modifyData],methods=[POST]}" onto public int com.myapp.app.controller.AjaxController.modifyData(java.lang.String,java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.322 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/suggestWords],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.suggestWords(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.322 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/authenticateUser],methods=[POST]}" onto public java.lang.String com.myapp.app.controller.AjaxController.authenticateUser(java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.323 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/insertJson],methods=[POST]}" onto public int com.myapp.app.controller.AjaxController.insertJsonResources(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.323 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/getvalue],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.getResource(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.324 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/searchQuery],methods=[GET]}" onto public java.lang.String com.myapp.app.controller.AjaxController.getResources(java.lang.String,java.lang.String) throws java.io.IOException
2017-09-05 19:31:09.330 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/upload],methods=[POST]}" onto public void com.myapp.app.controller.UploadController.doPost(org.springframework.web.multipart.MultipartFile,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2017-09-05 19:31:09.333 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-09-05 19:31:09.334 INFO 10325 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-09-05 19:31:09.388 INFO 10325 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-05 19:31:09.388 INFO 10325 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-05 19:31:09.461 INFO 10325 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-09-05 19:31:09.752 INFO 10325 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-09-05 19:31:09.861 INFO 10325 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8090 (http)
2017-09-05 19:31:09.867 INFO 10325 --- [ main] com.myapp.DemoApplication : Started DemoApplication in 5.349 seconds (JVM running for 5.866)
</pre>
此处服务器正在运行
$ curl 127.0.0.1:8090/login
Welcome to Login page
我的POM.xml
<code>
<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.myapp</groupId>
<artifactId>app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Jsp Springboot</name>
<description>Jsp Springboot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- Need this to compile JSP,
tomcat-embed-jasper version is not working, no idea why -->
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>rest</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>
</project>
</code>
我的application.properties
<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.myapp</groupId>
<artifactId>app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Jsp Springboot</name>
<description>Jsp Springboot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- Need this to compile JSP,
tomcat-embed-jasper version is not working, no idea why -->
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.6.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>rest</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>
</project>
我的项目结构
<code>
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
server.port=8090
</code>
谢谢。
答案 2 :(得分:4)
您最好的选择是将包装类型更改为战争,它应该无需进一步更改即可使用。
如上述评论所述,存在一些限制:
答案 3 :(得分:3)
27.3.5 JSP限制
当运行使用嵌入式servlet容器的Spring Boot应用程序(并打包为可执行存档)时,JSP支持存在一些限制。
使用Tomcat它应该可以使用war包装,即可执行的war会起作用,并且也可以部署到标准容器(不限于但包括Tomcat)。
由于Tomcat中的硬编码文件模式,可执行jar将无法工作。
使用Jetty它应该可以使用war包装,即可执行的战争可行,并且也可以部署到任何标准容器。
Undertow不支持JSP。
创建自定义error.jsp页面不会覆盖错误处理的默认视图,而是应该使用自定义错误页面。
答案 4 :(得分:2)
Spring Boot在JSP方面非常不错,只需要在配置下方
,它也很简单1 - tomcat-embad-jasper依赖
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
2 - 添加以下配置是application.properties
spring.mvc.view.prefix: /
spring.mvc.view.suffix: .jsp
它还有一些疑问,请在链接下方查看
答案 5 :(得分:2)
如果出于某种原因,你无法处理战争包装,那就是黑客攻击。完全归功于this家伙为旧版本的spring-boot做这件事。
执行此操作的一种方法是个性化tomcat并将BOOT-INF/classes
添加到tomcat的ResourceSet。在tomcat中,所有扫描的资源都被放入称为ResourceSet的东西中。例如,servlet 3.0规范中的应用程序jar包的META-INF / resources被扫描并放入ResourceSet中。
现在我们需要找到一种方法将fat jar的BOOT-INF / classes目录添加到ResourceSet中。我们可以通过tomcat LifecycleListener接口在Lifecycle.CONFIGURE_START_EVENT
事件中执行此操作,获取BOOT-INF / classes URL,然后将此URL添加到WebResourceSet。一个完整的例子是here,但你可以这样做:
import org.apache.catalina.Context;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnProperty(name = "tomcat.staticResourceCustomizer.enabled", matchIfMissing = true)
public class TomcatConfiguration {
@Bean
public WebServerFactoryCustomizer<WebServerFactory> staticResourceCustomizer() {
return new WebServerFactoryCustomizer<WebServerFactory>() {
@Override
public void customize(WebServerFactory factory) {
if (factory instanceof TomcatServletWebServerFactory) {
((TomcatServletWebServerFactory) factory)
.addContextCustomizers(new org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer() {
@Override
public void customize(Context context) {
context.addLifecycleListener(new StaticResourceConfigurer(context));
}
});
}
}
};
}
}
然后像这样使用LifecycleListener:
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.catalina.Context;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.WebResourceRoot.ResourceSetType;
import org.springframework.util.ResourceUtils;
public class StaticResourceConfigurer implements LifecycleListener {
private final Context context;
StaticResourceConfigurer(Context context) {
this.context = context;
}
@Override
public void lifecycleEvent(LifecycleEvent event) {
if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
URL location = this.getClass().getProtectionDomain().getCodeSource().getLocation();
if (ResourceUtils.isFileURL(location)) {
// when run as exploded directory
String rootFile = location.getFile();
if (rootFile.endsWith("/BOOT-INF/classes/")) {
rootFile = rootFile.substring(0, rootFile.length() - "/BOOT-INF/classes/".length() + 1);
}
if (!new File(rootFile, "META-INF" + File.separator + "resources").isDirectory()) {
return;
}
try {
location = new File(rootFile).toURI().toURL();
} catch (MalformedURLException e) {
throw new IllegalStateException("Can not add tomcat resources", e);
}
}
String locationStr = location.toString();
if (locationStr.endsWith("/BOOT-INF/classes!/")) {
// when run as fat jar
locationStr = locationStr.substring(0, locationStr.length() - "/BOOT-INF/classes!/".length() + 1);
try {
location = new URL(locationStr);
} catch (MalformedURLException e) {
throw new IllegalStateException("Can not add tomcat resources", e);
}
}
this.context.getResources().createWebResourceSet(ResourceSetType.RESOURCE_JAR, "/", location,
"/META-INF/resources");
}
}
}
答案 6 :(得分:1)
我正在使用 jar打包成功使用 JS P,将我的JSP文件放在src / main / webapp /上WEB-INF / JSP目录并将我的应用程序配置为下面的
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/JSP/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
我的控制器是:
@Controller
public class HelloController {
@RequestMapping(value = { "/", "/hello**" }, method = RequestMethod.GET)
public ModelAndView welcomePage() {
ModelAndView model = new ModelAndView();
model.addObject("title", "Spring Security Example");
model.addObject("message", "This is Hello World!");
model.setViewName("hello");
System.out.println("° ° ° ° welcomePage running. model = " + model);
return model;
}
. . .
我的hello.jsp是
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@page session="true"%>
<html>
<body>
<h1>Title : ${title}</h1>
<h1>${message}</h1>
<h2>Options:
<a href="<c:url value="/hello" />" >Home</a> |
<a href="<c:url value="/admin" />" >Administration</a> |
<a href="<c:url value="/super" />" >Super user</a>
<c:if test="${pageContext.request.userPrincipal.name != null}"> |
<a href="<c:url value="/logout" />" >Logout</a>
</c:if>
</h2>
</body>
</html>
我的pom.xml文件是
<groupId>br.com.joao-parana</groupId>
<artifactId>my-spring-boot-app</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<name>my-spring-boot-app Maven Webapp</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.4.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
. . .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<finalName>my-spring-boot-app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
我希望这有助于某人!
答案 7 :(得分:0)
嗨,我明白了如何将jar从jar复制到嵌入式tomcat文件夹
package com.demosoft.stlb.loadbalancer;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.context.ServletContextAware;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import java.io.*;
import java.net.MalformedURLException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@Component
public class JarFileResourcesExtractor implements ServletContextAware {
private String resourcePathPattern = "WEB-INF/**";
private String resourcePathPrefix = "WEB-INF/";
private String destination = "/WEB-INF/";
private ServletContext servletContext;
private AntPathMatcher pathMatcher = new AntPathMatcher();
/**
* Extracts the resource files found in the specified jar file into the destination path
*
* @throws IOException If an IO error occurs when reading the jar file
* @throws FileNotFoundException If the jar file cannot be found
*/
@PostConstruct
public void extractFiles() throws IOException {
try {
JarFile jarFile = (JarFile) getClass().getProtectionDomain().getCodeSource().getLocation().getContent();
Enumeration<JarEntry> entries = jarFile.entries();
System.out.println("Tomcat destination : " + servletContext.getRealPath(destination));
while (entries.hasMoreElements()) {
processJarEntry(jarFile, entries);
}
} catch (MalformedURLException e) {
throw new FileNotFoundException("Cannot find jar file in libs: ");
} catch (IOException e) {
throw new IOException("IOException while moving resources.", e);
}
}
private void processJarEntry(JarFile jarFile, Enumeration<JarEntry> entries) throws IOException {
JarEntry entry = entries.nextElement();
if (pathMatcher.match(resourcePathPattern, entry.getName())) {
String fileName = getFileName(entry);
if (checkFileName(fileName)) return;
String sourcePath = getSourcePath(entry, fileName);
if (checkSourcePath(sourcePath)) return;
copyAndClose(jarFile.getInputStream(entry), getOutputStream(fileName, sourcePath));
}
}
private FileOutputStream getOutputStream(String fileName, String sourcePath) throws IOException {
File destinationFolder = new File(servletContext.getRealPath(destination)+sourcePath);
destinationFolder.mkdirs();
File materializedFile = new File(destinationFolder, fileName);
materializedFile.createNewFile();
return new FileOutputStream(materializedFile);
}
private boolean checkSourcePath(String sourcePath) {
return sourcePath.startsWith(".idea");
}
private String getSourcePath(JarEntry entry, String fileName) {
String sourcePath = entry.getName().replaceFirst(fileName, "");
sourcePath = sourcePath.replaceFirst(resourcePathPrefix, "").trim();
return sourcePath;
}
private boolean checkFileName(String fileName) {
return fileName.trim().equals("");
}
private String getFileName(JarEntry entry) {
return entry.getName().replaceFirst(".*\\/", "");
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
public static int IO_BUFFER_SIZE = 8192;
private static void copyAndClose(InputStream in, OutputStream out) throws IOException {
try {
byte[] b = new byte[IO_BUFFER_SIZE];
int read;
while ((read = in.read(b)) != -1) {
out.write(b, 0, read);
}
} finally {
in.close();
out.close();
}
}
}
答案 8 :(得分:0)
我尝试了所有可能的解决方案,最终这帮助了我。
在pom.xml中添加以下依赖项
<!-- Need this to compile JSP -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- Need this to compile JSP -->
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>4.6.1</version>
</dependency>
将视图解析器添加到application.properties文件。
spring.mvc.view.prefix: /WEB-INF/jsp/
spring.mvc.view.suffix: .jsp
完成上述代码后,我们将使用maven命令构建项目,然后使用标准Java的jar执行命令作为独立jar执行。
cd <TO_YOUR_PROJECT_DIR>
mvn clean package spring-boot:repackage
java -jar target/<YOUR_PROJECT_CREATED_JAR>
答案 9 :(得分:0)
这是我的解决方法:
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
<targetPath>META-INF/resources</targetPath>
<includes>
<include>**/**</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- must use 1.4.2 version -->
<version>1.4.2.RELEASE</version>
</plugin>
</plugins>
</build>
答案 10 :(得分:0)
如果出于某种原因,有人在 SB2+ 中仍然需要这个,我们必须稍微调整生命周期事件方法
@Override
public void lifecycleEvent(LifecycleEvent event) {
if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
URL location = this.getClass().getProtectionDomain().getCodeSource().getLocation();
if (new LocalDevelDetection().isDocker()){
try {
//This is necessary to make JSP work in docker --> not sure which of those mounts actually does the trick but I think /YOUR_SB_APP_NAME one works for docker-compose and the other one for "vanilla docker" (non-compose)
context.getResources().createWebResourceSet(WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/<<YOUR_SB_APP_NAME>>", new URL("jar:file:/<<PATH_TO_YOUR_SB_APP>>.jar!/"), "/META-INF/resources");
context.getResources().createWebResourceSet(WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/", new URL("jar:file:/<<PATH_TO_YOUR_SB_APP>>.jar!/"), "/META-INF/resources");
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
else {
if (ResourceUtils.isFileURL(location)) {
// when run as exploded directory
String rootFile = location.getFile();
if (rootFile.endsWith("/BOOT-INF/classes/")) {
rootFile = rootFile.substring(0, rootFile.length() - "/BOOT-INF/classes/".length() + 1);
}
if (!new File(rootFile, "META-INF" + File.separator + "resources").isDirectory()) {
return;
}
try {
location = new File(rootFile).toURI()
.toURL();
} catch (MalformedURLException e) {
throw new IllegalStateException("Can not add tomcat resources", e);
}
}
String locationStr = location.toString();
if (locationStr.endsWith("/BOOT-INF/classes!/")) {
// when run as fat jar
locationStr = locationStr.substring(0, locationStr.length() - "/BOOT-INF/classes!/".length() + 1);
try {
location = new URL(locationStr);
} catch (MalformedURLException e) {
throw new IllegalStateException("Can not add tomcat resources", e);
}
}
this.context.getResources()
.createWebResourceSet(WebResourceRoot.ResourceSetType.RESOURCE_JAR, "/", location, "/META-INF/resources");
}
}
}
哦,还有我们的 LocalDevelDetection.isDocker() 方法:
public boolean isDocker(){
try (Stream< String > stream =
Files.lines(Paths.get("/proc/1/cgroup"))) {
return stream.anyMatch(line -> line.contains("/docker"));
} catch (IOException e) {
return false;
}
}