This time, in the development project generated from the blank project provided by TERASOLUNA 5.x (= Spring Framework), the file of the client library (CSS library, JS library) is applied by using the mechanism of WebJars. I will show you how to incorporate it into (= make a note).
Waht's TERASOLUNA 5.x ?
You can find out who TERASOLUNA 5.x is here here. It's a pity that the configuration method is XML-based and does not support Spring Boot, but it is packed with know-how for developing web applications using Spring, and maintenance is continuous (once a year). It is done in minor version upgrade + α).
In TERASOLUNA 5.x, "single project configuration" and "multi-project (multi-module) configuration We provide two types of blank projects (Mavne Archetype) of "/ terasolunaorg / terasoluna-gfw-web-multi-blank)", but this time we will create a project with a single project configuration.
command
$ mvn archetype:generate -B\
-DarchetypeGroupId=org.terasoluna.gfw.blank\
-DarchetypeArtifactId=terasoluna-gfw-web-blank-archetype\
-DarchetypeVersion=5.3.0.RELEASE\
-DgroupId=com.example\
-DartifactId=demo-webjars\
-Dversion=1.0.0-SNAPSHOT
Command execution result
$ mvn archetype:generate -B\
> -DarchetypeGroupId=org.terasoluna.gfw.blank\
> -DarchetypeArtifactId=terasoluna-gfw-web-blank-archetype\
> -DarchetypeVersion=5.3.0.RELEASE\
> -DgroupId=com.example\
> -DartifactId=demo-webjars\
> -Dversion=1.0.0-SNAPSHOT
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:2.3:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:2.3:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO]
[INFO]
[INFO] --- maven-archetype-plugin:2.3:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] Archetype repository not defined. Using the one from [org.terasoluna.gfw.blank:terasoluna-gfw-web-blank-archetype:5.3.0.RELEASE] found in catalog remote
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: terasoluna-gfw-web-blank-archetype:5.3.0.RELEASE
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: demo-webjars
[INFO] Parameter: version, Value: 1.0.0-SNAPSHOT
[INFO] Parameter: package, Value: com.example
[INFO] Parameter: packageInPathFormat, Value: com/example
[INFO] Parameter: package, Value: com.example
[INFO] Parameter: version, Value: 1.0.0-SNAPSHOT
[INFO] Parameter: groupId, Value: com.example
[INFO] Parameter: artifactId, Value: demo-webjars
[INFO] project created from Archetype in dir: /usr/local/apps/demo-webjars
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.617 s
[INFO] Finished at: 2017-09-03T13:01:31+09:00
[INFO] Final Memory: 16M/222M
[INFO] ------------------------------------------------------------------------
$
Configuration in the project
$ tree demo-webjars
demo-webjars
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ ├── app
│ │ │ └── welcome
│ │ │ └── HelloController.java
│ │ └── domain
│ │ ├── model
│ │ ├── repository
│ │ └── service
│ ├── resources
│ │ ├── META-INF
│ │ │ ├── dozer
│ │ │ └── spring
│ │ │ ├── applicationContext.xml
│ │ │ ├── demo-webjars-codelist.xml
│ │ │ ├── demo-webjars-domain.xml
│ │ │ ├── demo-webjars-infra.xml
│ │ │ ├── spring-mvc.xml
│ │ │ └── spring-security.xml
│ │ ├── ValidationMessages.properties
│ │ ├── dozer.properties
│ │ ├── i18n
│ │ │ └── application-messages.properties
│ │ └── logback.xml
│ └── webapp
│ ├── WEB-INF
│ │ ├── views
│ │ │ ├── common
│ │ │ │ ├── error
│ │ │ │ │ ├── accessDeniedError.jsp
│ │ │ │ │ ├── businessError.jsp
│ │ │ │ │ ├── dataAccessError.jsp
│ │ │ │ │ ├── invalidCsrfTokenError.jsp
│ │ │ │ │ ├── missingCsrfTokenError.jsp
│ │ │ │ │ ├── resourceNotFoundError.jsp
│ │ │ │ │ ├── systemError.jsp
│ │ │ │ │ ├── transactionTokenError.jsp
│ │ │ │ │ └── unhandledSystemError.html
│ │ │ │ └── include.jsp
│ │ │ └── welcome
│ │ │ └── home.jsp
│ │ └── web.xml
│ └── resources
│ └── app
│ └── css
│ └── styles.css
└── test
├── java
└── resources
28 directories, 25 files
$
After creating the project, use the Mavne command to build the war file.
$ cd demo-webjars
$ mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building TERASOLUNA Server Framework for Java (5.x) Web Blank Project 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo-webjars ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 11 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo-webjars ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /usr/local/apps/demo-webjars/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ demo-webjars ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo-webjars ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ demo-webjars ---
[INFO]
[INFO] --- maven-war-plugin:2.5:war (default-war) @ demo-webjars ---
[INFO] Packaging webapp
[INFO] Assembling webapp [demo-webjars] in [/usr/local/apps/demo-webjars/target/demo-webjars-1.0.0-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [/usr/local/apps/demo-webjars/src/main/webapp]
[INFO] Webapp assembled in [324 msecs]
[INFO] Building war: /usr/local/apps/demo-webjars/target/demo-webjars.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.454 s
[INFO] Finished at: 2017-09-03T13:07:22+09:00
[INFO] Final Memory: 32M/258M
[INFO] ------------------------------------------------------------------------
$
Deploy the built war file to the application server (Tomcat) using the Carog Mavne Plugin and start it.
$ mvn cargo:run
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building TERASOLUNA Server Framework for Java (5.x) Web Blank Project 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- cargo-maven2-plugin:1.6.2:run (default-cli) @ demo-webjars ---
[INFO] [en2.ContainerRunMojo] Resolved container artifact org.codehaus.cargo:cargo-core-container-tomcat:jar:1.6.2 for container tomcat8x
[INFO] [talledLocalContainer] Tomcat 8.x starting...
[INFO] [stalledLocalDeployer] Deploying [/usr/local/apps/demo-webjars/target/demo-webjars.war] to [/usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps]...
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Server version: Apache Tomcat/8.0.39
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Server built: Nov 9 2016 08:48:39 UTC
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Server number: 8.0.39.0
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: OS Name: Mac OS X
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: OS Version: 10.10.5
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Architecture: x86_64
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Java Home: /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: JVM Version: 1.8.0_131-b11
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: JVM Vendor: Oracle Corporation
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: CATALINA_BASE: /usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: CATALINA_HOME: /usr/local/apps/demo-webjars/target/cargo/installs/apache-tomcat-8.0.39/apache-tomcat-8.0.39
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Command line argument: -Xms512m
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Command line argument: -Xmx1024m
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Command line argument: -Dcatalina.home=/usr/local/apps/demo-webjars/target/cargo/installs/apache-tomcat-8.0.39/apache-tomcat-8.0.39
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Command line argument: -Dcatalina.base=/usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Command line argument: -Djava.io.tmpdir=/usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/temp
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.VersionLoggerListener log
[INFO] [talledLocalContainer]information: Command line argument: -Djava.util.logging.config.file=/usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/conf/logging.properties
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.core.AprLifecycleListener lifecycleEvent
[INFO] [talledLocalContainer]information: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /Users/shimizukazuki/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.coyote.AbstractProtocol init
[INFO] [talledLocalContainer]information: Initializing ProtocolHandler ["http-nio-8080"]
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
[INFO] [talledLocalContainer]information: Using a shared selector for servlet write/read
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.coyote.AbstractProtocol init
[INFO] [talledLocalContainer]information: Initializing ProtocolHandler ["ajp-nio-8009"]
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
[INFO] [talledLocalContainer]information: Using a shared selector for servlet write/read
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.Catalina load
[INFO] [talledLocalContainer]information: Initialization processed in 595 ms
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.core.StandardService startInternal
[INFO] [talledLocalContainer]information:Start the service Catalina
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.core.StandardEngine startInternal
[INFO] [talledLocalContainer]information: Starting Servlet Engine: Apache Tomcat/8.0.39
[INFO] [talledLocalContainer] 9 03, 2017 1:08:56 pm org.apache.catalina.startup.HostConfig deployWAR
[INFO] [talledLocalContainer]information:Web application archive/usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps/cargocpc.Deploy war
[INFO] [talledLocalContainer] 9 03, 2017 1:08:57 pm org.apache.catalina.startup.HostConfig deployWAR
[INFO] [talledLocalContainer]information: Deployment of web application archive /usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps/cargocpc.war has finished in 295 ms
[INFO] [talledLocalContainer] 9 03, 2017 1:08:57 pm org.apache.catalina.startup.HostConfig deployWAR
[INFO] [talledLocalContainer]information:Web application archive/usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps/demo-webjars.Deploy war
[INFO] [talledLocalContainer] 9 03, 2017 1:08:58 pm org.apache.jasper.servlet.TldScanner scanJars
[INFO] [talledLocalContainer]information: 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.
[INFO] [talledLocalContainer] 9 03, 2017 1:08:58 pm org.apache.catalina.core.ApplicationContext log
[INFO] [talledLocalContainer]information: No Spring WebApplicationInitializer types detected on classpath
[INFO] [talledLocalContainer] 9 03, 2017 1:08:59 pm org.apache.catalina.core.ApplicationContext log
[INFO] [talledLocalContainer]information: Initializing Spring root WebApplicationContext
[INFO] [talledLocalContainer] 9 03, 2017 1:09:00 pm org.apache.catalina.core.ApplicationContext log
[INFO] [talledLocalContainer]information: Initializing Spring FrameworkServlet 'appServlet'
[INFO] [talledLocalContainer] date:2017-09-03 13:09:00 thread:localhost-startStop-1 X-Track: level:INFO logger:o.springframework.web.servlet.DispatcherServlet message:FrameworkServlet 'appServlet': initialization started
[INFO] [talledLocalContainer] date:2017-09-03 13:09:00 thread:localhost-startStop-1 X-Track: level:INFO logger:o.s.w.s.m.m.a.RequestMappingHandlerMapping message:Mapped "{[/],methods=[GET || POST]}" onto public java.lang.String com.example.app.welcome.HelloController.home(java.util.Locale,org.springframework.ui.Model)
[INFO] [talledLocalContainer] date:2017-09-03 13:09:01 thread:localhost-startStop-1 X-Track: level:INFO logger:o.s.w.s.m.m.a.RequestMappingHandlerAdapter message:Looking for @ControllerAdvice: WebApplicationContext for namespace 'appServlet-servlet': startup date [Sun Sep 03 13:09:00 JST 2017]; parent: Root WebApplicationContext
[INFO] [talledLocalContainer] date:2017-09-03 13:09:01 thread:localhost-startStop-1 X-Track: level:INFO logger:o.s.w.s.m.m.a.RequestMappingHandlerAdapter message:Looking for @ControllerAdvice: WebApplicationContext for namespace 'appServlet-servlet': startup date [Sun Sep 03 13:09:00 JST 2017]; parent: Root WebApplicationContext
[INFO] [talledLocalContainer] date:2017-09-03 13:09:01 thread:localhost-startStop-1 X-Track: level:INFO logger:o.s.web.servlet.handler.SimpleUrlHandlerMapping message:Mapped URL path [/**] onto handler 'org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0'
[INFO] [talledLocalContainer] date:2017-09-03 13:09:01 thread:localhost-startStop-1 X-Track: level:INFO logger:o.s.web.servlet.handler.SimpleUrlHandlerMapping message:Mapped URL path [/resources/**] onto handler 'org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0'
[INFO] [talledLocalContainer] date:2017-09-03 13:09:01 thread:localhost-startStop-1 X-Track: level:INFO logger:o.springframework.web.servlet.DispatcherServlet message:FrameworkServlet 'appServlet': initialization completed in 1222 ms
[INFO] [talledLocalContainer] 9 03, 2017 1:09:01 pm org.apache.catalina.startup.HostConfig deployWAR
[INFO] [talledLocalContainer]information: Deployment of web application archive /usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps/demo-webjars.war has finished in 4,615 ms
[INFO] [talledLocalContainer] 9 03, 2017 1:09:01 pm org.apache.catalina.startup.HostConfig deployDirectory
[INFO] [talledLocalContainer]information:Web application directory/usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps/host-Deploy manager
[INFO] [talledLocalContainer] 9 03, 2017 1:09:01 pm org.apache.catalina.startup.HostConfig deployDirectory
[INFO] [talledLocalContainer]information: Deployment of web application directory /usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps/host-manager has finished in 19 ms
[INFO] [talledLocalContainer] 9 03, 2017 1:09:01 pm org.apache.catalina.startup.HostConfig deployDirectory
[INFO] [talledLocalContainer]information:Web application directory/usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps/Deploy manager
[INFO] [talledLocalContainer] 9 03, 2017 1:09:01 pm org.apache.catalina.startup.HostConfig deployDirectory
[INFO] [talledLocalContainer]information: Deployment of web application directory /usr/local/apps/demo-webjars/target/cargo/configurations/tomcat8x/webapps/manager has finished in 12 ms
[INFO] [talledLocalContainer] 9 03, 2017 1:09:01 pm org.apache.coyote.AbstractProtocol start
[INFO] [talledLocalContainer]information: Starting ProtocolHandler ["http-nio-8080"]
[INFO] [talledLocalContainer] 9 03, 2017 1:09:01 pm org.apache.coyote.AbstractProtocol start
[INFO] [talledLocalContainer]information: Starting ProtocolHandler ["ajp-nio-8009"]
[INFO] [talledLocalContainer] 9 03, 2017 1:09:01 pm org.apache.catalina.startup.Catalina start
[INFO] [talledLocalContainer]information: Server startup in 5012 ms
[INFO] [talledLocalContainer] Tomcat 8.x started on port [8080]
[INFO] Press Ctrl-C to stop the container...
When you access the application root, the following top screen (HTML) is applied.
$ curl -D - http://localhost:8080/demo-webjars/
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Track: c061e8853a3f49c2919c8ac6f46071cf
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: text/html;charset=UTF-8
Content-Language: ja-JP
Content-Length: 320
Date: Sun, 03 Sep 2017 04:11:03 GMT
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Home</title>
<link rel="stylesheet"
href="/demo-webjars/resources/app/css/styles.css">
</head>
<body>
<div id="wrapper">
<h1>Hello world!</h1>
<p>The time on the server is 2017/09/03 13:11:03 JST.</p>
</div>
</body>
</html>
$
This time, I will try to incorporate the CSS library Bootstrap into the application using the mechanism of WebJars.
pom.xml
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7-1</version>
</dependency>
Rebuild the war and deploy / start it again.
$ mvn package cargo:run
...
$
Try accessing the webJars bootstrap css file.
$ curl -D - http://localhost:8080/demo-webjars/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Track: cda63d914b0142c5bd36c0e85dd8e22d
Accept-Ranges: bytes
ETag: W/"121200-1469407916000"
Last-Modified: Mon, 25 Jul 2016 00:51:56 GMT
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: text/css;charset=UTF-8
Content-Length: 121200
Date: Sun, 03 Sep 2017 04:24:44 GMT
/*!
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{fo....
...
For application servers that support Servlet 3.0+, if there is a WebJars jar file in the classpath (WEB-INF / lib, etc.), you can access it without any special settings.
So, if you just use WebJars,
src/main/webapp/WEB-INF/views/welcome/home.jsp
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Home</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/resources/app/css/styles.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css"> <!--★ Addition-->
</head>
<body>
<div id="wrapper">
<h1>Hello world!</h1>
<p>The time on the server is ${serverTime}.</p>
</div>
</body>
</html>
If so, it's OK.
Perhaps ... many engineers don't want to include the version number (3.3.7-1
in this example) in the URL when accessing the css file.
Spring MVC provides a mechanism to exclude the version number from application code (JSP etc.) by linking with a library called webjar-locator
.
pon.xml
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
</dependency>
src/main/resources/META-INF/spring/spring-mvc.xml
<mvc:resources mapping="/webjars/**" location="/webjars/">
<mvc:resource-chain resource-cache="true"/> <!--If you specify this tag, Spring will be webjars-Automatically activates the function of linking with locator-->
</mvc:resources>
Rebuild the war, deploy and start it again, remove the version number and try to access it.
$ curl -D - http://localhost:8080/demo-webjars/webjars/bootstrap/css/bootstrap.min.css
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Track: adb21119739e422bb3faf020ff5e9e3f
Last-Modified: Sat, 17 Sep 2016 02:28:22 GMT
Accept-Ranges: bytes
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: text/css;charset=UTF-8
Content-Length: 121200
Date: Sun, 03 Sep 2017 04:53:18 GMT
/*!
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{
...
You could access it.
So, the part that specifies the css file to read is ...
src/main/webapp/WEB-INF/views/welcome/home.jsp
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Home</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/resources/app/css/styles.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/webjars/bootstrap/css/bootstrap.min.css"> <!--★ Remove version number from path-->
</head>
<body>
<div id="wrapper">
<h1>Hello world!</h1>
<p>The time on the server is ${serverTime}.</p>
</div>
</body>
</html>
If so, it's OK.
The fact that you don't need to include the version number in the path means that the path doesn't change even if you increase the version of the library. This means that depending on the Cache-Control settings, the files cached by the browser (files before version upgrade) may be used. However, if these files are not cached, useless network traffic and resource access on the server side will occur, so it is expected that "the load on the system will increase" and "the screen drawing speed will slow down". ..
To solve this problem
You can do it ... how (properly) ... Spring provides this feature! !!
First, register the ResourceUrlEncodingFilter
provided by Spring as a Servlet filter.
** Important: Servlet filter definition order **
Define ** after ** after the Spring Security Servlet Filter (springSecurityFilterChain).
src/main/webapp/WEB-INF/web.xml
<filter>
<filter-name>ResourceUrlEncodingFilter</filter-name>
<filter-class>org.springframework.web.servlet.resource.ResourceUrlEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ResourceUrlEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Therefore, JSP uses the tag library provided by JSTL or Spring when specifying the path.
src/main/webapp/WEB-INF/views/welcome/home.jsp
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Home</title>
<link rel="stylesheet"
href="${pageContext.request.contextPath}/resources/app/css/styles.css">
<link rel="stylesheet"
href="${pageContext.request.contextPath}/webjars/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"
href="<c:url value='/webjars/bootstrap/css/bootstrap.min.css'/>"> <!--★ Use JSTL tag library-->
<link rel="stylesheet"
href="<spring:url value='/webjars/bootstrap/css/bootstrap.min.css'/>"> <!--★ Use Spring tag library-->
</head>
<body>
<div id="wrapper">
<h1>Hello world!</h1>
<p>The time on the server is ${serverTime}.</p>
</div>
</body>
</html>
Then ...
$ curl -D - http://localhost:8080/demo-webjars/
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Track: 5576191e3ed54e82a83b67236bc98b24
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Content-Type: text/html;charset=UTF-8
Content-Language: ja-JP
Content-Length: 609
Date: Sun, 03 Sep 2017 05:28:08 GMT
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Home</title>
<link rel="stylesheet"
href="/demo-webjars/resources/app/css/styles.css">
<link rel="stylesheet"
href="/demo-webjars/webjars/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet"
href="/demo-webjars/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css">
<link rel="stylesheet"
href="/demo-webjars/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css">
</head>
<body>
<div id="wrapper">
<h1>Hello world!</h1>
<p>The time on the server is 2017/09/03 14:28:08 JST.</p>
</div>
</body>
</html>
$
HTML generated from JSP now includes the version number in the path.
Blank projects in TERASOLUNA 5.x provide Spring Security Servlet filters by default and are set to not cache access to paths other than / resources / **
. In other words, access to / webjars / **
is not cached, so you will have to re-acquire the CSS file each time you draw the screen.
To change this behavior, you can exclude access to / webjars / **
from Spring Security processing.
src/main/resources/META-INF/spring/spring-security.xml
<sec:http pattern="/resources/**" security="none"/>
<sec:http pattern="/webjars/**" security="none"/> <!--★ Addition-->
<sec:http>
<!-- ... -->
</sec:http>
If you access in this state ...
$ curl -D - http://localhost:8080/demo-webjars/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Track: a27dba531c8f4c79af0657ceaf5b430b
Last-Modified: Sat, 17 Sep 2016 02:28:22 GMT
Accept-Ranges: bytes
Content-Type: text/css;charset=UTF-8
Content-Length: 121200
Date: Sun, 03 Sep 2017 05:48:20 GMT
/*!
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{...
...
You can see that the Cache-Control header that Spring Security has given is gone. When I checked with Chrome and Safari,
It was a feeling that it was moving. (It may be a lie ...)
In the TERASOLUNA 5.x blank project, the following HandlerInterceptor
is applied by default, so prevent it from being applied when retrieving resources from WebJars.
TraceLoggingInterceptor
TransactionTokenInterceptor
CodeListInterceptor
src/main/resources/META-INF/spring/spring-mvc.xml
<mvc:interceptor>
<mvc:mapping path="/**" />
<mvc:exclude-mapping path="/resources/**" />
<mvc:exclude-mapping path="/webjars/**" /> <!--★ Addition-->
<mvc:exclude-mapping path="/**/*.html" />
<bean
class="org.terasoluna.gfw.web.logging.TraceLoggingInterceptor" />
</mvc:interceptor>
With WebJars,
webjars-locator
, you do not need to be aware of the library version number from the application code (JSP or HTML).Because there is a merit, I would like to use it positively.