We added a modelmap attribute named curruser in section ②, and placed the attribute named curruser in modelmap to the session through @ sessionattributes annotation at section ①, therefore, we can not only use the request in the JSP view page corresponding to the listboardtopic () request. getattribute ("curruser") and session. getattribute ("curruser") obtains the user object. You can also use Session on the JSP view page corresponding to the next request. getattribute ("curruser") or modelmap # Get ("curruser") to access this attribute.
Here we only put the attribute of one modelmap into the session. In fact, @ sessionattributes allows multiple attributes to be specified. You can specify multiple attributes through a string array, such as @ sessionattributes ({"attr1", "attr2 "}). In addition, @ sessionattributes can also specify the modelmap attribute to be session based on the attribute type, for example, @ sessionattributes (types = user. class), of course, you can also specify multiple classes, such as @ sessionattributes (types = {user. class, Dept. class}). You can also specify the @ sessionattributes (types = {user. class, Dept. class}, value = {"attr1", "attr2 "}).
The above describes how to place attributes in modelmap and How to Make attributes in modelmap have the range of the session domain. In addition to accessing attributes in modelmap through traditional methods on the JSP view page, readers may ask: Can I bind attributes in modelmap to the input parameters of the request processing method? The answer is yes. Spring provides a @ modelattribute annotation for this purpose. The following example uses the @ modelattribute annotation:
List 11. Make the specific attributes of the model object have the scope of the session range
Package COM. baobaotao. web; import COM. baobaotao. service. bbtforumservice; import Org. springframework. beans. factory. annotation. autowired; import Org. springframework. stereotype. controller; import Org. springframework. UI. modelmap; import Org. springframework. web. BIND. annotation. requestmapping; import Org. springframework. web. BIND. annotation. requestparam; import Org. springframework. web. BIND. annotation. sessionattr Ibutes; import Org. springframework. web. BIND. annotation. modelattribute; import javax. servlet. HTTP. httpservletrequest; import javax. servlet. HTTP. httpsession; @ controller @ requestmapping ("/bbtforum. do ") @ sessionattributes (" curruser ") // ① make the curruser attribute of modelmap have the session-level scope public class bbtforumcontroller {@ autowiredprivate bbtforumservice; @ requestmapping (Params = "method = listboardtopic") Publ IC string listboardtopic (@ requestparam ("ID") int topicid, user, modelmap model) {bbtforumservice. getboardtopics (topicid); system. out. println ("topicid:" + topicid); system. out. println ("User:" + User); Model. addattriing ("curruser", user); // ② Add a property return "listtopic";} @ requestmapping (Params = "method = listallboard") to modelmap ") // ③ set public string listallboard (@ modelattribute ("curruser") in modelmap ") User user) {// The curruser attribute is bound to the user input parameter. Bbtforumservice. getallboard (); system. Out. println ("User:" + User); Return "listboard ";}} |
At ②, we add a property named curruser to modelmap, And the annotation outside ① gives this curruser property a session-level scope. Therefore, we can bind the curruser attribute in modelmap to the user input parameter of the request processing method through the @ modelattribute annotation at ③.
So when we call the following URL request: http: // localhost/bbtforum. do? Method = listboardtopic & id = 1 & username = Tom & Dept. deptid = 12
To execute the listboardtopic () request processing method, and then access the following url: http: // localhost/sample/bbtforum. do? Method = listallboard
You can see that the user input parameter of listallboard () has been successfully bound to the session-level curruser attribute registered in listboardtopic.
Signature conventions for Request Processing Methods
Method Input parameters
We know that the Controller method marked with @ requestmapping annotation becomes the request processing method, and spring MVC allows extremely flexible request processing method signing methods. For method input parameters, multiple types of input parameters are allowed, which are described in the following table:
Optional type of request processing method input parameters |
Description |
Java basic data type and string |
By default, the URL parameter is bound by name matching. You can use the @ requestparam annotation to change the default binding rule. |
Request/response/session |
It can be servlet API or the object corresponding to the Portlet API. Spring will bind them to the corresponding objects of the servlet and the Portlet container. |
Org. springframework. Web. Context. Request. webrequest |
Contains the request object. |
Java. util. locale |
Bind to the locale object corresponding to the request |
Java. Io. inputstream/Java. Io. Reader |
You can access the request content. |
Java. Io. outputstream/Java. Io. Writer |
You can use this to perform response operations. |
Any input parameter marked with the @ requestparam Annotation |
The input parameter marked with the @ requestparam annotation will be bound to a specific request parameter. |
Java. util. MAP/org. springframework. UI. modelmap |
It binds the potential model objects created by each request in the spring MVC framework. They can be accessed by Web View objects (such as JSP) |
Command/form object (note: the object that binds the URL parameter sent using http get is a command object, and the object that binds the URL parameter sent using http post is a form object) |
Their attributes are bound to URL parameters by name matching rules, and type conversion is completed at the same time. The type conversion rules can be adjusted through the @ initbinder annotation or the handleradapter configuration. |
Org. springframework. validation. Errors/org. springframework. validation. bindingresult |
It is the Validation result of the command/form object in the attribute list. Note that the validation result parameter must be followed by the command/form object |
RG. springframework. Web. Bind. Support. sessionstatus |
You can use this type of status object to explicitly end form processing. This is equivalent to triggering the session to clear the attributes defined by @ sessionattributes. |
The ease of use of spring MVC framework is that you can define the input parameters of the Request Processing Method in any order (except that errors and bindingresult must be followed by the command object/form parameters ), spring MVC automatically transmits the corresponding object to the request processing method through the input parameter based on the reflection mechanism. This mechanism allows developers not to rely on the servlet API development control layer.ProgramWhen a request processing method requires a specific object, you only need to declare the input parameter in the parameter list. You do not need to consider how to obtain these objects, the spring MVC framework is like a manager who "worked hard" to prepare everything we needed. The following example shows how to use sessionstatus:
Listing 12. Using sessionstatus to control session-level model attributes
@ Requestmapping (method = requestmethod. post) Public String processsubmit (@ modelattribute owner, bindingresult result, sessionstatus status) {// <-- ① new ownervalidator (). validate (owner, result); If (result. haserrors () {return "ownerform";} else {This. clinic. storeowner (owner); status. setcomplete (); // <-- ② return "Redirect: Owner. do? Ownerid = "+ owner. GETID ();}} |
The owner form object in the processsubmit () method will be bound to the "owner" attribute of modelmap. The result parameter is used to store the object that verifies the owner result, and the status is used to control the status of form processing. In section ②, we call the status. setcomplete () method to clear all model attribute data of the Controller at the session level from the session.
Method return parameters
In earlier versions of spring MVC, the return value type of the request processing method must be modelandview. In spring 2.5, you have a variety of flexible options. Use the following table to describe:
Optional type of request processing method input parameters |
Description |
Void |
The logical view name is determined by the URL corresponding to the request processing method, as shown in the following method:
@ Requestmapping ("/welcome. Do") Public void welcomehandler (){} |
The logical view name is "welcome" |
String |
In this case, the name of the logical view is the returned character, as shown in the following method:
@ Requestmapping (method = requestmethod. get) Public String setupform (@ requestparam ("ownerid") int ownerid, modelmap model) {owner = This. clinic. loadowner (ownerid); Model. addattriform (owner); Return "ownerform ";} |
The logical view name is "ownerform" |
Org. springframework. UI. modelmap |
Like the return type void, the logical view name depends on the request URL, as shown in the following example:
@ Requestmapping ("/vets. Do") Public modelmap vetshandler () {return New modelmap (this. Clinic. getvets ());} |
The corresponding logical view name is "vets". The returned modelmap will be used as the model object for the request and can be accessed on the JSP view page. |
Modelandview |
It can also be a traditional modelandview. |
It should be said that using string as the return value type of the request processing method is a common method, so that the returned logical view name will not be bound to the request URL, which has great flexibility, model data can be controlled through modelmap. Of course, using traditional modelandview directly is also a good choice.
Register your own property Editor
Spring MVC has a set of common attribute editors, including the Attribute Editor of basic data types and their packages, the string Attribute Editor, And the JavaBean Attribute Editor. But sometimes we also need to register some custom attribute editors with spring MVC framework, such as the Attribute Editor in a specific time format.
Spring MVC allows you to register an Attribute Editor with the entire Spring framework, which has an impact on all controllers. Of course, spring MVC allows only registering an Attribute Editor with a controller, which has no impact on other controllers. The former can be implemented through the annotationmethodhandleradapter configuration, while the latter can be implemented through the @ initbinder annotation.
The following describes the custom editor registered with the entire spring MVC framework:
Listing 13. Register a framework-level custom property Editor
> Bean class = "org. springframework. web. servlet. MVC. annotation. annotationmethodhandleradapter "<> property name =" webbindinginitializer "<> bean class =" com. baobaotao. web. mybindinginitializer "/<>/property <>/bean < |
Mybindinginitializer implements the webbindinginitializer interface. In the interface method, you can register multiple custom attribute editors through binder.CodeAs follows:
Listing 14. Custom property Editor
Package Org. springframework. samples. petclinic. web; import Java. text. simpledateformat; import Java. util. date; import Org. springframework. beans. factory. annotation. autowired; import Org. springframework. beans. propertyeditors. customdateeditor; import Org. springframework. beans. propertyeditors. stringtrimmereditor; import Org. springframework. samples. petclinic. clinic; import Org. springframework. samples. petclinic. pettype; import Org. springframework. web. BIND. webdatabinder; import Org. springframework. web. BIND. support. webbindinginitializer; import Org. springframework. web. context. request. webrequest; public class mybindinginitializer implements webbindinginitializer {public void initbinder (webdatabinder binder, webrequest request) {simpledateformat dateformat = new simpledateformat ("yyyy-mm-dd"); dateformat. setlenient (false); binder. registercustomeditor (date. class, new customdateeditor (dateformat, false); binder. registercustomeditor (string. class, new stringtrimmereditor (false ));}} |
If you want an Attribute Editor to act only on a specific controller, you can define a @ initbinder annotation method in the Controller. You can register several attribute editors with the Controller in this method, let's look at the following code:
Listing 15. Register a controller-level custom property Editor
@ Controllerpublic class myformcontroller {@ initbinder public void initbinder (webdatabinder binder) {simpledateformat dateformat = new simpledateformat ("yyyy-mm-dd"); dateformat. setlenient (false); binder. registercustomeditor (date. class, new customdateeditor (dateformat, false ));}...} |
Note that the @ initbinder annotation method must have a webdatabinder-type input parameter, so that spring MVC framework can pass in the webdatabinder object registered with the property editor.
How to prepare data
When writing a controller, you often need to prepare some data before entering the request processing method for request processing or view rendering. In the traditional simpleformcontroller, The referencedata () method is used to prepare reference data. In spring 2.5, you can add @ modelattribute to any method that has the returned value, so that the returned value will enter the attribute list of the model object. Let's look at the following example:
Listing 16. Define a method to prepare data for processing requests
Package COM. baobaotao. web; import COM. baobaotao. service. bbtforumservice; import Org. springframework. beans. factory. annotation. autowired; import Org. springframework. stereotype. controller; import Org. springframework. UI. modelmap; import Org. springframework. web. BIND. annotation. modelattribute; import Org. springframework. web. BIND. annotation. requestmapping; import Org. springframework. web. BIND. annotation. requestparam; import Org. springframework. web. BIND. annotation. sessionattributes; import Java. util. arraylist; import Java. util. list; import Java. util. set; @ controller @ requestmapping ("/bbtforum. do ") public class bbtforumcontroller {@ autowired private bbtforumservice; @ modelattribute (" items ") // <-- ① add an attribute named items to the model object public list <string> populateitems () {list <string> lists = new arraylist <string> (); lists. add ("Item1"); lists. add ("item2"); Return lists ;}@ requestmapping (Params = "method = listallboard") Public String listallboard (@ modelattribute ("curruser") User user, modelmap Model) {bbtforumservice. getallboard (); // <-- ② access the items attribute system in the model. out. println ("model. items: "+ (list <string>) model. get ("items ")). size (); Return "listboard ";}} |
At ①, The populateitem () method is called before any request processing method is executed by using the @ modelattribute annotation, spring MVC puts the return value of this method in the implicit model object attribute list in the name of "items.
In section ②, we can access the items attributes through modelmap. When the listallboard () request processing method is executed, section ② prints the "model" on the console. items: 2. Of course, we can also access the items attribute in the model object in the request view.
Summary
Spring 2.5 has greatly enhanced spring MVC. Now we can almost completely replace the original spring MVC program based on the interface with annotation-based Spring MVC. Annotation-based Spring MVC has the following advantages over interface-based Spring MVC:
- Facilitate the ing between requests and controllers;
- The request processing method can bind URL parameters to input parameters;
- The controller does not have to inherit any interfaces. It is only a simple pojo.
However, annotation-based Spring MVC is not perfect, and there is still room for optimization, because it is more complicated than XML-based configuration in some aspects. For example, for the Controller that processes multiple requests, assume that we use a URL parameter to specify the calling processing method (such as XXX. do? Method = listboardtopic). When using annotations, @ requestmapping () is required for each request processing method () the annotation specifies the corresponding URL parameter (for example, @ requestmapping (Params = "method = listboardtopic"). In xml configuration, we only need to configure a parametermethodnameresolver.