Features Offered by the AbstractView


All views Spring features extend org.springframework.web.servlet.view.AbstractView. Except for some basic features, such as a parameterizable content type, it offers static attributes. Through the use of those static attributes, you can add additional attributes to the model returned by any controller, without the controller knowing. This is especially suited for customizing your views, without having your controllers implement any additional logic.

Attributes can be specified in one of two ways. When using the XmlViewResolver (which loads an XML file containing beans that represent views), you can add any arbitrary object to the static attributes. When using the ResourceBundleViewResolver, you can use a comma-separated value (CSV) format to specify them.

<bean    >   <property name="basename"><value>views</property> </bean>

The following are three view files, each containing different attributes for the view defined:

# /WEB-INF/classes/views.properties index.class=org.springframework.web.servlet.view.InternalResourceView index.url=/WEB-INF/jsp/index.jsp     # /WEB-INF/classes/views_en.properties index.attributesCSV=title={title},content={/WEB-INF/jsp/content-en.jsp}     # /WEB-INF/classes/views_fr.properties index.attributesCSV=title={titre},content={/WEB-INF/jsp/content-fr.jsp}

Along with everything added to the model by a controller, when returning the index view, the title and the content attributes are also merged into the model, making them available to the view renderer. Using JSTL tags, we can now create our view:

<html>   <head><title><c:out value="${title}"/></title></head>   <body>     <jsp:include page="${content}"/>   </body> </html>

Issuing a New Request Using the RedirectView

A special and in some situations often used view is the RedirectView, which redirects the user to a different URL, rather than rendering the view itself. One of the many situations where you will be using the RedirectView is when you want to issue a GET request after the posting of a form. This way, you won't run into awkward repost data warnings shown by several browsers.

The RedirectView has two features. After specifying a URL, it will first append all model data to the URL—as request parameters. When this is done, the RedirectView will use the response to send the browser a redirect.

When you indicate you don't need to maintain HTTP 1.0–compatible redirects, Spring will send a 303 status code with an accompanying Location header. Refreshing of a POST request is in principle not possible because a POST request is considered to be a non-repeatable transaction (consider making a reservation); RFC2616 states that a 303 status code has to redirect the browser to the URL specified by the Location header, without any questions being asked in the case of a POST request. The RedirectView essentially solves the problem of refreshing after a POST request because a GET request is inserted right after it. The user will no longer receive warnings. Refer to http://ppewww.ph.gla.ac.uk/~flavell/www/post-redirect.html for more information on redirects after POSTs. The following is an excerpt from a SimpleFormController:

public void onSubmit(Object command)  throws Exception {   // save the command object   RedirectView rv = new RedirectView("/confirm.action");   rv.setContextRelative(true);   rv.setHttp10Compatible(false);   return new ModelAndView(rv); }

Of course, wiring up RedirectViews can also be done using the ResourceBundleViewResolver in combination with a resource bundle containing view definitions:

 # views.properties confirm.class=org.springframework.web.servlet.view.RedirectView confirm.http10Compatible=false confirm.url=/confirm.action 

As you read before, the RedirectView adds any additional objects from the model as request parameters to the URL it redirects the client to. Instead of confirming for the user the successful execution of the action, we could also show him the show, using a ViewShowController (using a DAO to load a show and add it to the model):

public void onSubmit(Object command)  throws Exception {   Show show = (Show)command;   //save the show   ModelAndView mav = new ModelAndView("showdetails-rd", "show",      new Long(show.getId());   return mav; }     # views.properties showdetails-rd.class=org.springframework.web.servlet.view.RedirectView showdetails-rd.http10Compatible=false showdetails-rd.url=/show.view 

Returning the view like this will result in the following URL being set as the Location header and sent back to the client: http://host.com/show.view?id=<showid>.

Remember that Spring just adds all model attributes to the URL, using the toString() method of the object in the model. With complex toString() implementations, this might result in problems with the length of the URL. Spring encodes the URL so issues with invalid characters in the URL won't arise.

One solution to prevent lengthy URLs is to post process the model. Often objects included in the model come from the database. Looking them up again is no real issue if caching is involved. We've seen people implement a handler interceptor that switched all domain objects in the model for their respective primary keys (of course only when a redirect was issued). Another solution is to derive from RedirectView and create one specific to your application. Removing items from the model that don't make sense and replacing domain objects with their primary keys can then be done if you override the queryProperties() method.

Using View Prefixes to Issue Forwards or Redirects

As an alternative to returning RedirectViews from your controllers, Spring also supports prefixes you can add to the view name that will trigger redirects or forwards. By prefixing the view name, you remove the need to specifically instantiate the RedirectView and you decouple your controller from it. An excellent example of this mechanism is when using it in combination with the SimpleForm Controller. When using a RedirectView directly, we'd have to implement onSubmit() as follows:

public ModelAndView onSubmit(Object command) {   Show show = (Show)command;   // do something with the show here       return new RedirectView("success.html"); }

If we use the redirect prefix, we can change this to the following:

public void doSubmitAction(Object command) {   Show show = (Show)command;   // do something with the show here }

and configure the URL to redirect using the successView property:

<bean >   <!-- other properties here -->   <property name="successView"><value>redirect:success.html</value></property> </bean>

The redirect: prefix issues a redirect; in other words, it calls HttpServletResponse.sendRedirect(). The second prefix Spring offers is the forward: prefix that can be used to forward to another controller (or other Servlet resource) using the Servlet RequestDispatcher. Using the forward: prefix for JSPs is discouraged; Spring offers the InternalResourceView to do this. Use the forward: prefix to forward to yet another controller.



Professional Java Development with the Spring Framework
Professional Java Development with the Spring Framework
ISBN: 0764574833
EAN: 2147483647
Year: 2003
Pages: 188

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net