I'm developing a webapp using Spring MVC/JSP with Java 11, and SpringMVC 5.2.0, which started with config files, but I wanted to give programatic config (through java) a try. I've got the Servlet running, and I've successfully made the login page to "intercept" any other .jsp view if the user is not logged... However, I haven't been able to get my resources from my resource folder.
Every resource that should be loaded from there (e.g.
<link type="image/png" rel="icon" href="${contextPath}/resources/img/icon.png">) I get a 404 response, and in my IDE (Netbeans 11) I get the following message in the Network Monitor:
Request URL: http://localhost:8080/icon.png
Method: GET
Status: 404
Note: The URL should be http://localhost:8080/dragonline/resources/img/icon.png (<c:set var="contextPath" value="${pageContext.request.contextPath}"/>)
Here's my config java file:
package com.midknightmunch.dragonline.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.ResourceBundleViewResolver;
import org.springframework.web.servlet.view.JstlView;
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = {"com.midknightmunch.dragonline"})
public class WebConfig implements WebMvcConfigurer{
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
#Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
//registry.addResourceHandler("/img/**").addResourceLocations("/resources/img/");
//registry.addResourceHandler("/css/**").addResourceLocations("/resources/css/");
//registry.addResourceHandler("/js/**").addResourceLocations("/resources/js/");
//I've tried with and without these 3 (the commented ones)
}
#Bean
public ViewResolver internalViewResolver() {
InternalResourceViewResolver bean = new InternalResourceViewResolver();
bean.setViewClass(JstlView.class);
bean.setPrefix("/WEB-INF/views/");
bean.setSuffix(".jsp");
bean.setOrder(0);
return bean;
}
#Bean
public ViewResolver resourceBundleViewResolver() {
ResourceBundleViewResolver bean = new ResourceBundleViewResolver();
bean.setBasename("views");
bean.setOrder(1);
return bean;
}
#Bean("messageSource")
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
String[] basenames = {"classpath:validation"};
bean.setBasenames(basenames);
return bean;
}
}
And my project structure:
icon.png: dragonline/src/main/webapp/resources/img/icon.png
views(including the jsp trying to import this image): dragonline/src/main/webapp/WEB-INF/views/login.jsp
I've tried moving the resources folder everywhere, but everytime I get a 404.
Please, any help would be appreciated.
I figured it out. The problem was that I did not grant permission in my Spring Security config file to access the resources folder, so I solved it by adding:
http.authorizeRequests().antMatchers("/resources/**").permitAll()
in my WebSecurityAdapter's config() method
Related
While trying to do a simple program about the Spring MVC I got always the same error when running http://localhost:8080/project_name/:
404 - the requested resource is not available
This is the architecutre of the project:
src
| +--com
| +--memorynotfound
| +--config
| |--ServletInitializer.java
| |--WebConfig.java
| +--controller
| |--HomeController.java
| +--resources
| +--webapp
| +--WEB-INF
| +--views
| |--index.jsp
Here is the files in the package com.memorynotfound.config:
ServletInitializer.java
package com.memorynotfound.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { WebConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
}
WebConfig.java
package com.memorynotfound.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages="com.memorynotfound")
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
Files in the package com.memorynotfound.controller:
HomeController.java
package com.memorynotfound.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.ui.ModelMap;
#Controller
#RequestMapping("/")
public class HomeController {
#RequestMapping(method = RequestMethod.GET)
public String index(ModelMap model){
System.out.println("This is a test ================>");
model.addAttribute("message", "Spring MVC Java Configuration Example");
return "index";
}
}
And finally the Jsp file:
index.jsp
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Spring MVC Java Configuration Example</title>
</head>
<body>
${message}
</body>
</html>
I thought that when you were using Spring MVC without a web.xml file, you needed to supply an implementation of WebApplicationInitializer
Without such an initializer, you would still need to provide a web.xml file.
Minimally your WebApplicationInitializer instance should probably use setLoadOnStartup(1) and provide a mapping for the dispatcher.
From the referenced web page above
public class MyWebApplicationInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext container) {
ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet());
registration.setLoadOnStartup(1);
registration.addMapping("/example/*");
}
}
I solved the problem by doing :
right click on the project name and select properties
Select Deployment assembly
Add spring and JTL jars
I'm new to Spring Web MVC and I tried to try Hello world app.
I followed an example from "Spring In Action 4th ed" book which only uses java config (without any XML file). I use Tomcat v7.0 server and servlet 3.
The problem is when I try to go to the home page I get Http 404 error.
The used Java classes are :
DispatcherServlet configuration:
package config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class FirstWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
}
Spring MVC configuration :
package config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan("web")
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
Configuration used to get other Beans (doesn't do any thing in the hello world app)
package config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#ComponentScan(basePackages={"lgmi_cr"},excludeFilters={#Filter(type=FilterType.ANNOTATION, value=EnableWebMvc.class)})
public class RootConfig {
}
Home page controller
package web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class HomeController {
#RequestMapping(value="/")
public String home() {
return "home";
}
}
A JSP file "home" uneder /WEB-INF/views/
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>First app</title>
</head>
<body>
<h1>Hello world</h1>
</body>
</html>
Since it 404 error, my first impression is that it could not find any controller but I don't know why.
Thank you for any help
I have just found the problem.
Actually, I added the external Spring jar files to the project classpath and I forget to add them to myProject/WebContent/WEB-INF/lib.
When I try to go to link http://localhost:8080/ I get "HTTP Status 404", I use Tomcat 7.0.47, and I get the following error : The requested resource is not available.
WebConfig.Java
package config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#EnableWebMvc
#Configuration
#ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter{
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/static/js/**")
.addResourceLocations("/resources/static/js/");
registry.addResourceHandler("/resources/static/css/**")
.addResourceLocations("/resources/static/css/");
registry.addResourceHandler("/resources/static/views/**")
.addResourceLocations("/resources/static/views/");
registry.addResourceHandler("/resources/static/**")
.addResourceLocations("/resources/static/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/");
}
#Bean
public ViewResolver getViewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
WebAppInitalizer.Java
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
public class WebAppInitializer implements WebApplicationInitializer {
private static final String CONFIG_LOCATION = "config";
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("***** Initializing Application for " + servletContext.getServerInfo() + " *****");
// Create ApplicationContext
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.setConfigLocation(CONFIG_LOCATION);
// Add the servlet mapping manually and make it initialize automatically
DispatcherServlet dispatcherServlet = new DispatcherServlet(applicationContext);
ServletRegistration.Dynamic servlet = servletContext.addServlet("mvc-dispatcher", dispatcherServlet);
servlet.addMapping("/");
servlet.setAsyncSupported(true);
servlet.setLoadOnStartup(1);
}
}
MainController.Java
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class MainController {
#RequestMapping("/")
public String homepage(){
return "homepage";
}
}
My project has the following structure :
try to add this #AnnotationDrivenConfig on top of WebConfig and change this #ComponentScan with this #ComponentScan("controller")
Try to add some text into your requestMapping example:
#RequestMapping("/homePage")
and then go to http://localhost:8080/homePage
I am learning Spring MVC from a book called "Spring in Action". However. I am getting 404 error when I hit the correct controller. I am using annotations rather than xml configurations, so it is hard to find from web. You can see the very simple classes and configs I am using
SpittrWebInitializer.java
package spittr.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {RootConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
RootConfig.java
package spittr.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
#Configuration
#ComponentScan(basePackages = "spittr",
excludeFilters = #ComponentScan.Filter(type = FilterType.ANNOTATION,
value = EnableWebMvc.class))
public class RootConfig {
}
WebConfig.java
package spittr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"spittr.web"})
public class WebConfig extends WebMvcConfigurerAdapter {
#Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
HomeController.java
package spittr.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
public class HomeController {
#RequestMapping(value = "/home", method = RequestMethod.GET)
private String home() {
return "home";
}
}
and finally under resources/WEB-INF/views/ package I have one jsp called home.jsp which is like;
<html>
<body>
<h1>Spring 4.0.2 MVC web service</h1>
<h3>Welcome!!!</h3>
</body>
</html>
The can hit the controller, so I know they are initialized without any problem, however, context is not able to find the proper jsp. I appreciate for your help. Thanks
JSP location is not correct WEB-INF location is under src/main/webapp not under resources
I'm new at Spring and thymeleaf, I was working with JSF + Facelets so the method I've choosen thymeleaf layout dialect since it's very similar to Facelets, but, for some reason it's not working in my simple project.
I have this in my config files
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
public class AppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext sc) throws ServletException {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
applicationContext.register(WebConfig.class);
}
}
WebConfig.java
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#Configuration
#EnableWebMvc
#Import(ThymeLeafConfig.class)
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
my TyhmeLeafConfig
import nz.net.ultraq.thymeleaf.LayoutDialect;
import org.springframework.context.annotation.Bean;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
public class ThymeLeafConfig {
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setOrder(1);
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setDialect(new LayoutDialect());
return templateEngine;
}
#Bean
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
}
The layout.html file
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<title>Layout page</title>
<script src="js/jquery.js"></script>
</head>
<body>
<header>
<h1>MASTER!!!!</h1>
</header>
<section layout:fragment="content">
<p>MASTER CODE</p>
</section>
<footer>
<p>My footer</p>
<p layout:fragment="custom-footer">Custom footer here</p>
</footer>
</body>
</html>
The index.html file
<p layout:decorator="layout" layout:fragment="content">
asada
</p>
the problem is that when I open the index.html, it doesn't include anything that it's in the layout.html file, files are next to other in root so no folders are in there, did I miss something in the configuration? thanks
Even using Spring Boot you have to include on your dependencies layout-dialect like this:
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>
Use also the following dependency if you are using Spring Security:
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
Version 3.0.0: Deprecated layout:decorator processor has been deleted
->layout:decorate (https://github.com/ultraq/thymeleaf-layout-dialect/blob/main/CHANGELOG.md
)
According to Read.md in https://github.com/ultraq/thymeleaf-layout-dialect you need to specify file, not file name. So you should have (if they are in the same directory):
<p layout:decorator="layout.html" layout:fragment="content">
asada
</p>
Moreover, Thymeleaf supports layouts that are also very usefull for including framents into code. More info can be found here: http://www.thymeleaf.org/doc/articles/layouts.html
I had a similar problem when i replace
templateEngine.setDialect(new LayoutDialect());
by
templateEngine.addDialect(new LayoutDialect());
this solve it