Spring 的<spring:transform>标签必须位于<spring:bind>标签之中,搭配 PropertyEditor 使 用的话,您可以将 Command 的属性值转换为您所要的字串格式。
举个实际的例子来说,假设您的 Command 中储存了星期的数字表示,例如星期一使用"1"表示, 星期二使用"2"表示…星期日使用"0" 表示,然而您希望在填写表示时,您可以在表单上显示的 是"MON"、"THU"、"WED"等字样,您希望使用程式自动帮您完成转换。
可以先设计一个 WeekForm 类别,收集请求参数值"0"到"6":
package onlyfun.caterpillar; public class WeekForm { private String weekNumber; public void setWeekNumber(String weekNumber) { this.weekNumber = weekNumber; } public String getWeekNumber() { return weekNumber; } }
weekNumber 储存的是"1"、"2"、"3"之类的请求参数值,接着您可以设计一个 WeekPropertyEditor 类别来转换这些参数值为"MON"、"TUE"到"SUN":
package onlyfun.caterpillar; import java.beans.PropertyEditorSupport; public class WeekPropertyEditor extends PropertyEditorSupport { public void setAsText(String text) { if("MON".equals(text)) { setValue("1"); } else if("TUE".equals(text)) { setValue("2"); } else if("WED".equals(text)) { setValue("3"); } else if("THU".equals(text)) { setValue("4"); } else if("FRI".equals(text)) { setValue("5"); } else if("SAT".equals(text)) { setValue("6"); } else if("SUN".equals(text)) { setValue("0"); } else { setValue(""); } } public String getAsText() { if(this.getValue() != null && !(this.getValue() instanceof String)) { return ""; } String text = (String) this.getValue(); if("1".equals(text)) { return "MON"; } else if("2".equals(text)) { return "TUE"; } else if("3".equals(text)) { return "WED"; } else if("4".equals(text)) { return "THU"; } else if("5".equals(text)) { return "FRI"; } else if("6".equals(text)) { return "SAT"; } else if("0".equals(text)) { return "SUN"; } else { return text; } } }
您在设计 Controller 时,必须重新定义 initBinder()方法以注册这个自订的 PropertyEditor, 例如:
package onlyfun.caterpillar; import org.springframework.web.servlet. mvc.SimpleFormController; import org.springframework.web.servlet.*; import java.util.*; import javax.servlet.http.HttpServletRequest; import org.springframework.validation.BindException; import org.springframework.web. bind.ServletRequestDataBinder; public class WeekFormController extends SimpleFormController { private Map refData; public WeekFormController() { setCommandClass(WeekForm.class); refData = new HashMap(); List list = new ArrayList(); for(int i = 0; i < 7; i++) { list.add(String.valueOf(i)); } refData.put("weekNumbers", list); } protected ModelAndView onSubmit(Object command, BindException errors) throws Exception { WeekForm form = (WeekForm) command; if(form.getWeekNumber() == null) { return new ModelAndView(this.getFormView()); } else { return new ModelAndView( this.getSuccessView(), errors.getModel()); } } protected Map referenceData( HttpServletRequest request) throws Exception { return refData; } protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { super.initBinder(request, binder); binder.registerCustomEditor( String.class, new WeekPropertyEditor()); } }
在建构 WeekFormController 时,会预先准备好"0"到"6"的字串值,referenceData()方法会返回 包括这些字串值的 Map 物件,以在页面上加以显示,由于在 initBinder()中注册了自订的 WeekPropertyEditor,再配合<spring: transform>标签,就可以在页面上显示"SUN"、"MON"等 文字,页面 form.jsp 的设计如下所示,当中搭配了 JSTL 来协助页面 逻辑的撰写:
<%@page contentType="text/html"%> <%@page?pageEncoding="UTF-8"%> <%@taglib?prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="spring"uri="http://www.springframework.org/tags"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <spring:bind path="command.*"> <font color="red"><c:out value="${status.errorMessage}"/> </font> </spring:bind> <form name="weekForm" action="/TransFormTagDemo/weekForm.do" method="POST"> <spring:bind path="command.weekNumber"> <select name="weekNumber"> <c:forEach var="weekNumber" items="${weekNumbers}" > <spring:transform value="${weekNumber}" var="weekName"/> <c:choose> <c:when test="${status.value == weekName}"> <option value="<c:out value="${weekName}"/>" selected> </c:when> <c:otherwise><option value="<c:out value="${weekName}"/>"> </c:otherwise> </c:choose> <c:out value="${weekName}"/> </option> </c:forEach> </select> </spring:bind> <input type="submit" value="Submit"/> </form> </body> </html>
Bean 定义档如下撰写,由于使用了 JSTL,所以在 InternalResourceViewResolver 的"viewClass" 的设定上可以使用 JstlView 类别:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN""http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="viewResolver" class="org.springframework.web.servlet. → view.InternalResourceViewResolver"> <property name="viewClass"> <value> org.springframework.web.servlet.view.JstlView </value> </property> <property name="prefix"> <value>/WEB-INF/jsp/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <bean name="/weekForm.do" class="onlyfun.caterpillar.WeekFormController"> <property name="formView"> <value>form</value> </property> <property name="successView"> <value>success</value> </property> </bean> </beans>