EN
Spring Boot - pre-compile JSP files (Tomcat Server)
8
points
In this short article, we would like to show how to pre-compile *.jsp
files in Spring Boot application that uses Tomcat Server inside.
Problem:
*.jsp
files are compiled by Tomcat Server when they are first time used.
Solution: it is necessary to prepare some controller that imports existing
*.jsp
files without executing them - it will force compilation.
The below code shows how to implement JSP files pre-compiler, which should be run always after the Spring Boot Application is started.
Project structure:
/C/
|
+-- example-spring-boot-application/
|
+-- src/
| |
| +-- main/
| |
| +-- java/com/example/
| | |
| | +-- controllers/
| | | |
| | | +-- JspCompilerController.java
| | |
| | +-- SpringBootWebApplication.java
| |
| +-- webapp/WEB-INF/jsp
| |
| +-- about.jsp
| +-- jsp_compiler.jsp
| +-- gallery.jsp
| +-- index.jsp
| +-- login.jsp
| +-- reister.jsp
| +-- users.jsp
|
+-- pom.xml
Example implementations
It is necessary to run pre-compilation by opening preapared link:
https://my-domain.com/jsp-compiler
to run pre-compiler on deloyment,http://localhost/jsp-compiler
to run locally developed project if needed.
JspCompilerController.java
file:
package com.example.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class JspCompilerController {
@RequestMapping(value = {"/jsp-compiler"}, method = RequestMethod.GET)
public String getJspCompiler() {
return "jsp_compiler";
}
}
jsp_compiler.jsp
file:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.io.IOException" %>
<%@ page import="java.util.Set" %>
<%@ page import="java.util.Iterator" %>
<%!
private void compileJspFile(
ServletContext context,
JspWriter output,
HttpServletRequest request,
HttpServletResponse response,
String file
) throws IOException {
output.print("<div class=\"file\"><code>" + file + "</code> ");
try {
RequestDispatcher dispatcher = context.getRequestDispatcher(file);
if (dispatcher == null) {
output.print("<span class=\"error\">not found!</span>");
} else {
dispatcher.include(request, response);
output.print("<span class=\"success\">pre-compiled!</span>");
}
} catch (Exception ex) {
output.print("<span class=\"error\">error!</span>");
}
output.print("</div>");
output.flush();
}
private void compileJspFiles(
ServletContext context,
JspWriter output,
HttpServletRequest request,
HttpServletResponse response,
String directory
) throws IOException {
Set<String> files = context.getResourcePaths(directory);
Iterator<String> iterator = files.iterator();
while (iterator.hasNext()) {
String file = iterator.next();
if (file.endsWith(".jsp")) {
compileJspFile(context, output, request, response, file);
continue;
}
if (file.endsWith("/")) {
compileJspFiles(context, output, request, response, file);
continue;
}
}
}
%>
<html>
<head>
<title>JSP files pre-compilation</title>
<style>
div.files {
border: 1px solid gray;
}
span.error {
background: #ce4545;
color: #800000;
}
span.success {
background: #4ece45;
color: green;
}
div.summary {
margin: 20px 0 0 0;
background: #4ece45;
color: green;
}
</style>
</head>
<body>
<div class="files">
<%
ServletContext context = pageContext.getServletContext();
HttpServletRequest wrapper = new HttpServletRequestWrapper(request) {
public String getQueryString() {
/*
`jsp_precompile` parameter added to URL forces JSP pre-compliation:
?jsp_precompile
?jsp_precompile=true
?jsp_precompile=false
?some-parameter=here&jsp_precompile=true
?some-parameter=here&jsp_precompile=false
e.g.
https://my-domain.com/path/to/api?jsp_precompile=true
will force returned JSP view recompliation.
*/
return "jsp_precompile"; // required to run jsp files pre-compilation only
};
};
compileJspFiles(context, out, wrapper, response, "/WEB-INF/jsp");
%>
</div>
<div class="summary">Done!</div>
</body>
</html>