0

I'm trying to serve an static resource (css file).

I already register the location and handler

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
      registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/");
    }
}

so the Tomcat's Logger displays the correct mapping to resource

Mapped URL path [/resources/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]

When the browser renders the view, the inspector displays a 404 error trying to get the static resource.

enter image description here

AppInitializer.java

@Configuration
@ComponentScan("com.learning")
@EnableWebMvc
public class ApplicationInitializer extends WebMvcConfigurerAdapter implements WebApplicationInitializer {

    private final Logger LOGGER = Logger.getLogger(ApplicationInitializer.class.getName());
    public static final String DISPATCHER_SERVLET_NAME = "dispatcher";

    @Autowired
    private ApplicationContext applicationContext;

    public ApplicationInitializer() {
    }

    //region Context Initialization Area
    public void onStartup(ServletContext servletContext) throws ServletException {
        WebApplicationContext springContext = getSpringApplicationContext();
        MyDispatcherServlet dispatcherServlet = new MyDispatcherServlet(springContext);

        servletContext.addListener(new ContextLoaderListener(springContext));
        servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
        servletContext.getSessionCookieConfig().setHttpOnly(true);

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, dispatcherServlet);
        dispatcher.addMapping("/");
        dispatcher.setLoadOnStartup(1);

    }

    private WebApplicationContext getSpringApplicationContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        LOGGER.info(String.format("Registering springApplicationContext: %s", context));
        // Loads into container first
        context.register(ApplicationInitializer.class);
        LOGGER.info(String.format("Registration success of springApplicationContext: %s", context));
        return context;
    }
    //endregion

    //region ViewResolver Region
    @Bean
    public ViewResolver viewResolver() {
        //Runs after coontroller ends its execution. It receives the view name to be processed.
        ThymeleafViewResolver resolver = new ThymeleafViewResolver();
        resolver.setTemplateEngine(templateEngine());
        resolver.setCharacterEncoding("UTF-8");
        return resolver;
    }

    @Bean
    public TemplateEngine templateEngine() {
        // Processes the template
        SpringTemplateEngine engine = new SpringTemplateEngine();
        engine.setEnableSpringELCompiler(true);
        engine.setTemplateResolver(templateResolver());
        return engine;
    }

    private ITemplateResolver templateResolver() {
        //Resolves templates with provided prefix and suffix
        SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
        resolver.setApplicationContext(applicationContext);
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".html");
        resolver.setTemplateMode(TemplateMode.HTML);
        return resolver;
    }
    //endregion

    //region ResourceHandler Region
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/");
    }
    //endregion
}

Hello.html

h1 {
    color: red;
    text-align: center;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href="/resources/css/MyCss.css" th:href="@{/resources/css/MyCss.css}"/>
</head>
<body>
    <h1 th:text="'Hello ' + ${name}">Hello World</h1>
</body>
</html>

It supposed to displays as the running snippet... but as I mentioned, the app is not able to find and load the resource.

Log File

classpath

enter image description here

enter image description here

Any help?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Rafael Reyes
  • 2,615
  • 8
  • 34
  • 51
  • Turn your logs to debug or trace, show us what Spring spits out. – Sotirios Delimanolis Sep 23 '16 at 20:09
  • Done, check my edit. @SotiriosDelimanolis – Rafael Reyes Sep 23 '16 at 21:02
  • Those logs show _Successfully completed request_. – Sotirios Delimanolis Sep 23 '16 at 21:04
  • You're looking for something on the classpath ' /resources/css/MyCss.css' What is your classpath like? How are you deploying this? Where is the MyCss in your war? (or Jar?) – Koos Gadellaa Sep 23 '16 at 21:07
  • 1
    Please add the resource tree – reos Sep 23 '16 at 21:18
  • Please check my edit @KoosGadellaa – Rafael Reyes Sep 25 '16 at 17:34
  • Please check my edit @reos – Rafael Reyes Sep 25 '16 at 17:34
  • Can you retrieve the css through the webserver? And what would it's actual URL be? it's probably http://localhost:8080/webapp_name/resources/css/MyCss.css, as @MosheArad says. If you verified / found out what it is, you then need to modify the link. Maybe instead of using /resources/css/MyCss, use ../resources/css/MyCss ? Or something similar. But first verify it is being served (I'm guessing it is, just at a different location). Then either modify the location at which it is being served, or the location where it is referred to. – Koos Gadellaa Sep 26 '16 at 07:28
  • Please check my edit, is not served by the webserver @KoosGadellaa – Rafael Reyes Sep 26 '16 at 12:10
  • So figure out where it is being served, if at all. You're using `registry.addResourceHandler("/resources/**").addResourceLocations("classpath:/resources/");` and your css is located under src/main/webapp/resources. Are they being served from the WEB-INF? (and thus, your classpath being "classpath:/WEB-INF/resources/") Kinda depends on your packaging if you do something special. Do a maven install, and open the war as a zip. You can then see under what directory it is being located. That's the location where it should be referred to in your classpath. – Koos Gadellaa Sep 26 '16 at 12:31
  • Check my edit pleasse, is pointing to the right path @KoosGadellaa – Rafael Reyes Sep 26 '16 at 13:09
  • According to http://stackoverflow.com/questions/25061237/spring-4-addresourcehandlers-not-resolving-the-static-resources, what happens if you do not use `classpath:/resources/' , but `/resources/` (i.e. without the classpath?) – Koos Gadellaa Sep 26 '16 at 13:58

1 Answers1

1

http://localhost:8080/resources/css/MyCss.css

you are missing the webapp name:

http://localhost:8080/webapp_name/resources/css/MyCss.css

Within your: link rel="stylesheet" ...

Use the Spring URL tag, in order to resolve your URL better.

Here is how i use to import bootstrap.min.css:

<link rel="stylesheet" href='<spring:url value="/resources/bootstrap/bootstrap.min.css"/>' type="text/css" />

Don't forget to add the taglib, like this:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
Moshe Arad
  • 3,587
  • 4
  • 18
  • 33
  • I'm using Thymeleaf and .html files for views, how can I reference the taglib in those files? When I use the import following the way you pointed I get this error in te browser inspector: 2http://localhost:8080/%3Cspring:url%20value=%22/resources/css/MyCss.css%22/%3E Failed to load resource: the server responded with a status of 404 – Rafael Reyes Sep 25 '16 at 17:46
  • I'm not familiar with Thymeleaf, but from wiki I see that it's servlet-based, and JSP files are basically Servlet file after Jasper component of Tomcat translate it into servlet. You suppose to add this taglib as a directive to a JSP file. – Moshe Arad Sep 25 '16 at 18:05