简体   繁体   中英

Manually handle error validation in Spring annotated controller

I'm trying to update a Spring controller to use annotations for a relatively simple 'change password' page. The only fields on the page are 'password' and 'confirm password'. When the form is submitted, it calls to a webservice to do the actual changing of the password. That webservice may return a InvalidPasswordException based upon password rules run within that service. So I want to catch the exception, then add an error message to the view to show up next to the 'password' field. The velocity code is already written using #springShowErrors, so I want to add the error in a way that in can be read in by that tag.

Here is my controller:

@Controller
@RequestMapping("/edit-password.ep")

public class EditPasswordFormControllerImpl {

@Autowired
private CustomerService customerService;
@Autowired
private CustomerSessionService customerSessionService;

@RequestMapping(method = RequestMethod.POST)
protected ModelAndView onSubmit(@ModelAttribute("editPasswordFormBean") EditPasswordFormBeanImpl editPasswordFormBean, BindingResult errors, HttpServletRequest request) throws EpWebException {

    String nextView = "redirect:/manage-account.ep";

    final CustomerSession customerSession = (CustomerSession) request.getSession().getAttribute(WebConstants.CUSTOMER_SESSION);
    final Customer customer = customerSession.getShopper().getCustomer();

    try {
        CustomerInfo customerInfo = new CustomerInfo();
        customerInfo.setCustomerId(customer.getUserId());
        customerInfo.setPassword(editPasswordFormBean.getPassword());

        UpdateAccountServiceRequest updateRequest = new UpdateAccountServiceRequest();
        updateRequest.setClientId(CLIENT_ID);
        updateRequest.setCustomerInfo(customerInfo);

        //this is the webservice call that could throw InvalidPasswordException
        customerService.updateUserAccount(updateRequest);

    } catch (InvalidPasswordException e) {

        // This is where I'm not sure what to do.
        errors.addError(new ObjectError("password", e.getMessage()));
        nextView = "edit-password.ep";

    } catch (ServiceException e) {
        throw new EpWebException("Caught an exception while calling webservice for updating user", e);
    }

    return new ModelAndView(nextView);
}

@RequestMapping(method = RequestMethod.GET)
protected String setupForm(ModelMap model) {
    EditPasswordFormBean editPasswordFormBean = new EditPasswordFormBeanImpl();
    model.addAttribute("editPasswordFormBean", editPasswordFormBean);
    return "account/edit-password";
}
}

And here is a snippet of my velocity template:

<fieldset>
<legend>#springMessage("editPassword.editPasswordTitle")</legend>
<table border="0" cellspacing="0" cellpadding="3">
    <colgroup>
        <col width="150">
        <col width="*">
    </colgroup>
    <tr>
        <td colspan="2">
            <br />
            <strong>#springMessage("editPassword.changePassword")</strong>
        </td>
    </tr>
    <tr>
        <td align="right">#springMessage("editPassword.password")</td>
        <td>
            #springFormPasswordInput("editPasswordFormBean.password" "maxlength='100'")
            #springShowErrors("<br>" "req")
        </td>
    </tr>
    <tr>
        <td align="right">#springMessage("editPassword.confirmPassword")</td>
        <td>
            #springFormPasswordInput("editPasswordFormBean.confirmPassword" "maxlength='100'")
            #springShowErrors("<br>" "req")
        </td>
    </tr>
</table>
</fieldset>

I'm not quite sure what I should do when I catch the exception. What I currently have doesn't work. It returns to the edit-password page, but no error displays. I've read about HandleExceptionResolver, but even if I use that, I'm still not sure how to get the error to display on the view.

Any help is greatly appreciated!

Jeff, its just a guess, if you see the controller you have the RequestMapping("/edit-password.ep"), so when there is an error scenario your next view is "edit-password.ep", so it will come to this controller and it will be consdiered as a get request to the controller. But in your GET mapping method you are always creating a new EditPasswordBean and sending back to the back. If you run the server in debug mode and keep a break point in setUpForm method you will why the errors have been swallowed. Try to give specific mappings for get and post to avoid such issues. Ideally you should a Validator defined and it should be registered in your initBinder method. Check out this link http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM