Spring 3 doesn't return css - css

I just started with Spring 3 MVC today. Running into a dilemma...
web.xml maps everything ("/") to Spring. But as a result, when I put something like:
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath()%>/css/navigation.css" />
It is not returned by the container...
Perhaps someone could suggest how to handle this?
Thanks.

Use mvc:resources, as explained in the documentation. This allows service static resources from the web app, but also from the classpath.

How are you trying to serve it? If you are trying to serve it from the webapp itself (ie WEB-INF/static/css) You would need to include a servlet to do that for you. In the spring context you can include something like
<mvc:resources mapping="/resources/**" location="/resources/" />
You can see more here
How to handle static content in Spring MVC?

As suggested by others, use mvc:resource to serve your static resources.
<mvc:resources mapping="/resources/**" location="/resources/" />
It is also recommended to avoid using scriptlets in your JSP code if possible. You should instead use JSTL to build the correct path to your CSS file.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
...
<link rel="stylesheet" type="text/css" href="<c:url value="/resources/css/navigation.css" />"/>

Related

Spring <mvc:resources ... /> request routing

TL;DR: I'm writing a simple Tomcat/Spring/Freemarker webapp and seem to be having a lot of trouble getting Spring's DispatcherServlet to honor <mvc:resources...> configuration.
PLEASE NOTE: AFAICT this is not a duplicate of other questions since I've tried the solutions given in other answers. If someone finds an existing question and that question provides a solution I missed, I'll gladly VTC as a dup (or delete this question if desired).
I have a very simple webapp based on Freemarker. That part is working fine. I have a single request-handler method to handle all requests (#RequestMapping("/**")) but wish to serve static resources /${contextPath}/static/... using the <mvc:resources.../> facility. The resources are located in subdirectories of the top-level webapp directory.
Based on reading other questions on SO I added
<mvc:resources mapping="/static/**" location="/" />
to my Spring configuration.
No matter what I do, requests that I expect to be resolved as a static resource file are being sent to the request handler method of my controller instead. The only thing I can think of is that the #RequestMapping annotation has precedence over mvc:resources, but that doesn't make a lot of sense.
I have verified that the resource URLs are being generated correctly, i.e. the template line
<link rel="stylesheet" href="${contextPath}/static/css/gallery.css">
generates
<link rel="stylesheet" href="/gallery/static/css/gallery.css">
and the request is being received by the Tomcat server, just routed to the wrong place.
I've read most of the questions on SO about this subject and I believe I'm doing it right (see for example Trying to get mvc resources to serve my static resources), but clearly I'm missing something obvious.
Environment
Eclipse Luna
Java 8
Tomcat 8
Freemarker 2.3.23
Spring 4.2.0
Windows 7 SP1
Deployed Layout
Standard Java EE Tomcat directory structure
webapps
|- gallery
|- css
|- images
|- js
|- META-INF
|- WEB-INF
|- classes
|- lib
|- views
Tomcat Context Definition
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="D:\dev\tools\apache-tomcat-8.0.24\wtpwebapps\gallery"
path="/gallery" reloadable="true"
source="org.eclipse.jst.j2ee.server:gallery"/>
Spring Servlet Config
WEB-INF/main-servlet.xml
...
<mvc:resources mapping="/static/**" location="/" />
<mvc:annotation-driven/>
<context:component-scan base-package="com.mysite.gallery"/>
...
I've tried all possible orderings of these statements but that seems to have no effect. I also tried adding
<mvc:default-servlet-handler/>
with no effect.
WEB-INF/web.xml
Standard Spring MVC DispatcherServlet config
...
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>main</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
...
RequestMapping method
...
#RequestMapping("/**")
public String gallery(ModelMap modelMap, HttpServletRequest req, HttpServletResponse resp)
{
etc...
Freemarker Template
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="${contextPath}/static/css/photoswipe.css">
<link rel="stylesheet" href="${contextPath}/static/css/default-skin/default-skin.css">
<link rel="stylesheet" href="${contextPath}/static/css/gallery.css">
<script src="${contextPath}/static/js/photoswipe.min.js"></script>
<script src="${contextPath}/static/js/photoswipe-ui-default.min.js"></script>
</head>
<body>
<div>
...
You gave the answer in your question: The only thing I can think of is that the #RequestMapping annotation has precedence over mvc:resources, but that doesn't make a lot of sense.
You may think it does not make sense, but is is how Spring fellow decided it should be, at least by default...
But you have different ways for static ressources to have precedences on the #RequestMapping annotated controller.
The simplest way is to add an "order=0" attribute to the <mvc:resources.../> tag :
<mvc:resources mapping="/static/**" location="/" order="0"/>
and to write it in WEB-INF/main-servlet.xml before <mvc:annotation-driven/>
I tested in with Spring 3.2.4 and it works like you want. But it looks like driving spring framework where it was not designed for, so I cannot guarantee that it will work on other versions.
You could also map the dispatcher servlet to / instead of /*. That way all static resources (and also JSP) that can be served directly by the servlet container will be. The main caveat with that mapping, is that root will no longer be served by Spring dispatcher servlet. One possible workaround it to use a /home URL for the root controller, and put a welcome file in web xml :
<servlet>
<servlet-name>main</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/home</welcome-file>
</welcome-file-list>
That way, you to not even need to use /mappings/images/img.gif, just use /images/img.gif/.
But there is another caveat, that I have always accepted (because I could not find any workaround): if /url is served by one controller, /url.jsp or /url.jpeg will give a 404 error. As the container default servlet knows about .jpeg or .jsp files it will catch the request and fail.

Spring MVC resource TAG in MVC configuration

I'm trying to find a clean solution to configure spring mvc to handle requests to static resources using the tag resources in my configuration.
It works well so far for simple configuration like:
<mvc:resources mapping="/img/**" location="file:${environment_variable}/mystaticfolder/img/" cache-period="31556926" />
<mvc:resources mapping="/css/**" location="file:${environment_variable}/mystaticfolder/css/" cache-period="31556926" />
and so on..
But i would like to be able to redirect the requests coming with a path containing "content" (always static files)+ specific_folder with some kind of regular expression (like rewrite rules).
For example:
<mvc:resources mapping="/content/${specificfolder}**"
location="file:${environment_variable}/content/${specificfolder}/" cache-period="31556926" />
Without doing a configuration for each folder under content.
Is that possible ?.
I could not find some detail about what i can put in the "location" attribute of the tag (a link could be useful too)
Thanks in advance for any tips you can share.
Regards.
S.

Spring mvc does not find my /opt/ path

I'm trying to access to static resources outside context root with spring mvc (yes, it's possible), but the "file:/opt/final-test/target/**" is red and I cannot access to anything. (404).
<mvc:resources mapping="/generatedThumbnails/" location="file:/opt/final-test/target/**" />
I already tried to put :
file:/opt/final-test/target/**
file:/opt/final-test/target/
file:/opt/final-test/target
but nothing is good.
Can you help me ? Thanks
Add two stars to the mapping /generatedThumbnails/** :
<mvc:resources mapping="/generatedThumbnails/**" location="file:/opt/final-test/target/**" />

Spring can't load my css files

Spring can't load my css files and this is my architecture:
Project
Webcontent
WEB-INF
pages
index.jsp
css
jquery-ui.css
You can put the css file and other files like javascript, images in the folder resources
Project
Webcontent
resources
css
jquery-ui.css
WEB-INF
pages
index.jsp
And put the following line in spring configuration
<mvc:resources mapping="/resources/**" location="/resources/" />
And give the reference in jsp pages like
<link href="${pageContext.request.contextPath}/resources/css/jquery-ui.css"
rel="stylesheet">
As fvu explained, the content inside WEB-INF is not accessible over HTTP. The Webcontent directory in
your directory structure looks like it was created for this particular purpose: storing CSS files, images and JavaScript files.
Even after you move your CSS files, they will not be accessible over HTTP automatically because Spring MVC will intercept these
HTTP requests. You need to use the <mvc:resources> tag in your bean configuration:
<mvc:resources mapping="/webcontent/**" location="/Webcontent/" />
Your CSS files will be accessible at URLs like the following:
http://localhost:8080/you-app-name/webcontent/...
There is a lot of information on <mvc:resources> at Stackoverflow.

Integrating Twitter Bootstrap within a SpringMVC application

I'm starting out with building basic applications in SpringMVC. At the same time, I wanted to use some easy to setup UI frameworks like Twitter Bootstrap. But, No clue on how to set it up.
Question:
Where do I place the downloaded bootstrap folder?
What I have so far.
I would put these in src/main/resources NOT under WEB-INF. These don't need to be protected.
Also, make sure you tell Spring where they are in your dispatcher servlet config file as per the documentation.
<mvc:resources mapping="/resources/**" location="/resources/" />
If you're using Spring security as well you'll need to make sure that the resources are not protected.
<http pattern="/resources/**" security="none"/>
You don't need the .less files unless you plan to compile custom css. Maven projects, you typically place them in the resources folder. resources/assets/css and resources/assets/js
In the JSP:
<spring:url scope="page" var="bootstrapStylesheetUrl" value="/resources/assets/css/bootstrap.css"/>
<spring:url scope="page" var="bootstrapResponsiveStylesheetUrl" value="/resources/assets/css/bootstrap-responsive.css"/>
<spring:url scope="page" var="bootstrapJavascriptUrl" value="/resources/assets/js/bootstrap.js"/>
And then in the head tag
<script src="${pageScope.bootstrapJavascriptUrl}"></script>
<link rel="stylesheet" href="${pageScope.bootstrapStylesheetUrl}"/>
<link rel="stylesheet" href="${pageScope.bootstrapResponsiveStylesheetUrl}"/>
Also, don't forget to add the spring taglib to the top of your jsp
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
In your spring servlet context config(productmgmt-servlet.xml) add the line:
<mvc:resources mapping="/resources/**" location="classpath:/"/>

Resources