4

I have been testing some request mapping in Spring MVC, and I came across a strange situation in my application. I decided to create a simple cenario so that you can understand my problem. I will first show you the details of my project (the source), and then I'll get to my question.

I have the following directory structure in my project:

+webapp
  +WEB-INF
    +recursos
      +estilos
        test.css
    +spring
      fronte-beans.xml
    +views
      +testes
        page1.jsp
        page2.jsp
  web.xml

My Tomcat deployment descriptor:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.4">

    <display-name>Archetype Created Web Application</display-name>

    <servlet>
        <servlet-name>fronte</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/spring/fronte-beans.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>fronte</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

My application context for DispatcherServlet:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd ">

    <mvc:annotation-driven />

    <mvc:resources mapping="/recursos/**" location="/WEB-INF/recursos/" />

    <context:component-scan base-package="com.regra7.minhaapp.contro" />

    <bean id="handlerMapping"
        class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    </bean>

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

My controller class for page1.jsp:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value="/path")
public class TestController 
{
    @RequestMapping(value="/to/something")
    public String getPage()
    {
        return "testes/page2";
    }
}

My page1.jsp:

<!DOCTYPE html>

<%@ page 
    language="java" 
    contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<html lang="pt-BR">

    <!-- ############################################### -->
    <!--                                          HEADER -->
    <!-- ############################################### -->

    <head>
        <title>Test Page</title>
        <meta name="author"                 content="RDS"       />
        <meta name="description"            content="? ? ?" />

        <meta charset="UTF-8" />

        <link rel="stylesheet" type="text/css" href="recursos/estilos/test.css" media="all" />
    </head>

    <!-- ############################################### -->
    <!--                                            BODY -->
    <!-- ############################################### -->

    <body>

        <h1>PAGE 1</h1>
        <p>This is a test, p1.</p>
        <p>This is a test, p2.</p>
        <p>This is a test, p3.</p>

        <a href="${pageContext.request.contextPath}/path/to/something">CLICK TO PAGE 2</a>

    </body>

</html>

I can access page1.jsp and page2.jsp smoothly, but the CSS file of page2.jsp ends up not being found. The following text is printed on my console:

dez 29, 2014 8:16:22 PM org.springframework.web.servlet.PageNotFound noHandlerFound
WARNING: No mapping found for HTTP request with URI [/testeSpringMvc/path/to/recursos/estilos/test.css] in DispatcherServlet with name 'fronte'

For what reason "/path/to" is being included in the resulting path? If I try to add different combinations of mapping, both class or method-level, the same thing happens. However, if I map the link to a query string (URL) as follows, the file is found without problems...

page1.jsp:

<a href="${pageContext.request.contextPath}/?cd=page2">CLICK TO PAGE 2</a>

Controller:

@Controller
@RequestMapping(value="/")
public class TestController
...
@RequestMapping(params="cd=page2")
public String getPage()

What's happening? How can I set a path I want so that my pages use and find the necessary resources? I'm trying to separate pages in different paths so that I can apply the security features from Tomcat (security constraints).

NOTE: I've tried using contextPath to help me in setting the CSS file path, but nothing worked. In fact, the situation worsened because Page1.jsp also turned out not having stylization:

<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}recursos/estilos/test.css" media="all" />

As always, thank you for your attention and time.

Loa
  • 2,117
  • 3
  • 21
  • 45

4 Answers4

3

Same was happening to me, and I found a solution. I hope this can help someone else:

As you see in the error message, paths you use for resources /testeSpringMvc/path/to/recursos/estilos/test.css are trying to be resolved by Spring's DispatchServlet.

This happens because in your web.xml file you have the following:

<servlet-mapping>
    <servlet-name>fronte</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Your fronte servlet will try to resolve anything that starts with /.

Just add a simple extension to you <url-pattern>. Something like <url-pattern>/*.html</url-pattern> should do the job.

Paco Lagunas
  • 320
  • 1
  • 13
  • Thank you for sharing this. Surely I'm not the only one going through this. I am very grateful for your attention and availability. I'm sure others will see it too, as they may be going through the same situation.Thank you! :) – Loa Mar 05 '15 at 19:36
2

I just found the answer to my problems. I will leave here the solution, but unfortunately I did not understand how it solves the seen scenario.

I have found that this can be solved with JSTL. I read the JSTL documentation, and all I found was this description:

Creates a URL with optional query parameters.

If reference to the CSS file is changed by the following sentence, the problem will be solved:

<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<link rel="stylesheet" type="text/css" href="<c:url value="/recursos/estilos/test.css" />" media="all" />

If any moderator see this and know the explanation of how this is resolved, I kindly ask you to expose it here. Edit my answer, or comment it out, please. I'm sure other people can have the same doubt as me in the future.

Thank you all for the attention and time.

Loa
  • 2,117
  • 3
  • 21
  • 45
0

Take a look at this blog entry. The relevant passage is:

If I want to apply main.css to url: www.mysite.com/index.html, I need to use following construction in HTML code:

< link href="resources/css/main.css" rel="stylesheet" type="text/css"/ >  

If I want to apply main.css to url: www.mysite.com/some/location.html, I need to use following construction in HTML code:

< link href="../resources/css/main.css" rel="stylesheet" type="text/css"/ >

As a possible workaround, perhaps this might work:

<mvc:resources mapping="/**/recursos/**" location="/WEB-INF/recursos/" />
Don Bottstein
  • 1,640
  • 13
  • 17
  • Thanks for answering. I tried to change my application context file, and then also tried to change page2.jsp as mentioned. Unfortunately I did not get results. Would you have any more suggestions? Thanks either way. – Loa Dec 30 '14 at 01:05
  • Just so I'm clear, you tried changing the css link in your page2.jsp to be: ``? – Don Bottstein Dec 30 '14 at 01:13
  • I had not done it in fact. I tried to something else before. After reading your comment, I tried what you suggested, and unfortunately it did not work... I am really frustrated with this, and I know I'm doing something wrong. I'm sure there are ways to map this way keeping the styling of a page. Did you'd know some source that would indicate to me that I look? I would be eternally grateful. In the future, if I find the answer, I will share with you all here. Thank you anyway. – Loa Dec 30 '14 at 19:40
0

You can access resource as given below.

     <link rel="stylesheet" type="text/css" href="/recursos/estilos/test.css" media="all" />

you are missing / at the beginning

kamoor
  • 2,909
  • 2
  • 19
  • 34
  • Thanks for responding, but it did not work. Now page1.jsp also has no CSS styling. – Loa Dec 30 '14 at 01:00
  • when you hit the css url directly. what is returning? – kamoor Dec 30 '14 at 01:13
  • Can you open war file and see where is test.css stored? – kamoor Dec 30 '14 at 14:02
  • When I look at the source code of the page, the browser indicates that the resource could not be found. I do not do the distribution of my application in WAR yet, because I'm just testing it. But test.css is within the "styles" folder, which is inside "resources," which in turn is inside "WEB-INF", and "webapp" (the directory structure is in scope of my question). – Loa Dec 30 '14 at 19:44
  • Do you want to share project in github? – kamoor Jan 01 '15 at 15:31