This SHOULD be pretty simple, but day 2 I cannot figure it out. I have a login.jsp which contains a routine login form. I want to essentially post to itself, and have the controller take action based on whether the form is being hit for the first time or if it is being submitted with data.
What’s happening is that the blank form loads fine, but upon submission of a username and password I get an HTTP 404.
<div id="messageBox">${loginMessage}</div>
<form id="form1" name="form1" method="post" action="/do/login" onsubmit="return validateForm()">
<table>
<tr>
<td>Username:</td>
<td><input name="username" type="text" size=30 value="" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input name="password" type="password" size=30 value="" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" name="submit" value="Login" /></td>
</tr>
</table>
</form>
These are my controller mappings:
@RequestMapping(value = "/login", method=RequestMethod.POST)
public ModelAndView login(@RequestParam("username") String username, @RequestParam("password") String password, Model model) {
if (username == null || password == null) {
// User has not specified all required fields
String loginMessage = "Please complete all fields";
return new ModelAndView("login", "loginMessage", loginMessage);
} else {
// User has specified username and password
// Attempt authentication
Login login = new Login();
isAuthenticated = login.authenticate(username, password);
if (isAuthenticated) {
// Authentication succeeded, return the options page
return viewOptions(model);
} else {
// Authentication failed, return the login page
String loginMessage = "Authentication failed";
return new ModelAndView("login", "loginMessage", loginMessage);
}
}
}
@RequestMapping(value = "/login", method=RequestMethod.GET)
public ModelAndView login(Model model) {
// Blank login screen
String loginMessage = " ";
return new ModelAndView("login", "loginMessage", loginMessage);
}
Edit after much pounding on this …
I’ve also tried the following approach, which gets the same result…
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<div id="messageBox">${loginMessage}</div>
<form:form modelAttribute="loginForm" id="form1" name="form1" method="post" action="/do/authenticate" onsubmit="return validateForm()">
<table>
<tr>
<td><form:label path="username">Username:</form:label></td>
<td><form:input path="username" /></td>
</tr>
<tr>
<td><form:label path="password">Password:</form:label></td>
<td><form:input path="password" /></td>
</tr>
<tr>
<td> </td>
<td><input type="submit" name="submit" value="Login" /></td>
</tr>
</table>
</form:form>
With a LoginForm backing object:
package com.cloudfordev.spring3;
public class LoginForm {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
And the following controller:
@Controller
@SessionAttributes
public class VMGeneratorController {
@ModelAttribute("loginForm")
public LoginForm getLoginFormObject() {
return new LoginForm();
}
@RequestMapping(value = "/viewoptions", method = RequestMethod.GET)
public ModelAndView viewOptions(Model model) {
Menu menu = new Menu();
String optionsPage = menu.draw();
return new ModelAndView("options", "body", optionsPage);
}
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public ModelAndView login(@ModelAttribute("loginForm") LoginForm loginForm, BindingResult result) {
boolean isAuthenticated = false;
String username = loginForm.getUsername();
String password = loginForm.getPassword();
if (username == null || password == null) {
// User has not specified all required fields
String loginMessage = "Please complete all fields";
return new ModelAndView("login", "loginMessage", loginMessage);
} else {
// User has specified username and password
// Attempt authentication
Login login = new Login();
isAuthenticated = login.authenticate(username, password);
if (isAuthenticated) {
// Authentication succeeded, return the options page
String loginMessage = "Success";
return new ModelAndView("login", "loginMessage", loginMessage);
} else {
// Authentication failed, return the login page
String loginMessage = "Authentication failed";
return new ModelAndView("login", "loginMessage", loginMessage);
}
}
}
@RequestMapping(value = "/login", method=RequestMethod.GET)
public ModelAndView login(Model model) {
// Blank login screen
String loginMessage = " ";
return new ModelAndView("login", "loginMessage", loginMessage);
}
}
Maybe you need to take into account the web-app context-root. Assuming your webapp is placed on http://mydomain.com/myapp, then you need to post to /myapp/do/login instead of just /do/login ?
If above is not the solution, then you need to trace your spring context.xml, web.xml, app server specifix config (tomcat context.xml / jboss-web.xml) etc. to ensure you’ve get all the plumbing in place