In order to overcome LazyInitializationException I've decided to use OpenEntityManagerInViewFilter - here's code from my AppInitializer class which implements WebApplicationInitializer:
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerListener(servletContext);
registerDipsatcherServlet(servletContext);
registerOpenEntityManagerInViewFilter(servletContext);
}
private void registerListener(ServletContext servletContext) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
}
private void registerDipsatcherServlet(ServletContext servletContext) {
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
dispatcherServlet.register(MvcConfiguration.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
customizeRegistration(dispatcher);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
private void registerOpenEntityManagerInViewFilter(ServletContext servletContext) {
FilterRegistration.Dynamic registration = servletContext.addFilter("openEntityManagerInView", new OpenEntityManagerInViewFilter());
registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), false, "/*");
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
}
#Override
protected Class<?>[] getRootConfigClasses() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
protected Class<?>[] getServletConfigClasses() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
protected String[] getServletMappings() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
And here's the #Configuration class which defines the bean:
#Configuration
#EnableTransactionManagement
#EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager", basePackages = "podraza.piotr.eshopper.repository")
public class PersistenceConfiguration {
#Autowired
private JpaVendorAdapter jpaVendorAdapter;
#Value("${jpa.show-sql:false}")
private boolean showSql;
#Value("${jpa.datasource.url}")
private String databaseUrl;
#Value("${jpa.datasource.username}")
private String username;
#Value("${jpa.datasource.password}")
private String password;
#Value("${jpa.datasource.driverClassName}")
private String driverClassName;
/*
#Value("${jpa.hibernate.ddl-auto}")
private String hibernateDdlAuto;
*/
#Bean
public HibernateJpaVendorAdapter hibernateJpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(showSql);
//hibernateJpaVendorAdapter.getJpaPropertyMap().put("hibernate.hbm2ddl.auto", hibernateDdlAuto);
hibernateJpaVendorAdapter.setDatabase(Database.POSTGRESQL);
return hibernateJpaVendorAdapter;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl, username, password);
dataSource.setDriverClassName(driverClassName);
return dataSource;
}
#Bean
public EntityManager entityManager() {
return entityManagerFactory().createEntityManager();
}
#Bean
public EntityManagerFactory entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource());
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("podraza.piotr.eshopper.entity");
lef.setPersistenceUnitName("defaultPersistenceUnit");
lef.afterPropertiesSet();
return lef.getObject();
}
#Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager(entityManagerFactory());
}
}
How can I indicate this bean for the filter?
You are using Spring classes and the first thing you do is not use it. Replace your AppInitializer with the following.
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
}
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {PersistenceConfiguration.class}
}
#Override
protected Class<?>[] getServletConfigClasses() {
throw new Class[] {MvcConfiguration.class};
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
protected Filter[] getServletFilters() {
return return new Filter[] {new OpenentityManagerInViewFilter()};
}
}
Also make sure that in your MvcConfiguration you aren't loading the PersistenceConfiguration class again as that would lead to bean duplication.
Related
I'm new in Spring but i've already made simple spring-mvc projects in spring 5, now i decided to choose new 6 version and do everything the same way, but it does not work.
SpringConfig.java:
#Configuration
#ComponentScan("org.example")
#EnableWebMvc
public class SpringConfig implements WebMvcConfigurer {
private final ApplicationContext applicationContext;
#Autowired
public SpringConfig(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
#Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// IT DOES NOT GO HERE!!!!
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
#Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
return templateResolver;
}
MySpringMVCDispatcherServletInitializer.java:
public class MySpringMVCDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringConfig.class };
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
public void onStartup(ServletContext aServletContext) throws ServletException {
super.onStartup(aServletContext);
registerHiddenFieldFilter(aServletContext);
}
private void registerHiddenFieldFilter(ServletContext aContext) {
aContext.addFilter("hiddenHttpMethodFilter",
new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*");
}
}
I can see that somehow "public void configureViewResolvers(ViewResolverRegistry registry)" is not getting called and as far as I understand it is the problem why no controller is working.
What should I do?
I wanted to make REST Api using Spring.
I have added Tomcat in Run/Debug Configurations.
Here is my Config class
#Configuration
#ComponentScan("com.dashkindima.blog.mvc")
#EnableWebMvc
#EnableTransactionManagement
public class MyConfig {
#Bean
public DataSource dataSource() {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/reeve?autoReconnect=true&allowMultiQueries=true&useSSL=false&useUnicode=true&&characterEncoding=UTF8");
dataSource.setUser("root");
dataSource.setPassword("1234");
} catch (PropertyVetoException e) {
e.printStackTrace();
}
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan("com.dashkindima.blog.mvc.hibernatetest.entity");
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");
sessionFactory.setHibernateProperties(hibernateProperties);
return sessionFactory;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
}
I have also defined WebInitializer class
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
#Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{MyConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[]{"/*"};
}
}
I have tried almost all urls in #RequestMapping like /api , /{app_name}/api but nothing happens.
#RestController
#RequestMapping("/blog/api")
public class MyRESTController {
#Autowired
private LivingComplexService livingComplexService;
#GetMapping("/living")
public List<LivingComplex> showAllLivingComplexes(){
List<LivingComplex> allComplexes = livingComplexService.getAllComplexes();
return allComplexes;
}
}
You can be sure that Service will return livingComplexes. So the problem is in Tomcat.
I created a project with Spring Boot. I am configuring the basic config, but there is a problem in implementing WebMvcConfigurer.
addInterceptors works well, but addViewControllers and addResourceHandlers don't work. There are no errors, but these two methods don't apply.
I think I set it all right, but I can not find the cause. Can I see why?
[Project Structure]
java
--me
----eastglow
------sample
--------controller
----------SampleController.java
------config
--------RootContextConfig.java
--------Application.java
--------DispatcherServletConfig.java
[RootContextConfig.java]
#Configuration
#ComponentScan(
basePackages = {"me.eastglow.*"},
excludeFilters = {#Filter(Controller.class)}
)
public class RootContextConfig {
}
[Application.java]
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
#Override
public void onStartup(ServletContext container) throws ServletException {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(RootContextConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
dispatcherServlet.register(DispatcherServletConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher = container.addServlet("appServlet", new DispatcherServlet(dispatcherServlet));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.json");
dispatcher.addMapping("*.do");
}
}
[DispatcherServletConfig.java]
#Configuration
#ComponentScan(
basePackages={"me.eastglow.*"},
useDefaultFilters = false,
includeFilters={#Filter(Controller.class)},
excludeFilters={#Filter(Service.class), #Filter(Repository.class)}
)
#EnableWebMvc
#PropertySource(
value={"classpath:application-${spring.profiles.active}.properties", "classpath:log4jdbc.log4j2.properties"},
ignoreResourceNotFound = true)
public class DispatcherServletConfig implements WebMvcConfigurer {
private final static String[] RESOURCE_HANDLER_PATH = {"/favicon.ico"
, "/image/**"
, "/js/**"};
private final static String[] RESOURCE_HANDLER_LOCATION = {"/resources/favicon.ico"
, "/resources/image/"
, "/resources/js/"};
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
CacheControl cacheControl = CacheControl.empty().cachePrivate();
registry.addResourceHandler(RESOURCE_HANDLER_PATH).addResourceLocations(RESOURCE_HANDLER_LOCATION).setCacheControl(cacheControl);
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/member/login.do");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BusinessInterceptor()).addPathPatterns("/**");
}
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
List<ViewResolver> resolvers = new ArrayList<>();
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setPrefix("/WEB-INF/views/");
internalResourceViewResolver.setSuffix(".jsp");
resolvers.add(internalResourceViewResolver);
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setViewResolvers(resolvers);
resolver.setContentNegotiationManager(manager);
return resolver;
}
}
[Updated]
public class DispatcherServletConfig implements WebMvcConfigurer {
private final static String[] RESOURCE_HANDLER_PATH = {"/favicon.ico"
, "/image/**"
, "/js/**"};
private final static String[] RESOURCE_HANDLER_LOCATION = {"/resources/favicon.ico"
, "/resources/image/"
, "/resources/js/"};
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
CacheControl cacheControl = CacheControl.empty().cachePrivate();
registry.addResourceHandler(RESOURCE_HANDLER_PATH).addResourceLocations(RESOURCE_HANDLER_LOCATION).setCacheControl(cacheControl);
}
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/member/login.do");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BusinessInterceptor()).addPathPatterns("/**");
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new FormHttpMessageConverter());
converters.add(jacksonMessageConverter()); //Json Message Converter
converters.add(new StringHttpMessageConverter());
converters.add(new ResourceHttpMessageConverter()); // File Transfer Message Converter
}
#Bean
public ViewResolver contentNegotiatingViewResolver(ContentNegotiationManager manager) {
List<ViewResolver> resolvers = new ArrayList<>();
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setViewClass(JstlView.class);
internalResourceViewResolver.setPrefix("/WEB-INF/views/");
internalResourceViewResolver.setSuffix(".jsp");
internalResourceViewResolver.setOrder(2);
resolvers.add(internalResourceViewResolver);
JsonViewResolver jsonViewResolver = new JsonViewResolver();
resolvers.add(jsonViewResolver);
resolvers.add(beanNameViewResolver());
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setViewResolvers(resolvers);
resolver.setContentNegotiationManager(manager);
return resolver;
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer configurer = new TilesConfigurer();
configurer.setDefinitions(new String[]{"/WEB-INF/tiles/tiles.xml"});
configurer.setCheckRefresh(true);
return configurer;
}
#Bean
public TilesViewResolver tilesViewResolver() {
TilesViewResolver viewResolver = new TilesViewResolver();
viewResolver.setOrder(1);
return viewResolver;
}
class JsonViewResolver implements ViewResolver {
#Override
public View resolveViewName(String viewName, Locale locale) {
MappingJackson2JsonView view = new MappingJackson2JsonView();
view.setPrettyPrint(true);
view.setContentType("application/json;charset=UTF-8");
view.setDisableCaching(true);
return view;
}
}
#Bean(name="beanNameViewResolver")
public BeanNameViewResolver beanNameViewResolver(){
BeanNameViewResolver beanNameViewResolver = new BeanNameViewResolver();
beanNameViewResolver.setOrder(0);
return beanNameViewResolver;
}
#Bean(name="jacksonMessageConverter")
public MappingJackson2HttpMessageConverter jacksonMessageConverter(){
return new MappingJackson2HttpMessageConverter();
}
#Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
You are working around Spring Boot instead of using it.
For starters remove the onStartup method of your Application class. Spring Boot takes care of all of that.
Next ditch your RootContextConfig.
2 cleanup your DispatcherServletConfig
#Configuration
#PropertySource(
value={"classpath:log4jdbc.log4j2.properties"},
ignoreResourceNotFound = true)
public class DispatcherServletConfig implements WebMvcConfigurer {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("redirect:/member/login.do");
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new BusinessInterceptor());
}
}
Now in your application.properties (or create one) add the following
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
spring.resources.cache.cache-private=true
The mappings should work by default else place your js and images inside src/main/resources/static or src/main/resources/public.
This is all you need if you properly use Spring Boot (instead of working around it).
I am running Spring 4.3.7 in combination with Spring Security 4.2.2 and configured it using Java config, so no web.xml. Now I want to get a custom 404 page and the way to go seems to be overwriting the createDispatcherServlet Method as described here and here to throw an exception if a page cannot be resolved. I want to use a SimpleMappingExceptionResolver to handle it and return my custom 404 page, but throwing the exception does not even work for me yet. I hope the configurations given below are enough.
MvcWebApplicationInitializer.java
public class MvcWebApplicationInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("resourceUrlEncodingFilter",
new ResourceUrlEncodingFilter());
filterRegistration.setInitParameter("encoding", "UTF-8");
filterRegistration.setInitParameter("forceEncoding", "true");
filterRegistration.addMappingForUrlPatterns(null, true, "/*");
}
#Override
protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext)
{
DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
return dispatcherServlet;
}
}
AppConfig.java
#EnableWebMvc
#Configuration
#ComponentScan(...)
#EnableTransactionManagement
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver
= new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
[...]
}
#Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
#PostConstruct
public void init() {
requestMappingHandlerAdapter.setIgnoreDefaultModelOnRedirect(true);
}
#Bean(name = "simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver exceptionResolver = new MappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("UserNotAccessibleException", "access");
mappings.setProperty("VersionsModelCreationException", "versions");
exceptionResolver.setExceptionMappings(mappings);
exceptionResolver.setDefaultErrorView("index");
exceptionResolver.setExceptionAttribute("exception");
return exceptionResolver;
}
[...]
}
I still only get a
WARN in DispatcherServlet.java:noHandlerFound:1172: No mapping found for HTTP request with URI [/root/notexisting] in DispatcherServlet with name 'dispatcher'
instead of an exception that I might handle with my SimpleMappingExceptionResolver. Any advice?
I want to handle unmapped urls/404 errors in Spring MVC App I have found an example Here SO Answer, I Java Based Configuration and tried in this way
#EnableWebMvc
#Configuration
#ComponentScan(basePackages = { "com.app.controller" })
public class ServletConfigurer extends WebMvcConfigurerAdapter {
private Properties errorResolverProperties;
private Properties errorProperties;
/// Here I'm configuring <beans as mentioned in SO Answer
#Bean
public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
errorResolverProperties = new Properties();
errorProperties = new Properties();
errorProperties.put("/**", pageNotFoundController());
errorResolverProperties.put("mappings", errorProperties);
return simpleUrlHandlerMapping;
}
// this is my Controller
#Bean
public PageNotFoundController pageNotFoundController(){
return new PageNotFoundController();
}
#Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions("/WEB-INF/tiles_xml/tiles.xml");
return tilesConfigurer;
}
}
My controller is
#Controller
public class PageNotFoundController {
#ExceptionHandler
#ResponseStatus(HttpStatus.NOT_FOUND)
public String handleINFException(PageNotFoundException ex) {
return "error";
}
}
and finally the
public class PageNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public PageNotFoundException(String message) {
super(message);
}
}
but it always shows the same error page of Apache not the custom/my error page.
UPDATE
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext rootContext = getWebApplicationContext();
servletContext.addListener(new ContextLoaderListener(rootContext));
servletContext.setInitParameter("defaultHtmlEscape", "true");
// add the dispatcher servlet and map it to /
DispatcherServlet dispatcherServlet = new DispatcherServlet(rootContext);
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
"springDispatcher", dispatcherServlet);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
private AnnotationConfigWebApplicationContext getWebApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.app.config");
return context;
}
}
that is it..
If you want to catch it globally, you need a ControllerAdvice:
#ControllerAdvice
public class ExceptionHandlerController {
public static final String DEFAULT_ERROR_VIEW = "error";
public static final String STATUS_CODE = "404";
public static final String TYPE = "Custom Type";
#ExceptionHandler(value = {NoHandlerFoundException.class})
public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) {
ModelAndView mav = new ModelAndView(DEFAULT_ERROR_VIEW);
mav.addObject("timestamp", new Date());
mav.addObject("status", STATUS_CODE);
mav.addObject("type", TYPE);
mav.addObject("message", String.format("The requested url is: %s", request.getRequestURL()));
return mav;
}
}
Now you need to activate, that an Exception is thrown in case of 404:
#Autowired
public void configureDispatcher(DispatcherServlet dispatcherServlet){
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
}
Insert it in any #Configuration annotated class.
That's it!
UPDATE
Change your class to
#Configuration
public class AppInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext rootContext = getWebApplicationContext();
servletContext.addListener(new ContextLoaderListener(rootContext));
servletContext.setInitParameter("defaultHtmlEscape", "true");
}
private AnnotationConfigWebApplicationContext getWebApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.app.config");
return context;
}
#Autowired
public void configureDispatcher(DispatcherServlet dispatcherServlet){
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
}
}