0

I am writing a Spring MVC web application. I am attempting to configure Spring with Java based configuration, however Spring is unable to detect my controllers without adding additional XML configuration.

My front controller class looks like this:

package no.magnus.controller; 
public class FrontController extends 
   AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {MvcConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }
}

My MVC configuration class:

package no.magnus.config;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"no.magnus"})
public class MvcConfig implements WebMvcConfigurer {

    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver vr = new InternalResourceViewResolver();
        vr.setSuffix(".jsp");
        return vr;
    }
}

A simple home controller:

package no.magnus.controller;
@Controller
public class HomeController {

    @RequestMapping("/home")
    public ModelAndView index() {

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    }
}

Attempting to access url http://localhost:8080/home i get a 404 error. If i add XML based configuration to web.xml as well as xml servlet configuration, the home controller is detected and index.jsp is returned.

subset web.xml:

<servlet>
  <servlet-name>dispatcher</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
  </init-param>
 </servlet>
 <servlet-mapping>
  <servlet-name>dispatcher</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>

dispatcher-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:ctx="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <ctx:annotation-config/>
    <ctx:component-scan base-package="no.magnus"/>

</beans>

http://localhost:8080/home index.jsp returned successfully!

My expectations are that Spring MVC shall be able to detect Spring MVC configuration from java code, making above XML configuration redundant. Please clarify wheter my understanding is mistaken or not. '

Thanks!

EDIT1: Applying code changes suggested by Chris. New issue present. index.jsp is still not returned using only java config. enter image description here

├───java
│   └───no
│       └───magnus
│           ├───config
│           │       MvcConfig.java
│           │
│           └───controller
│                   FrontController.java
│                   HomeController.java
│
└───webapp
    │   result.jsp
    │
    └───WEB-INF       
        │   web.xml
        │
        └───jsp
                index.jsp
3
  • is your HomeControllerlocated in a sub-package of "no.magnus"? Commented Aug 5, 2019 at 20:34
  • Yes! updating above samples with package names. Commented Aug 5, 2019 at 20:41
  • If you don't instruct the DispatcherServlet to load your java based configuration instead of your XML one nothing will happen. So either stick with XML - Java combo or properly configure your DispatcherServlet. Commented Aug 6, 2019 at 9:29

1 Answer 1

0

http://localhost:8080/home wont call your HomeController's index()-Method (/home-Mapping) - in your posted url home is the name of your app and you need a mapping for "/" to index.jsp.

please change your FrontControllerto:

package no.magnus.config; 
public class FrontController extends 
   AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // from
        // return new Class[] {MvcConfig.class};
        // to
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        // from
        // return null;
        // to
        return new Class[] {MvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }
}

your MvcConfig should look like this:

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.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;


@EnableWebMvc
@Configuration
// to also scan subpackages for components
@ComponentScan("no.magnus.**")
public class MvcConfig
        implements
            WebMvcConfigurer {
    @Override
    public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
        WebMvcConfigurer.super.configureDefaultServletHandling(configurer);
    }

    @Override
    public void configureViewResolvers(final ViewResolverRegistry registry) {
        registry.viewResolver(this.jspViewResolver());
        WebMvcConfigurer.super.configureViewResolvers(registry);
    }

    @Bean
    public InternalResourceViewResolver jspViewResolver() {
        final InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setOrder(1);
        // jsp-location!!! - please change it to where your jsp's are located
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
}

and your HomeController should look like this:

package no.magnus.controller;
@Controller("HomeController")
public class HomeController {

    // for the very first start
    // RequestMapping can be replaced with GetMapping
    @GetMapping("/")
    public ModelAndView index() {

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("index");
        return modelAndView;
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

sorry, my english is not best at all - is it ironic? i just compared his posted sources with my config-files that work :|
index.jsp moved from webapp/index.jsp to webapp/WEB-INF/jsp/ per suggestions. Applying suggested code changes now prompts me Directory:/ page accessing localhost:8080. I can only see jsp files which are directly sub of webapp directory. index.jsp is not returned. See edit above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.