一、Struts标签的使用
(1)<s:select>标签
<select name="empDepartmentCode"> <option value="E000001">IT部</option> <option value="E000002">市场部</option> <option value="E000003">销售部</option> </select> <s:select list="#request.deptList" name="empDepartmentCode" listKey="departmentCode" listValue="departmentName" headerKey="" headerValue="--请选择部门--" theme="simple" onchange=""> <!-- list:是要显示的集合,这里是deptList集合 name:Department的empDepartmentCode属性,对应的是<select name="">中的name属性 listKey:要显示的元素的标识,Department的departmentCode属性,对应的是<option value="">中的value属性 listValue:要显示的元素的文字内容,Department的departmentName属性,对应的是<option>元素中间的值 headerKey:默认头部显示的值的标识 headerValue: 默认头部显示的元素的文字内容 --> </s:select> e.g: <s:select list="{'aa','bb','cc'}" theme="simple" headerKey="00" headerValue="00"></s:select> <s:select list="#{1:'aa',2:'bb',3:'cc'}" label="abc" listKey="key" listValue="value" headerKey="0" headerValue="aabb"> <% HashMap map = new LinkedHashMap(); map.put(1,"aaa");map.put(2,"bbb"); map.put(3,"ccc"); request.setAttribute("map",map); request.setAttribute("aa","2"); %> <s:select list="#request.map" label="abc" listKey="key" listValue="value" value="#request.aa" headerKey="0" headerValue="aabb"></s:select> <s:select list="discussions" listKey="id" listValue="discussionName" name="seldis" value="%{subject.discussion.id}"></s:select>
(2)struts2标签获取parameter,request,session,application中的值,有三种方式
<!-- parameters --> <s:property value="#parameters.mySessionPropKey"/> <s:property value="#parameters['mySessionPropKey']"/> <s:property value="#parameters['myRequestPropKey']"/> <!-- request --> <s:property value="#request.mySessionPropKey"/> <s:property value="#request['mySessionPropKey']"/> <s:property value="#request['myRequestPropKey']"/> <!-- session --> <s:property value="#session.mySessionPropKey"/> <s:property value="#request['mySessionPropKey']"/> <s:property value="#request['myRequestPropKey']"/> <!-- application --> <s:property value="#application.mySessionPropKey"/> <s:property value="#application['mySessionPropKey']"/> <s:property value="#application['myRequestPropKey']"/>参考资料: http://struts.apache.org/release/2.1.x/docs/ognl.html
(3)EL表达式从request、session等中取值
<!-- 从request、session、application中取值都类似 --> <input value="${requestScope.dept.departmentCode}" name="departmentCode" type="text" /> <input value="${sessionScope.dept.departmentCode}" name="departmentCode" type="text" />
四、Struts自定义类型转换器
类型转换有局部转换和全局转换,相对而言局部转换用的更多。局部转换就是针对一个action去编写一个配置文件,对这个action里的私有
属性进行类型转换,全局转换是针对一个对象,只要这个对象属性出现了就进行类型换。自定义转换器有以下两个步骤:
1) 继承StrutsTypeConverter,实现convertFromString和convertToString两个方法
2) 新建一个文件放在对应的action同一个包下:
局部转换器命名规则:类名-conversion.properties
文件内容填写规则:属性名=进行类型转换操作类的全名(局部),
public class PointConverter extends StrutsTypeConverter { //客户端的字符串 >> 服务端对象 public Object convertFromString(Map context, String[] values, Class toClass) { /* * context:上下文对象,一般用不上 * values:传进来的值,可能是多个对象的字符串,所以是数组。 * toClass:要转换成的目标类型 */ Point point = new Point(); String value = values[0]; String[] result = value.split(","); point.setX(Integer.parseInt(result[0])); point.setY(Integer.parseInt(result[1])); return point;//然后调用action中的setPoint(Point point)方法把这个值设置进去 } //客户端字符串 << 服务端对象 public String convertToString(Map context, Object o) { Point point = (Point) o; int x = point.getX(); int y = point.getY(); String result = "x: " + x + " y: " + y; return result; } }
配置文件:
3) 全局转换器只是配置文件不一样。
全局转换器命名规则:xwork-converion.properties,文件名不能变。文件放在src目录下,文件内容的格式与局部的一致。
五、Struts校验
1、用编码方式完成数据校验
1) 继承ActionSupport,重写ActionSupport的validate( )方法,validate()方式会验证Action里所有业务方法。
注意:如果重写了该方法(或者有validateXxx()方法),则在struts.xml文件的action节点下应该配置一个reuslt节点,name的值必须为input,
用与指定当验证没通过时要转到的页面
<action name="register"class="com.maple.action.UserAction"method="register"> <result name="toRegisterSuccessJsp" type="dispatcher">/register_success.jsp</result> <result name="input" type="dispatcher">/register.jsp</result> <!--如果该方法是要被验证的,则必须配置一个result节点,且name=“input” --> </action>
2) 要验证指定的方法,可以指定验证的方法名,格式:
validateXxx(),说明该方法是验证xxx()方法的。其他方法执行执行之前不会进行验证。
例如:validateSave(),说明该方法是验证save()方法的。
3) XxxxActiong类中各个方法的执行顺序为:
setXxxxx() ---validateXxx() ---validate() -----Xxx()
注意:如果在set过程中出现类型转换错误会直接被转到INPUT所指页面
4) 修改Struts默认的Field级别错误提示:
在xxxAction同一个目录下新建一个文件:
修改FieldError默认信息命名规则:类名.properties
内容填写规则:invalid.fieldvalue.属性名 = 错误消息
//一、继承ActionSupport public class LoginAction extends ActionSupport { private String username; private Date birthday; public String save() throws Exception { System.out.println("Four:save方法被调用"); return SUCCESS; } //三、自定义验证方法(只对请求save方法的请求进行验证) public void validateSave() { System.out.println("Second:自定义方法被调用"); } //二、重写validate() public void validate() { System.out.println("Three:validate方法被调用"); /* 进行服务端验证 * Struts2把错误消息分为两个级别: * 1) Action级别的Error。Struts不会帮我们生存action消息 * 2) Field级别的Error(字段级别的)。类型转换出现错误时Struts会自动帮我们自动生成Field级别的错误消息 */ if (null == username || -1 != username.indexOf("hello")) { this.addFieldError("username", "username invalid");// 设置Field级别错误消息 } // TODO 如果客户端传过来的日期格式不正确的话就不能成功调用SET方法,这样服务器端的Date属性就是NULL if (null == birthday) { this.addActionError("birthday invalid");// 设置Action级别错误消息 } } public void setUsername(String username) { System.out.println("First:SET方法被调用"); this.username = username; } public String getUsername() { return username; } }
<!-- 输出action级别错误消息 --> <s:actionerror cssStyle="color:red"/> <!-- 输出field级别错误消息 --> <s:fielderror cssStyle="color:blue" ></s:fielderror> <!-- Struts标签的表单已内置错误消息输出功能,这时候不需要去指定输出actionError或FieldError --> <s:form action="login"> <s:textfield name="username" label="username"></s:textfield> <s:textfield name="birthday" label="birthday"></s:textfield> <s:submit value="submit"></s:submit> </s:form>
Struts在返回视图层时会把action里的成员属性值带着一起经过拦截器,然后把属性值包装起来放入值栈ValueStack返回给视图