Struts2开发--类型转换

一、Struts2 类型转换介绍
 
类型转换:解析HTTP请求参数,将Http请求参数赋值给Action的属性;比如:
 
 
<s:form action="valid" > 
 <s:textfield label="用户名" name="name"></s:textfield>  
<s:password label="密码" name="password"></s:password>  
<s:textfield label="年龄" name="age"></s:textfield>   
<s:submit value="提交"></s:submit>
</s:form>
 
此处将名为name、password、age的值赋值给Action的属性,类型转换是指这个赋值过程中可能出现的类型不一致问题而做出的转换,因为HTTP参数都是字符串类型的;因此从String类型的age参数传给int类型的age属性时,就需要类型转换,当然这些struts2框架已经做完了,开发人员不需要自行处理;
Struts2已经内建了对于String和基本类型的类型转换,比如String<-->int 、String<-->boolean等;
Action属性一定要有getter和setter方法!
Struts2提供了强大的类型转换支持,不仅提供了内置的类型转换器,还可以自定义类型转换器,以满足自定义需求;
Struts2类型转换是通过params拦截器进行转换;如果转换失败,则conversionError拦截器拦截该异常,并封装到fieldError中,放入ActionContext中;
Struts2类型转换还支持OGNL表达式,只需要在表单控件的name属性使用ognl表达式即可,比如表单控件的name属性为user.name,则此控件的数据将进入赋值给Action的user属性中的name属性;
 
二、通过一个例子初步了解Struts2类型转换
 
 
此处的类型转换因为是内建的,因此代码上和原来的struts2应用没有不同,struts2框架内部完成了所有了类型转换,以下程序是将name、age赋值给Action类的name、age属性,gender、salary赋值给p.gender、p.salary属性;struts.xml的配置和原来一样,所以就不给出了;
 
Conversion01Action.java
 
 
package org.conversion.action;
 
import org.person.Person;
 
import com.opensymphony.xwork2.ActionSupport;
 
public class Conversion01Action extends ActionSupport {
 
    private String name;
    private int age;
    private Person p ;
    public String execute()throws Exception{
        System.out.println(name);
        System.out.println(age);
        System.out.println(p.getGender());
        System.out.println(p.getSalary());
        return SUCCESS;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person getP() {
        return p;
    }
    public void setP(Person p) {
        this.p = p;
    }
    
    
}
 
1. jsp
 
此处需要注意的是性别、薪水的表单控件的name属性是OGNL表达式;
 
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
    <%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<s:fielderror></s:fielderror>
    <s:form action="conversion01" >
        <s:textfield label="姓名" name="name"></s:textfield>
        <s:textfield label="年龄" name="age"></s:textfield>
        <s:textfield label="性别" name="p.gender"></s:textfield>
        <s:textfield label="薪水" name="p.salary"></s:textfield>
        <s:submit value="提交"></s:submit>
    </s:form>
</body>
</html>
 
补充:List 和Map 的Action属性的类型转换问题
 
前面我们将的都是基本类型和自定义类型,因此这里我们将讲述集合类型的类型转换问题;
如果Action的属性为List类型,List<String>lists ,则表单控件的命名方式为lists[i] ,如lists[0]表示第1个元素;
如果Action的属性为Map类型,Map<String,Person> maps;则表单控件的命名方式为maps[ ' first ' ].salary ,表示map中key为'first'的value中的salary属性;
 
以上的list和map类型属性都通过泛型的方式说明集合元素的类型,如果在JDK1.5之前,泛型没有出现,则需要通过局部类型转换文件进行表示;
局部类型转换文件:对于特定Action的特定属性有效,位于特定Action同一目录下,命名规则:ActionName-conversion.properties;
 
对于List元素来说,内容如 :Element_attributeName=typeName;
对于Map元素来说,
(1)如果表示key的类型,则:Key_attributeName=typeName;
(2)如果表示value的类型,则为:Element_attributeName=typeName;
 
 
比如,此处没有使用泛型,而是使用了局部类型转换文件:
 
Conversion02Action.java
 
package org.conversion.action;
 
import java.util.List;
import java.util.Map;
 
import org.person.Person;
 
import com.opensymphony.xwork2.ActionSupport;
 
public class Conversion02Action extends ActionSupport {
    private List lists;
    private Map maps;
    public String execute()throws Exception{
        System.out.println(((Person)lists.get(0)).getGender());
        System.out.println(((Person)lists.get(0)).getSalary());
        System.out.println(((Person)maps.get("one")).getGender());
        System.out.println(((Person)maps.get("one")).getSalary());
        return SUCCESS;
    }
    public List getLists() {
        return lists;
    }
    public void setLists(List lists) {
        this.lists = lists;
    }
    public Map getMaps() {
        return maps;
    }
    public void setMaps(Map maps) {
        this.maps = maps;
    }
    
}
 
Conversion02Action-conversion.properties
 
 
Element_lists=org.person.Person
Key_maps=java.lang.String
Element_maps=org.person.Person
 
2.jsp
 
 
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
    <%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<s:fielderror></s:fielderror>
    <s:form action="conversion02" >
        <s:textfield label="list1.salary" name="lists[0].salary"></s:textfield>
        <s:textfield label="list1.gender" name="lists[0].gender"></s:textfield>
        <s:textfield label="map1.gender" name="maps['one'].gender"></s:textfield>
        <s:textfield label="map1.salary" name="maps['one'].salary"></s:textfield>
        <s:submit value="提交"></s:submit>
    </s:form>
</body>
</html>
 
 
Conversion02Action-conversion.properties
 
 
Element_lists=org.person.Person
Key_maps=java.lang.String
Element_maps=org.person.Person
 
 
 
 
 
 
 
三、自定义类型转换器
 
1.继承DefaultTypeConverter
 
 
如果我们自定义一个类型转换器,第一种方法是继承DefaultTypeConverter,并重写public Object convertValue(ActionContext context,Object value,Class toType);
这个函数的功能是完成双向转换,即从String数组转到Action属性及Action属性转到String;需要注意的是从String数组转到Action属性,而不是String转到Action属性;如果只有一个字符串,则取params[0] 即可;
 
因此一般此函数的模板代码如下:
 
 
public Object convertValue(Map<String, Object> context, Object value,
            Class toType) {
        if(toType==String.class){
            ......
            return String;
        }
        else if(toType==Action属性.class){
            String params[] = (String[])value;//必须是字符串数组
            .......
            return Action属性;
        }
        return null;
    }
 
完成自定义类型转换器编写后,如果需要使用此转换器,就需要配置,通常有两种配置方法:
1.局部类型转换文件中配置,仅对特定的Action的特定属性有效,比如在Action1中有aa属性,则仅对Action1的aa属性有效;
2.全局类型转换文件中配置,对某个类型都有效;比如对Person注册了类型转换器,则对任何Person和String的转换都有效;
 
全局类型转换文件命名为:xwork-conversion.properties,通常放在WEB-INF\classes下;
文件内容如:attributeName=ConvertClass ,比如aa=org.convert.Converter1
attributeName表示属性名称,convertClass表示转换器的实现类;
局部类型转换文件命名为:ActionName-conversion.properties,放在特定Action的目录下;
文件内容如:typeName=ConvertClass,比如org.person.Person = org.convert.Converter2
 
注意:typeName表示转换类型,convertClass表示转换器的实现类;
 
代码示例:
 
Conversion03Action.java
 
 
package org.conversion.action;
 
import org.person.Person;
 
import com.opensymphony.xwork2.ActionSupport;
 
public class Conversion03Action extends ActionSupport {
 
    private Person p ;
    public String execute()throws Exception{
        System.out.println(p.getGender());
        System.out.println(p.getSalary());
        return SUCCESS;
    }
    public Person getP() {
        return p;
    }
    public void setP(Person p) {
        this.p = p;
    }
 
}
 
Converter01.java
 
 
package org.converter;
 
import java.util.Map;
 
import org.person.Person;
 
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
 
public class Converter01 extends DefaultTypeConverter {
 
    @Override
    public Object convertValue(Map<String, Object> context, Object value,
            Class toType) {
        if(toType==String.class){
            Person p = (Person)value;
            return p.getSalary()+","+p.getGender();
        }
        else if(toType==Person.class){
            String params[] = (String[])value;
            String[]values = params[0].split("\\,");
            Person p = new Person();
            p.setGender(values[1]);
            p.setSalary(Double.parseDouble(values[0]));
            return p;
        }
        return null;
    }
 
}
 
3.jsp
 
 
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
    <%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<s:fielderror></s:fielderror>
    <s:form action="conversion03" >
        <s:textfield label="薪水,性别" name="p"></s:textfield>
        <s:submit value="提交"></s:submit>
    </s:form>
</body>
</html>
 
Conversion03Action-conversion.properties
 
p=org.convert.Converter01
 
 
2.继承StrutsTypeConverter
 
StrutsTypeConverter是DefaultTypeConverter的子类,DefaultTypeConverter的类型转换器是在一个函数中进行双向转换,而继承StrutsTypeConverter的类型转换器则是将两个方向分别用两个函数实现:
 
 
@Override
public Object convertFromString(Map context, String[] values, Class toClass) {
 
}
 
@Override
public String convertToString(Map context, Object o) {
 
}
 
 
将DefaultTypeConverter中的Converter01换成如下代码就可以完成StrutsTypeConverter的类型转换器;
 
 
 
package org.converter;
 
import java.util.Map;
 
import org.apache.struts2.util.StrutsTypeConverter;
import org.person.Person;
 
public class Converter02 extends StrutsTypeConverter {
 
    @Override
    public Object convertFromString(Map context, String[] value, Class toClass) {
        String params[] = (String[])value;
        String[]values = params[0].split("\\,");
        Person p = new Person();
        p.setGender(values[1]);
        p.setSalary(Double.parseDouble(values[0]));
        return p;
    }
 
    @Override
    public String convertToString(Map context, Object o) {
        Person p = (Person)o;
        return p.getSalary()+","+p.getGender();
    }
}
 
xwork-conversion.properties
 
 
orgorg.person.Person=org.converter.Converter02
 
 
四、错误处理机制
 
客户输入错误信息是很正常的事,因此需要对此种行为进行处理,Struts2提供了很好的错误处理机制,是由conversionError拦截器自动完成,我们只需要配置输出什么错误信息即可;
当发生类型转换错误时,conversionError拦截器拦截此错误,并封装成fieldError,将此错误信息放入ActionContext中,并返回input逻辑视图;当然在<action>元素中必须配一个类似于<result name="input">/1.jsp</result>的子元素,以应对类型转换错误;
而为了显示错误信息,则在jsp页面中使用<s:fielderror/>即可显示错误信息;
注意:类型转换的Action在struts.xml中配置所在包需要extends="struts-default",因此在此文件中包含conversionError拦截器;
 
这时我们需要配置显示的错误信息,错误信息配置方式有两种:
 
 
1.配置默认提示信息
 
 
在国际化资源文件中配置形如:
xwork.default.invalid.fieldvalue={0},错误;
{0}代表类型转换错误的属性名称;
 
 
2.配置Action特定属性错误信息
 
 
在Action范围的国际化资源文件中配置形如:
invalid.fieldvalue.attributeName= 内容
attributeName是Action中的属性名称;
 
我们在上面的程序中添加类型转换错误的消息:
 
在Conversion04Action_zh_CN.properties中添加:
 
 
<span style="font-family:'Microsoft YaHei';">invalid.fieldvalue.p=person类型转换错误;</span>
意思是对p属性配置了特定的错误提示信息,当p属性类型转换错误后就会显示此信息;
 
摘自xiazdong的专栏 http://www.2cto.com/kf/201202/118296.html
基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值