Sunday, February 27, 2011

Spring MVC - View

Hey
So far we could setup and config spring and make an advance controller. In simple pattern of MVC we have three aspects: Model, View, Controller.
I explain each of them in the following figure-1:

figure-1: MVC diagram

It is a customary pattern in web and every presentation layer framework should handle each of these three aspects. In Spring MVC we have some facilities in Controller which has be explained. Here I'm going to explain what is View and what kind of views can we have.

Different kinds of view are supported in Spring MVC. But first we should define our views in spring configuration file as a view resolver. For example in Spring MVC(Simple CRUD) post we had determined tiles as a view in spring-servlet.xml file:
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/layout/tiles-config.xml</value>
            </list>
        </property>
    </bean>

    <bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
        <property name="order" value="1"/>
    </bean>
all kinds of viewResolver should implements "org.springframework.web.servlet.ViewResolver" and "org.springframework.core.Ordered" so all of them have order property to assign priority. we can have more than one view resolver in spring mvc so we can make priority on this way. so when a result is returned from Controller, Spring MVC looks for the first order of view resolver. if this can handle the return value so view will be accepted but if not it refers to the second one. for example in StudentController:
    @RequestMapping("/edit")
    public String edit() {
        student = studentService.findById(student.getId());
        return "student.edit";
    }

"student.edit" is returned so first spring looks for view resolver and finds tilesViewResolver with order of "1". This kind of viewResolver needs "tilesConfigurer" (a configuration of tiles for more info refer to Spring MVC(Simple CRUD)) and finally in tiles configuration, this return value is handled so it will be accepted.

some other kinds of spring view resolvers are:
  • JSP
        <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
  • FreeMarker
    <bean id="freemarkerConfigurer"
      class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
      <property name="templateLoaderPath" value="/WEB-INF/templates/"/>
    </bean>
     
    <bean id="viewResolver"
      class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
      <property name="suffix" value=".ftl"/>
    </bean>
  • Velocity
    <bean id="velocityConfigurer"
      class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
      <property name="configLocation" value="WEB-INF/velocity.properties"/>
    </bean>
    <bean id="viewResolver"
      class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
      <property name="suffix" value=".vm"/>
    </bean>
  • Tiles
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
            <property name="definitions">
                <list>
                    <value>/WEB-INF/layout/tiles-config.xml</value>
                </list>
            </property>
    </bean>

    <bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
            <property name="order" value="1"/>
    </bean>
  • ...
in jsp files spring mvc has some basic tags that I am going explain them. These are so simple and basic tags. one of the weakness points of spring MVC is this. there are no advance tag libraries for Spring MVC or even a framework on top of it to handle that (like RichFaces on top of JSF). I had begun a project in PMT in spring framework to make a powerful tag library based on JQuery UI and this project is done successfully.
There are 2 kinds of tags:
  • html tags: <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
    • form: Renders an HTML 'form' tag and exposes a binding path to inner tags for binding.
    • input: Renders an HTML 'input' tag with type 'text' using the bound value.
    • password: Renders an HTML 'input' tag with type 'password' using the bound value.
    • hidden: Renders an HTML 'input' tag with type 'hidden' using the bound value.
    • select: Renders an HTML 'select' element. Supports databinding to the selected option.
    • option: Renders a single HTML 'option'. Sets 'selected' as appropriate based on bound value.
    • options: Renders a list of HTML 'option' tags. Sets 'selected' as appropriate based on bound value.
    • radiobutton: Renders an HTML 'input' tag with type 'radio'.
    • radiobuttons: Renders multiple HTML 'input' tags with type 'radio'.
    • checkbox: Renders an HTML 'input' tag with type 'checkbox'.
    • checkboxes: Renders multiple HTML 'input' tags with type 'checkbox'.
    • textarea: Renders an HTML 'textarea'.
    • errors: Renders field errors in an HTML 'span' tag.
    • label: Renders a form field label in an HTML 'label' tag.
  • spring tags: <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
    •  htmlEscape: Sets default HTML escape value for the current page.
                  Overrides a "defaultHtmlEscape" context-param in web.xml, if any.
    • escapeBody: Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping.
                  The HTML escaping flag participates in a page-wide or application-wide setting
                  (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
    • message: Retrieves the message with the given code, or text if code isn't resolvable.
                  The HTML escaping flag participates in a page-wide or application-wide setting
                  (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
    • theme: Retrieves the theme message with the given code, or text if code isn't resolvable.
                  The HTML escaping flag participates in a page-wide or application-wide setting
                  (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
    • hasBindErrors: Provides Errors instance in case of bind errors.
                  The HTML escaping flag participates in a page-wide or application-wide setting
                  (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
    • nestedPath: Sets a nested path to be used by the bind tag's path.
    • bind: Provides BindStatus object for the given bind path.
                  The HTML escaping flag participates in a page-wide or application-wide setting
                  (i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
    • transform: Provides transformation of variables to Strings, using an appropriate
                  custom PropertyEditor from BindTag (can only be used inside BindTag).
                  The HTML escaping flag participates in a page-wide or application-wide setting
                  (i.e. by HtmlEscapeTag or a 'defaultHtmlEscape' context-param in web.xml).
    • url: URL tag based on the JSTL c:url tag.  This variant is fully
              backwards compatible with the standard tag.  Enhancements include support
              for URL template parameters.
    • param: Parameter tag based on the JSTL c:param tag.  The sole purpose is to
              support params inside the spring:url tag.
    • eval: Evaluates a Spring expression (SpEL) and either prints the result or assigns it to a variable.
the form tag has commandName attribute. look this:
<form:form id="studentForm" commandName="student">
...
</form:form> 
It is the name of the model attribute under which the form object is exposed. Defaults to 'command'. model attribute is detemine in controller.
As you remember in Spring MVC(Simple CRUD) sample the controller sets itself to the model attribute and the name is "command":
@ModelAttribute("command")
public BaseController init(HttpServletRequest request, HttpServletResponse response, Model model) {
        this.model = model;
        this.request = request;
        this.response = response;
        ServletRequestDataBinder binder = new ServletRequestDataBinder(this, "command");
        binder.bind(request);
        return this;
    }
code-1

so there is no need to set commandName attribute of form tag in student-edit.jsp because its default is "command".
<form:form id="studentForm">
    <form:hidden path="student.id"/>
    <table>
        <tr>
            <td>name</td>
            <td><form:input path="student.name"/></td>
        </tr>
        <tr>
            <td>average</td>
            <td><form:input path="student.average"/></td>
        </tr>
    </table>
    <input type="submit" value="save" onclick="setFormAction('/student/save.html')"/>
</form:form>
code-2

Ok maybe the major question is what's the need of commandName? commandName do nothing for formTag but most of spring tags have "path" attribute to bind a value from model and set it to model in request time as you can see it in above sample in red. path value is a field of model attribute which is determined commandName attribute of form tag. For example 'path="student.name"' means 'command.student.name' because the default value of commandName attribute is 'command'. command is a type of studentController (look code-1). Finally 'path="student.name"' means "studentController.getStudent().getName()". And in request time it means "studentController.getStudent().setName(input value)".
In Spring MVC(Simple CRUD) I use simple spring tags and tiles as viewResolver. In future posts I'll use more advanced spring tags like: message, bind, security and so on.


all rights reserved by Mostafa Rastgar and Programmer Assistant weblog

No comments: