Salman Riaz
Salman Riaz

Reputation: 51

Spring MVC Multiple Controllers with same @RequestMapping

I am trying to make a web app that allows user to login from landing page index.htm. this action is mapped with a LoginController that after successful login takes user back to same index.htm but as logged in user and greets user with welcome message.

index.htm also have another form named itemform, that allows user to add in item name as text. This action is controlled by itemController.

My problem is both my LoginController and itemController have same @RequestMapping and hence I get this error:

Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0' defined in ServletContext resource [/WEB-INF/tinga-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot map handler [loginController] to URL path [/index.htm]: There is already handler [com.tinga.LoginController@bf5555] mapped.

Cannot map handler [loginController] to URL path [/index.htm]: There is already handler [com.tinga.LoginController@bf5555] mapped.

How should I go about tackling this problem?

Upvotes: 4

Views: 16327

Answers (4)

WilQu
WilQu

Reputation: 7423

Add an hidden parameter in your forms to differentiate them, then differentiate them by adding the params attribute in the annotation of your post methods.

<form:hidden name="hiddenAction" value="login" />
<form:hidden name="hiddenAction" value="item" />

@RequestMapping(method = RequestMethod.POST, params = {"hiddenAction=login"})
@RequestMapping(method = RequestMethod.POST, params = {"hiddenAction=item"})

Upvotes: 0

Matt
Matt

Reputation: 11815

@RequestMapping(value="/login.htm")
public ModelAndView login(HttpServletRequest request, HttpServletResponse response) {
   // show login page if no parameters given
   // process login if parameters are given
}

@RequestMapping(value="/index.htm")
public ModelAndView index(HttpServletRequest request, HttpServletResponse response) {
   // show the index page
}

Finally, you'll need a servlet filter to intercept the requests and if you're not requesting the login.htm page, you'll have to check to make sure the user is logged in. If you, you allow the filterchain to proceed. If not, you issue a forward to /login.htm

public class LoginFilter implements Filter {
  public void doFilter(ServletRequest request,  ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

    HttpServletRequest httpServletRequest = (HttpServletRequest)request;

    boolean loggedIn = ...; // determine if the user is logged in.
    boolean isLoginPage = ...; // use path to see if it's the login page

    if (loggedIn || isLoginPage) {
        chain.doFilter(request, response);
    }
    else {
        request.getRequestDispatcher("/login.htm").forward(request, response);
    }
  }
}

And in the web.xml

Example from my deployment descriptor:

<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>LoginFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>  
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping>

This is all from memory, but it should give you the general idea of how to go about this.

Upvotes: 2

Vitor Braga
Vitor Braga

Reputation: 2212

Maybe in your controllers with the same @RequestMapping you should define the Method (GET, POST...), like this way:

@RequestMapping(value="/index.htm", method = RequestMethod.GET)
@RequestMapping(value="/index.htm", method = RequestMethod.POST)

The controller with the GET method you use to render the form and bind the data (some object) to it. The controller with POST method you usually use to process the submission and validation of the form.

Upvotes: 0

Rahul Agrawal
Rahul Agrawal

Reputation: 8971

Request Mapping for all controllers should be unique in Spring MVC.

Upvotes: 1

Related Questions