Reputation: 136
I'm currently developing a login change password part where the validation is driven by the authentication policy registered for the user.
I have the following controller which calls the authentication service that will check that the password is matching all the rules set by the authentication policy of the user:
@RequestMapping(value = "/changepw", method = RequestMethod.POST)
public String changePw(@RequestParam(value = "username") final String username,
@Valid @ModelAttribute("changePw") final ChangePasswordForm changePasswordForm, final BindingResult errors) {
this.log.debug("Entering password change");
try {
final LoginResult result = this.authService.changePassword(changePasswordForm.getUsername(),
changePasswordForm.getOldPassword(), changePasswordForm.getNewPassword1(), changePasswordForm.getNewPassword2());
this.log.debug("login result: {}", result);
if (result.getResultCode() == CODE.ERROR) {
this.log.error(result.getErrorMessage());
errors.reject(result.getErrorMessage());
return "redirect:/login/changepw/";
}
if (result.getResultCode() == CODE.SUCCESS) {
return "redirect:/login/login";
}
errors.reject("error.login.unknown.error");
return "redirect:/login/changepw/";
} catch (final Exception e) {
errors.reject("error.login.catch.error");
return "redirect:/login/changepw";
}
}
My LoginResult is basically just a bean
public class LoginResult implements Serializable {
private static final long serialVersionUID = 6058401105878015102L;
public enum CODE {
SUCCESS,
ERROR,
CHANGE_PASSWORD
}
private CODE resultCode;
private String errorMessage;
//constructors getters setters.
the method changePassword is basically returning either CODE.SUCCESS,null
or CODE.ERROR, error.whatever.code
now what I'd like to do is to have the error.code being displayed in my jsp in a div above the first input.
here is my jsp:
<form:form commandName="changePw" method="POST">
<form:errors cssClass="errorBlock" element="div"/>
<div class="form_block">
<form:label path="username"><spring:message code="prompt.label.username"/></form:label>
<form:input path="username"/>
</div>
<div class="form_block">
<form:label path="oldPassword"><spring:message code="prompt.label.oldpassword"/></form:label>
<form:password path="oldPassword"/>
<div class="capsLockImage control" id="capsLockImage1" title="<spring:message code="prompt.caps_lock"/>"></div>
</div>
<div class="form_block">
<form:label path="newPassword1"><spring:message code="prompt.label.newpassword1"/></form:label>
<form:password path="newPassword1"/>
<div class="capsLockImage control" id="capsLockImage2" title="<spring:message code="prompt.caps_lock"/>"></div>
</div>
<div class="form_block">
<form:label path="newPassword2"><spring:message code="prompt.label.newpassword2"/></form:label>
<form:password path="newPassword2"/>
<div class="capsLockImage control" id="capsLockImage3" title="<spring:message code="prompt.caps_lock"/>"></div>
</div>
<input type="submit" value="<spring:message code="prompt.label.changepw"/>"/>
So far the error gets registered in the BindingResult, but doesn't return to the view. What is the best practise to make that work?
Upvotes: 0
Views: 772
Reputation: 22994
This is happening because you're redirecting to the view - and the errors stored in the BindingResult
are lost as a result.
You may be better to just forward back to the changepw
view in the event of an error - e.g.:
if (result.getResultCode() == CODE.ERROR) {
this.log.error(result.getErrorMessage());
errors.reject(result.getErrorMessage());
return "changepw"; // Or whatever the jsp view is called
}
If you can't do that, then you'll have to store the errors in session so that they're available once the redirected request comes back in.
To do this you can explicitly use the HttpSession
or alternatively the RedirectAttributes
in later versions of Spring - as this post explains: Spring - Redirect after POST (even with validation errors)
Upvotes: 1