Spring MVC: how to create a default controller for index page?

SpringSpring Mvc

Spring Problem Overview


I'm trying to do one of those standard spring mvc hello world applications but with the twist that I'd like to map the controller to the root. (for example: http://numberformat.wordpress.com/2009/09/02/hello-world-spring-mvc-with-annotations/ ) So the only real difference is that they map it to host\appname\something and I'd like to map it to host\appname.

I placed my index.jsp in src\main\webapp\jsp and mapped it in the web.xml as the welcome file. I tried:

@Controller("loginController")
public class LoginController{

  @RequestMapping("/")
  public String homepage2(ModelMap model, HttpServletRequest request, HttpServletResponse response){
	System.out.println("blablabla2");
	model.addAttribute("sigh", "lesigh");
	return "index";
  }

As my controller but I see nothing appear in the console of my tomcat. Does anyone know where I'm messing up?

My web.xml:

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

	<!-- Index -->
	<welcome-file-list>
		<welcome-file>/jsp/index.jsp</welcome-file>
	</welcome-file-list>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
	</context-param>

	<servlet>
		<servlet-name>springweb</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>springweb</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

The mvc-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:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<context:annotation-config />
	<context:component-scan base-package="de.claude.test.*" />

	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>

</beans>

I'm using Spring 3.0.5.release

Or is this not possible and do I need to put my index.jsp back in the root of the web-inf and put a redirect to somewhere inside my jsp so the controller picks it up?

Spring Solutions


Solution 1 - Spring

I had the same problem, even after following Sinhue's setup, but I solved it.

The problem was that that something (Tomcat?) was forwarding from "/" to "/index.jsp" when I had the file index.jsp in my WebContent directory. When I removed that, the request did not get forwarded anymore.

What I did to diagnose the problem was to make a catch-all request handler and printed the servlet path to the console. This showed me that even though the request I was making was for http://localhost/myapp/, the servlet path was being changed to "/index.html". I was expecting it to be "/".

@RequestMapping("*")
public String hello(HttpServletRequest request) {
	System.out.println(request.getServletPath());
	return "hello";
}

So in summary, the steps you need to follow are:

  1. In your servlet-mapping use <url-pattern>/</url-pattern>
  2. In your controller use RequestMapping("/")
  3. Get rid of welcome-file-list in web.xml
  4. Don't have any files sitting in WebContent that would be considered default pages (index.html, index.jsp, default.html, etc)

Hope this helps.

Solution 2 - Spring

The redirect is one option. One thing you can try is to create a very simple index page that you place at the root of the WAR which does nothing else but redirecting to your controller like

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:redirect url="/welcome.html"/>

Then you map your controller with that URL with something like

@Controller("loginController")
@RequestMapping(value = "/welcome.html")
public class LoginController{
...
}

Finally, in web.xml, to have your (new) index JSP accessible, declare

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

Solution 3 - Spring

We can simply map a Controller method for the default view. For eg, we have a index.html as the default page.

@RequestMapping(value = "/", method = GET)
public String index() {
    return "index";
}

once done we can access the page with default application context.

E.g http://localhost:8080/myapp

Solution 4 - Spring

It works for me, but some differences:

  • I have no welcome-file-list in web.xml
  • I have no @RequestMapping at class level.
  • And at method level, just @RequestMapping("/")

I know these are no great differences, but I'm pretty sure (I'm not at work now) this is my configuration and it works with Spring MVC 3.0.5.

One more thing. You don't show your dispatcher configuration in web.xml, but maybe you have some preffix. It has to be something like this:

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

If this is not your case, you'll need an url-rewrite filter or try the redirect solution.

EDIT: Answering your question, my view resolver configuration is a little different too:

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

Solution 5 - Spring

It can be solved in more simple way: in web.xml

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>
<welcome-file-list>
    <welcome-file>index.htm</welcome-file>
</welcome-file-list>

After that use any controllers that your want to process index.htm with @RequestMapping("index.htm"). Or just use index controller

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <props>
            <prop key="index.htm">indexController</prop>
        </props>
    </property>
<bean name="indexController" class="org.springframework.web.servlet.mvc.ParameterizableViewController"
      p:viewName="index" />
</bean>

Solution 6 - Spring

Just put one more entry in your spring xml file i.e.mvc-dispatcher-servlet.xml

<mvc:view-controller path="/" view-name="index"/>

After putting this to your xml put your default view or jsp file in your custom JSP folder as you have mentioned in mvc-dispatcher-servlet.xml file.

change index with your jsp name.

Solution 7 - Spring

One way to achieve it, is by map your welcome-file to your controller request path in the web.xml file:

[web.xml]

<web-app ...

<!-- Index -->
<welcome-file-list>
    <welcome-file>home</welcome-file>
</welcome-file-list>

</web-app>

[LoginController.java]

@Controller("loginController")
public class LoginController{

@RequestMapping("/home")
public String homepage2(ModelMap model, HttpServletRequest request, HttpServletResponse response){
    System.out.println("blablabla2");
    model.addAttribute("sigh", "lesigh");
    return "index";
}

Solution 8 - Spring

The solution I use in my SpringMVC webapps is to create a simple DefaultController class like the following: -

@Controller
public class DefaultController {

    private final String redirect;

    public DefaultController(String redirect) {
        this.redirect = redirect;
    }

    @RequestMapping(value = "/")
    public ModelAndView redirectToMainPage() {
        return new ModelAndView("redirect:/" + redirect);
    }

}

The redirect can be injected in using the following spring configuration: -

<bean class="com.adoreboard.farfisa.controller.DefaultController">
    <constructor-arg name="redirect" value="${default.redirect:loginController}"/>
</bean>

The ${default.redirect:loginController} will default to loginController but can be changed by inserting default.redirect=something_else into a spring properties file / setting an environment variable etc.

As @Mike has mentioned above I have also: -

  • Got rid of <welcome-file-list> ... </welcome-file-list> section in the web.xml file.
  • Don't have any files sitting in WebContent that would be considered default pages (index.html, index.jsp, default.html, etc)

This solution lets Spring worry more about redirects which may or may not be what you like.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionHugoView Question on Stackoverflow
Solution 1 - SpringMike M. LinView Answer on Stackoverflow
Solution 2 - SpringEmmanuel BalleriniView Answer on Stackoverflow
Solution 3 - SpringSathish Kumar ThiyagarajanView Answer on Stackoverflow
Solution 4 - SpringsinuhepopView Answer on Stackoverflow
Solution 5 - SpringRoman PlatonovView Answer on Stackoverflow
Solution 6 - SpringShalin PatelView Answer on Stackoverflow
Solution 7 - SpringDaniel De LeónView Answer on Stackoverflow
Solution 8 - SpringbobmarksieView Answer on Stackoverflow