Announcement Announcement Module
Collapse
No announcement yet.
Why is Validator trying to validate ModelMap? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Why is Validator trying to validate ModelMap?

    Hi All,

    Newbie question here: I've been trying to use Spring 3.0 with a Spring 2.5 style validator. The validator is like so:

    Code:
    public class CreateTrackValidator implements Validator {
    
    	@SuppressWarnings("unchecked")
    	@Override
    	public boolean supports(Class arg0) {
    		return CreateTrackInfo.class.isAssignableFrom(arg0);
    	}
    
    	@Override
    	public void validate(Object createTrackCommand, Errors errors) {
    		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "track.name", "track.name.empty");
    		CreateTrackInfo cmd = (CreateTrackInfo) createTrackCommand;
    		if (cmd.getTrack().getLength() == null) {
    			errors.rejectValue("track.length","track.length.empty");
    		} else
    		if (cmd.getTrack().getLength() <= 0) {
    			errors.rejectValue("track.length","track.length.nonpositive");
    		}
    	}
    
    }
    The Command object it is intended to validate is:

    Code:
    public class CreateTrackInfo {
    
    	Track track = new Track();
    	
    	public Track getTrack() {
    		return track;
    	}
    
    	public void setTrack(Track track) {
    		this.track = track;
    	}
    	
    }
    Where Track is a POJO with a "name" String and a "length" Integer.

    In my Spring 3.0 style controller, I've used the @InitBinder annotation to set the validator:

    Code:
    @InitBinder
    public void initWebDataBinder(WebDataBinder binder) {
    	binder.setValidator( new CreateTrackValidator() );
    }
    Then I access the CommandInfo object in the handler like so:

    Code:
    @RequestMapping(value="/createtrack.{mode}")
    protected String createTrack(@PathVariable String mode, CreateTrackInfo commandInfo, BindingResult result, ModelMap model)
    		throws Exception {
    	if (result.hasErrors()) {
    		model.put("errorMessage", getErrorString(result));
    	} else {
    		try {
    			CreateTrackCommand cmd = newCommand("createtrack");
    			cmd.setCommandInfo(commandInfo);
    			cmd.execute(model);
    		} catch (Exception e) {
    			e.printStackTrace();
    			model.put("errorMessage", e.getMessage());
    		}
    	}
    	return mode + "/createtrack";
    }
    The command does a simple hibernateTemplate.save( commandInfo.getTrack() ) then puts the track into a "resultingTrack" key in the passed ModelMap.

    However, there are two problems with this:

    1. The validator is trying to validate the ModelMap! Why? When I put a simple key/value pair like ("foo",new Integer(42)) into the ModelMap, it doesn't complain. But when I put ("resultingTrack", new Track() ) where Track is my POJO, it complains that the Validator doesn't support my Track object. Of course; the validator is supposed to be for the CreateTrackInfo object. What is going on here? Maybe I don't understand the lifecycle of the ModelMap object.

    2. The validator isn't working on the CreateTrackInfo object. Although I assume this is because I need to add a JSR-303 implementation to the classpath (which is NOT included in Spring 3.0 dist!) and a @Valid annotation before the CreateTrackInfo argument.

    Can anyone enlighten me as to why the ModelMap being validated?

    Also, if there is a way to validate command objects without a JSR-303 library could you please fill me in? I've read I can use a DataBinder instance, but I don't know where to get the PropertyValues object from within the handler method.

    Cheers and greetings!

  • #2
    Ok, I figured out a simple way to validate the CreateTrackInfo object (I didn't realize BindingResult implemented Errors):

    Code:
    @RequestMapping(value="/createtrack.{mode}")
    protected String createTrack(@PathVariable String mode, CreateTrackInfo commandInfo, BindingResult result, ModelMap model, HttpServletRequest request)
    		throws Exception {
    	new CreateTrackValidator().validate(commandInfo,result);
    	if (result.hasErrors()) {
    		model.put("errorMessage", getErrorString(result));
    	} else {
    		try {
    			CreateTrackCommand cmd = newCommand("createtrack");
    			cmd.setCommandInfo(commandInfo);
    			cmd.execute(model);
    		} catch (Exception e) {
    			e.printStackTrace();
    			model.put("errorMessage", e.getMessage());
    		}
    	}
    	return mode + "/createtrack";
    }
    Then I removed the controller's @InitBinder method, and that stopped the ModelMap from being unnecessarily validated. Still, I'm wondering why that happened.

    Comment

    Working...
    X