HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalStateException

时间:2015-09-01 21:57:00

标签: spring validation spring-mvc spring-validator

I am working on a Spring MVC application and have an issue with the validation. I need to create an user and it is a 2 step process(meaning 2 jsps with the same controller). The jsps have 2 different commandNames. So when I created the validator for the first model and initialize it, the first page loads fine. For testing, I am not using an if condition, but forwarding to next page. I get an error as the controller tries to load the validator with the current commandName object and it fails.

When I enter the url http://ip:port/data, the page loads as there is no validation, it is just initial load When I try to submit the page without entering the firstName and submit, the method @RequestMapping(value = "/user") is called and the the next page 2 is supposed to be loaded. But the page 2 fails.

binder.getTarget() prints UserData the first time which is right
binder.getTarget() prints userinfo the 2nd time, when the next page is loading and it fails with the error

StackTrace:

HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalStateException: Invalid target for Validator [.validator.UserDataValidator@4366febc]: .model.UserInfo@4e3a061b

type Exception report

message Request processing failed; nested exception is java.lang.IllegalStateException: Invalid target for Validator [.validator.UserDataValidator@4366febc]: .model.UserInfo@4e3a061b

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: Invalid target for Validator [.validator.UserDataValidator@4366febc]: .model.UserInfo@4e3a061b
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)

root cause

java.lang.IllegalStateException: Invalid target for Validator [.validator.UserDataValidator@4366febc]: .model.UserInfo@4e3a061b
    org.springframework.validation.DataBinder.assertValidators(DataBinder.java:516)
    org.springframework.validation.DataBinder.setValidator(DataBinder.java:507)
    .controller.AccountDataController.initBinder(AccountDataController.java:65)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:606)
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    org.springframework.web.method.annotation.InitBinderDataBinderFactory.initBinder(InitBinderDataBinderFactory.java:62)
    org.springframework.web.bind.support.DefaultDataBinderFactory.createBinder(DefaultDataBinderFactory.java:53)
    org.springframework.web.method.annotation.ModelFactory.updateBindingResult(ModelFactory.java:251)

Any suggestions on how to handle this would be helpful. Is there a way to make this work - having 2 different commandNames and trying to validate using one controller or do I need to update the commandName to one object and that object has all the classes inside it.

e.g.

class Parent{
 UserData UserData;
 UserInfo userInfo;

 getter & setter
} 

My Controller:

@Controller
@SessionAttributes("userData")
public class AController {

    @Autowired
    @Qualifier("userDataValidator")
    private Validator validator;

    @InitBinder
    private void initBinder(WebDataBinder binder) {

        System.out.println("getTarget: "+binder.getTarget()); ------------ 
        binder.setValidator(validator);
    }

    @RequestMapping(value = "/data", method = RequestMethod.GET)
    public String initForm(Model model){

        UserData userData = new UserData();
        model.addAttribute("userData", userData);
        return "page1";

    }//

    @RequestMapping(value = "/user", method=RequestMethod.POST )
    public String details(Model model, @Validated UserData userData, BindingResult result) {
        *****
        model.addAttribute("userinfo", userinfo);
        return "page2";

    }//
    **EDIT**
    @RequestMapping(value = "/create", method=RequestMethod.POST )
*****************
public String create(Model model, Userinfo userinfo, UserData userData) {

*********************user creation
}
**EDIT**
}

My JSPs

page1.jsp

<form:form method="POST" action="user" commandName="userData">
    <form:label path="firstName"><b>Name</b></form:label> <br />
    <form:input class="formLabel" path="firstName" />
    ****
</form>

page2.jsp

 <form:form method="POST" action="create" commandName="userinfo">
 ***********fields
 </form>

My validator

public class UserDataValidator  implements Validator{

    public boolean supports(Class<?> paramClass) {
        return UserData.class.equals(paramClass);

    }

    public void validate(Object obj, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "valid.firstName");

    }

}

My Model

UserData.java

public class UserData {

    String firstName;

    getter & setter for firstName

}

Let me know if any more details are needed. Thanks.

0 个答案:

没有答案