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
Post a Comment