spring bind相关资料

spring bind相关资料

spring 2007-07-26 10:30:44 阅读41 评论0 字号:

在Spring框架体系下,可以说规约最少,最不受限制的就是表现层技术了。不像Struts,改定了好多的标签,而且有些功能还和标签绑定了。Sping也定义了一些标签,但这些标签只是给使用者提供了一些方便,并不会提供额外的功能或效果。
    Sping Tag比较少,不超过十个,这里只介绍最常用的一个<sping:bind>,也叫作Spring绑定。
    下面以一个登陆事例为例,controller使用的是SimpleFormController。
 
web.xml就不说了,先看 /WEB-INF/mvc-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
 <!--InternalResourceViewResolver-->
 <bean id="viewResolver"
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix">
   <value>/WEB-INF/jsp/</value>
  </property>
  <property name="suffix">
   <value>.jsp</value>
  </property>
 </bean>
 
 <!--SimpleUrlHandlerMapping-->
 <bean id="urlHandlerMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
  <property name="mappings">
   <props>
    <prop key="/index.htm">indexController</prop>
    <prop key="/login.htm">loginController</prop>
   </props>
  </property>
 </bean>
 
 <!--ParameterizableViewController-->
 <bean id="indexController"
  class="org.springframework.web.servlet.mvc.ParameterizableViewController">
  <property name="viewName">
   <value>login</value>
  </property>
 </bean>
 
 <!--SimpleFormController-->
 <bean id="loginController"
  class="com.yangsq.controller.LoginController">
  <property name="formView">
   <value>login</value>
  </property>
  <property name="successView">
   <value>success</value>
  </property>
  <property name="commandClass">
   <value>com.yangsq.domain.LoginForm</value>
  </property>
  <property name="sessionForm">
   <value>true</value>
  </property>
  <property name="commandName">
   <value>loginForm</value>
  </property>
 </bean>
</beans>

indexController作用只是把页面转到/WEB-INF/login.jsp,起到逻辑控制的是loginController。其中红色标记的部分就是在页面中绑定是使用的名称,即用loginForm代表这个表单类(使用更多的是command作为 commandName 的值,但这只是一个代替符号问题)。但是不要认为loginForm仅仅代表这个表单类,实际上它更像一个model,除了表单类,它还包括了其他一些信息,例如错误信息(BinException对象)。

import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.yangsq.domain.LoginForm;

public class LoginController extends SimpleFormController {

 protected ModelAndView onSubmit(Object command, BindException errs) throws Exception {
  LoginForm loginForm = (LoginForm) command;
  
  if ("yangsq".equals(loginForm.getUsername()) && "123".equals(loginForm.getPassword())) {
   return new ModelAndView(this.getSuccessView(), "username", loginForm.getUsername());
  } else {
   errs.reject("errCode","用户名或密码错误");
   return new ModelAndView(this.getFormView(), errs.getModel());
  }
 }
}

这是一个逻辑很简单的一个Controller。其中红颜色标记的字体下面会说明。

看登陆页面/WEB-INF/jsp/login.jsp:

<%@ page language="java" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="/WEB-INF/tags/c.tld"%>
<%@ taglib prefix="spring" uri="/WEB-INF/tags/spring.tld" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language" content="cn-zh" />
   <title>main</title>
  </head>
  <BODY>
  <FORM action="login.htm" method="post">
 <TABLE>
  <TBODY>
   <TR>
    <TD>
     <spring:bind path="loginForm.username">
      用户名:<INPUT name="${status.expression}" type="text" value="${status.value}"/>
     </spring:bind>
    </TD>
   </TR>
   <TR>
    <TD>
     <spring:bind path="loginForm.password">
      密码:<INPUT name="${status.expression}" type="password" value="${status.value}"/>
     </spring:bind>
    </TD>
   </TR>
   <TR>
    <TD>
     <spring:bind path="loginForm.*">
      <font color="red"><c:out value="${status.errorMessage}" /></font>
     </spring:bind>
    </TD>
   </TR>
   <TR>
    <TD align="center">
     <INPUT type="submit" value="提交" />
    </TD>
   </TR>
  </TBODY>
 </TABLE>
  </FORM>
  </BODY>
</html>

<sping:bind>的path属性制定了与表单中的那个属性绑定,这样,${status.expression}就代表了那个属性的名称,${status.expression}代表那个属性的值。如果path属性为“XXX.*”则与那个表单的所有属性绑定。

上面的例子表单有两个属性username和password。实际上绑定方式有两种,第一种就像上面的那样,第二种如下:

......
  <spring:bind path="loginForm">
      用户名:<INPUT name="username" type="text" value="${loginForm.username}"/><br>
      密码:<INPUT name="password" type="password" value="${loginForm.password}"/>
     </spring:bind>

......

这种情况input的name属性就不能用${status.expression}代表了。

使用<sping:bind>标签,在初次进入表单页面时并不会有什么作用,而是当表单提交后,如果有BindException错误时再返回这个页面时,可以把先前的输入显示在input里。

好了,现在该来看看对错误(BindException)的处理了。可以看到LoginController中用红色标出的代码。它调用了BindException的reject方法,这样,再调用BindException的getModel()方法,就把错误连同表单等信息一并返回到表单页面用以显示。

reject方法的第一个参数是错误码,如果设定了国际化资源,则显示资源文件中该错误码对应的错误条目,如果没有设定了国际化资源,则显示reject方法的第二个参数。

reject方法的不足之处是在表现层不能区分错误消息属于那个字段,即不能说明是username不对呢还是password不对。解决这种情况可以使用rejectValue方法,这也是更一般使用的方法。rejectValue方法定义如下:

rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage)

第一个参数指定表单的域,即username或password,这样就可以分辨到底是那块出了问题;第二个参数和reject方法的第一个参数一样,制定错误码;第三个参选数制定了资源文件中的占位符;第四个参数和和reject方法的第二个参数一样。rejectValue方法还有一个简化的定义:

rejectValue(String field, String errorCode, String defaultMessage)

上面是在Controller里使用的方法,使用上述方法后,若果出现BindException错误,返回表单页面时就会显示错误信息,那么如何在页面里显示错误信息呢?

上面/WEB-INF/jsp/login.jsp里由于在controller里使用的是reject方法,所以只能那么显示,如果我们使用rejectValue方法,例如改动LoginController:

......

rejectValue("username", "nameErr", null, "用户名错误");

......

rejectValue("password", "passErr", null, "密码错误");

......

这样,就可以把页面改为如下:

......
<spring:bind path="loginForm.username">
      用户名:<INPUT name="${status.expression}" type="text" value="${status.value}"/>
      <font color="red"><c:out value="${status.errorMessage}" /></font>
</spring:bind>
......
<spring:bind path="loginForm.password">
      密码:<INPUT name="${status.expression}" type="password" value="${status.value}"/>
     <font color="red"><c:out value="${status.errorMessage}" /></font>
</spring:bind>

这样错误的消息就绑定到相应的字段了。当然也可以不制定某个字段,一股脑都输出

......
<spring:bind path="loginForm.*"><font color="red">错误如下:
     <c:forEach items="${status.errorMessages}" var="err">
          <c:out value="${err}" />
     </c:forEach>
    </font>
</spring:bind>

关于Sping Tag,就学这么多,学完了bean管理,controller体系,Sping view技术,下面该是Spring持久了:)

 
(1)一个常见的错误:
不通过controller直接访问含有spring:bind标签的JSP页面会出现下面的错误:
javax.servlet.ServletException: Neither Errors instance nor plain target object for bean name 'person' available as request attribute
解决办法:
http://spring.jactiongroup.net/viewtopic.php?p=5482

(2)星号(*)的意思
global and all field errors,
    ## use wildcard (*) in place of the property name
    <spring:bind path="company.*">
        <c:forEach items="${status.errorMessages}" var="error">
       c:out value="${error}"/><br/>
        </c:forEach>
    </spring:bind>

(3)command的意思
   3-1 commandClass
   相当于struts中的ActionForm,用来封装V中的数据,方便在C中使用。

3-2 commandName
   用来指定JSP中的数据需要绑定到哪个对象。默认为command
   比如下面的配置中,commandName就是command
     <spring:bind path='command.email'>
     <td><input type='text' name='${status.expression}'
                value='${status.value}' size='30'
                maxlength='100'></td></tr>
     </spring:bind>
因为是缺省值,所以它就不需要再在Controller中显示声明

如果在Controller中设置了setCommandName("me");则上面的配置文件需要改为:
     <spring:bind path='me.email'>
     <td><input type='text' name='${status.expression}'
                value='${status.value}' size='30'
                maxlength='100'></td></tr>
     </spring:bind>
简单吧。

(4)一个要注意的问题(原文链接

一个普通的<spring.bind>的使用类似于:

<spring:bind path="user.age">
      <input type="text" name="age" value="${status.value}">
      <font color="red">${status.errorMessage}</font>
</spring:bind>

需要注意的是:<input>的name属性值必须与<spring:bind>的path属性的匹配,否则就绑定不了!

例如下面的代码就绑定不了

<spring:bind path="user.age">
      <input type="text" name="theAge" value="${status.value}">
      <font color="red">${status.errorMessage}</font>
</spring:bind>

为了避免手误,强烈推荐下列方法来绑定:

<spring:bind path="user.age">
      <input type="text" name="${status.expression}" value="${status.value}">
      <font color="red">${status.errorMessage}</font>
</spring:bind>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值