Reputation: 51
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
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
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
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
Reputation: 8971
Request Mapping for all controllers should be unique in Spring MVC.
Upvotes: 1