java - Form submit in Spring MVC 3 - explanation -


i'm having problems understanding how form submit in spring 3 mvc work.

what want do, create controller take user's name , display him. , somehow have done don't understand how works. so..

i have form looks this:

<form:form method="post" modelattribute="person">     <form:label path="firstname">first name</form:label>     <form:input path="firstname" />     <br />      <form:label path="lastname">last name</form:label>     <form:input path="lastname" />     <br />      <input type="submit" value="submit" /> </form:form> 

i have controller looks this:

@controller public class homecontroller {      @requestmapping(value = "/", method = requestmethod.get)     public string showhellopage(model model) {         model.addattribute("person", new person());         return "home";     }      @requestmapping(value = "/", method = requestmethod.post)     public string sayhello(person person, model model) {         model.addattribute("person", person);         return "home";     } } 

to display welcome message user use following code in jsp page:

<c:if test="${not empty person.firstname , not empty person.lastname}">     hello ${person.firstname} ${person.lastname}! </c:if> 

and works (i omit xml configuration files because irrelevant problem).

i thought "modelattribute" attribute in form points bean variable should populated inputs' values (as set in "path" attributes). looks, works in different way. if remove line

model.addattribute("person", new person()); 

from "showhellopage" method (common) exception "neither bindingresult nor...".

also, on beginning, "sayhello" method looked like:

(...) public string sayhello(@modelattribute("person") person person, model model) { (...) 

i mean, had "modelattribute" annotation. added it, because in tutorials have read, present. after removed it, worked well, did before.

so question is - use of "modelattribute" anonnatation? way omit "modelattribute" attribute in form? , second part, way (maybe annotation) make form automatically bind inputs' values proper bean's properties (which declared method parameter)? without need of adding empty bean before sending form (as have now).

thanks replies (which aren't links spring's documentation, because have read it).

the @modelattribute annotation in case used identify object spring should add model attribute. model attributes abstraction httpservletrequest attributes. basically, objects identified key find way httpservletrequest attributes. can manually adding attribute model#addattribute(string, object), have @modelattribute annotated method, or annotating method parameter @modelattribute.

the thing need understand how spring resolves handler method parameters , injects arguments. uses handlermethodargumentresolver interface so. there number of implementing classes (see javadoc) , each has responsibility resolveargument() returning argument spring use invoke() handler method through reflection. spring call resolveargument() method if handlermethodargumentresolver supportsparameter() method returns true specific parameter.

the handlermethodargumentresolver implementation in question here servletmodelattributemethodprocessor extends modelattributemethodprocessor states

resolves method arguments annotated @modelattribute , handles return values methods annotated @modelattribute.

spring (3.2) register handlermethodargumentresolver , others

private list<handlermethodargumentresolver> getdefaultargumentresolvers() {         list<handlermethodargumentresolver> resolvers = new arraylist<handlermethodargumentresolver>();      // annotation-based argument resolution     resolvers.add(new requestparammethodargumentresolver(getbeanfactory(), false));     resolvers.add(new requestparammapmethodargumentresolver());     resolvers.add(new pathvariablemethodargumentresolver());     resolvers.add(new servletmodelattributemethodprocessor(false));     resolvers.add(new requestresponsebodymethodprocessor(getmessageconverters()));     resolvers.add(new requestpartmethodargumentresolver(getmessageconverters()));     resolvers.add(new requestheadermethodargumentresolver(getbeanfactory()));     resolvers.add(new requestheadermapmethodargumentresolver());     resolvers.add(new servletcookievaluemethodargumentresolver(getbeanfactory()));     resolvers.add(new expressionvaluemethodargumentresolver(getbeanfactory()));      // type-based argument resolution     resolvers.add(new servletrequestmethodargumentresolver());     resolvers.add(new servletresponsemethodargumentresolver());     resolvers.add(new httpentitymethodprocessor(getmessageconverters()));     resolvers.add(new redirectattributesmethodargumentresolver());     resolvers.add(new modelmethodprocessor());     resolvers.add(new mapmethodprocessor());     resolvers.add(new errorsmethodargumentresolver());     resolvers.add(new sessionstatusmethodargumentresolver());     resolvers.add(new uricomponentsbuildermethodargumentresolver());      // custom arguments     if (getcustomargumentresolvers() != null) {         resolvers.addall(getcustomargumentresolvers());     }      // catch-all     resolvers.add(new requestparammethodargumentresolver(getbeanfactory(), true));     resolvers.add(new servletmodelattributemethodprocessor(true));      return resolvers; } 

when spring needs invoke handler method, it'll iterate through parameter types , through above list , use first 1 supportsparameter().

notice 2 instances of servletmodelattributemethodprocessor added (one after //catch all comment). modelattributemethodprocessor has annotationnotrequired field tells if should @modelattribute or not. first instance must @modelattribute, second 1 doesn't. spring can register own handlermethodargumentresolver instances, see // custom arguments comment.


specifically

@requestmapping(value = "/", method = requestmethod.post) public string sayhello(person person, model model) {     model.addattribute("person", person);     return "home"; } 

in case, doesn't matter if person parameter annotated or not. modelattributemethodprocessor resolve , bind form fields, ie. request parameters, fields of instance. shouldn't need add model modelattributemethodprocessor class handle that.

in showhellopage() method

model.addattribute("person", new person()); 

is needed <form> taglib. that's how resolves input fields.


so question - use of "modelattribute" anonnatation?

to automatically add specified parameter (or method return value) model.

is way omit "modelattribute" attribute in form?

no, form binding looks object in model , binds fields html input elements.

and second part, way (maybe annotation) make form automatically bind inputs' values proper bean's properties (which declared method parameter)? without need of adding empty bean before sending form (as have now).

a spring <form> tag latches onto model attribute object , uses fields create input , label elements. doesn't matter how object ended in model long did. if can't find model attribute name (key) specified, throws exceptions, saw.

 <form:form method="post" modelattribute="person"> 

the alternative providing empty bean create html yourself. spring's <form> use bean's field names create input element. this

<form:form method="post" modelattribute="person">     <form:label path="firstname">first name</form:label>     <form:input path="firstname" /> 

creates like

<form method="post" action="[some action url]">     <label for="firstname">first name<label>     <input type="text" name="firstname" value="[whatever value firstname field had]" />     ... 

spring binds request parameters instance fields using name attribute.


Comments

Popular posts from this blog

ios - MKAnnotationView layer is not of expected type: MKLayer -

ZeroMQ on Windows, with Qt Creator -

unity3d - Unity SceneManager.LoadScene quits application -