有一个UserInfo类,它有若干属性,例如用户名,密码,地址等
private String userName;
private String password;
private String address;
...
//有若干getter和setter方法,
public String getUserName(){
   return this.userName;
}public void setUserName(String userName){
   this.userName = userName;
}
...在项目中,由webwork自动将客户端提交的数据,把这个对象的各个属性赋值。
原有用form提交数据的方式时正常,但当改用 ajax方式提交数据时,属性中的中文内容出现乱码。
现在想在webwork的action中再把这个对象的所有是字符串类型的属性的值,强制转换为 GBK 字符集。有没有方法能遍历这个userInfo对象中的所有属性,并将其中是String类型的属性的值,强制转换为GBK呢?请大侠们指导。百分感谢~~! 

解决方案 »

  1.   

    import java.beans.BeanInfo;
    import java.beans.IntrospectionException;
    import java.beans.Introspector;
    import java.beans.MethodDescriptor;
    import java.beans.PropertyDescriptor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import org.apache.commons.beanutils.PropertyUtils;
    import org.apache.log4j.Logger;public class BeanInfoWrapper
    {
        private static Logger logger = Logger.getLogger(BeanInfoWrapper.class);    /**
         * 将指定的值赋值给指定的bean的指定属性。所指定的bean对象必须符合bean的方法命名规则
         * 
         * @param bean
         * @param propertyName
         * @param values
         */
        public static void setPropertyValue(Object bean, String propertyName,
                Object value)
        {
            BeanInfo beanInfo = null;
            try
            {
                beanInfo = Introspector.getBeanInfo(bean.getClass());
            } catch (IntrospectionException e)
            {
                logger.error("获取bean信息时出错");
                e.printStackTrace();
            }
            MethodDescriptor[] methods = beanInfo.getMethodDescriptors();
            PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < properties.length; i++)
            {
                if (propertyName.equals(properties[i].getDisplayName()))
                {
                    Method writeMethod = properties[i].getWriteMethod();
                    try
                    {
                        writeMethod.invoke(bean, new Object[] { value });
                    } catch (IllegalArgumentException e1)
                    {
                        logger.error("属性值与属性的setter方法参数不一致");
                        e1.printStackTrace();
                    } catch (IllegalAccessException e1)
                    {
                        logger.error("没有指定属性的setter方法");
                        e1.printStackTrace();
                    } catch (InvocationTargetException e1)
                    {
                        logger.error("引用属性的setter方法出错");
                        e1.printStackTrace();
                    }
                }
            }
        }    /**
         * 获得指定bean的指定属性值。所指定的bean对象必须符合bean的方法命名规则
         * 
         * @param bean
         * @param propertyName
         * @return
         */
        public static Object getPropertyValue(Object bean, String propertyName)
        {
            Object retVal = null;
            BeanInfo beanInfo = null;
            try
            {
                beanInfo = Introspector.getBeanInfo(bean.getClass());
            } catch (IntrospectionException e1)
            {
                logger.error("获取bean信息时出错");
                e1.printStackTrace();
            }
            PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < properties.length; i++)
            {
                if (propertyName.equals(properties[i].getDisplayName()))
                {
                    Method writeMethod = properties[i].getReadMethod();
                    try
                    {
                        retVal = writeMethod.invoke(bean, new Object[] {});
                    } catch (IllegalArgumentException e)
                    {
                        logger.error("属性的getter方法返回值类型错误");
                        e.printStackTrace();
                    } catch (IllegalAccessException e)
                    {
                        logger.error("没有指定属性的getter方法");
                        e.printStackTrace();
                    } catch (InvocationTargetException e)
                    {
                        logger.error("引用属性的getter方法出错");
                        e.printStackTrace();
                    }
                }
            }
            return retVal;
        }    /**
         * 读取内嵌的bean属性值
         * 
         * @param bean
         * @param property
         * @return
         */
        public static Object getNestValue(Object bean, String property)
        {
            Object temp = bean;
            String[] p = property.split("[.]");
            for (int i = 0; i < p.length; i++)
            {
                temp = getPropertyValue(temp, p[i]);
            }
            return temp;
        }    /**
         * 返回指定类型的一个实例
         * 
         * @param clazz
         * @return
         */
        public static Object newInstance(Class clazz)
        {
            Object retVal = null;
            try
            {
                retVal = clazz.newInstance();
            } catch (InstantiationException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            }
            return retVal;
        }    public static void copyProperties(Object dest, Object orig)
        {
            try
            {
                PropertyUtils.copyProperties(dest, orig);
            } catch (IllegalAccessException e)
            {
                logger.error("没有指定属性的getter方法");
                e.printStackTrace();
            } catch (InvocationTargetException e)
            {
                logger.error("引用属性的getter方法出错");
                e.printStackTrace();
            } catch (NoSuchMethodException e)
            {
                logger.error("没有相应的getter或setter方法");
                e.printStackTrace();
            }
        }    public static void getAllInfo(Object bean)
        {
            String beanTypeName = bean.getClass().getName();
            Class theClass = bean.getClass();
            Method[] methods = theClass.getMethods();
            Field[] fields = theClass.getFields();
            logger.info("***The ClassName of the bean is :" + beanTypeName);
            logger.info("***The method names of bean is :");
            for (int i = 0; i < methods.length; i++)
            {
                Method m = methods[i];
                logger.info(m.getName());
            }
            logger.info("***The field name and type of bean is :");
            for (int i = 0; i < fields.length; i++)
            {
                Field f = fields[i];
                logger.info(f.getName() + " || " + f.getType().getName());
            }
        }    public static Object invodeMethod(Object obj, String name, Object[] args)
        {
            Object retVal = null;
            Class[] types = null;
            Method method = null;
            if (args != null)
            {
                types = new Class[args.length];
                for (int i = 0; i < args.length; i++)
                {
                    types[i] = args[i].getClass();
                }
            }
            try
            {
                method = obj.getClass().getMethod(name, types);
            } catch (SecurityException e)
            {
                logger
                        .error("请确定被调用的方法修饰符是public,如果方法所属的类位于某个package中,请确认该package是可访问的.");
                e.printStackTrace();
            } catch (NoSuchMethodException e)
            {
                logger.error(obj.getClass().getName() + " 没有匹配的方法");
                e.printStackTrace();
            }
            try
            {
                retVal = method.invoke(obj, args);
            } catch (IllegalArgumentException e1)
            {
                logger.error("参数不匹配");
                e1.printStackTrace();
            } catch (IllegalAccessException e1)
            {
                logger.info("方法不可访问");
                e1.printStackTrace();
            } catch (InvocationTargetException e1)
            {
                logger.info("访问方法过程中发生异常");
                e1.printStackTrace();
            }
            return retVal;
        }
    }
    相信对你有帮助,仔细看一下代码的getPropertyValue方法中的内容,就能实现你的功能了
      

  2.   

    > 有没有方法能遍历这个userInfo对象中的所有属性,
    > 并将其中是String类型的属性的值,强制转换为GBK呢?“遍历所有属性”并不难,就像楼上说的,反射就可以了。问题是“将其中是String类型的属性的值,强制转换为GBK”这个事情就有问题了。String 类型的值,就是一个字符串对象,在 Java 里本身是无所谓“编码方式”的,也就无所谓“转换为 GBK”一说了。如果这个字符串是乱码的,那么是当初给它赋值的时候就已经乱掉了。当初给它赋值的时候,一定把某个字节数组(或者是字节流)转成字符串的,转的时候需要指定编码方式,如果指定错了,得到的字符串就是乱的。如果得到的字符串对象已经是乱码了,那么原则上是没什么好办法的。经常看到有人用 str = new String(str.getBytes(encoding1), encoding2) 来“处理乱码问题”,这其实是不对的。虽然有时候从现象上看好像能解决问题,但由于方法并不正宗,不是从根本上解决问题,所以实际上还会隐藏着问题。
      

  3.   

    在的web应用里加一个转换的filter应该就可以了主要的思路就是整体转换字符集,一般网络传输过程中是ISO8859-1
    那你就 String new_str = new String(old_str.getBytes("ISO8859_1"),"GBK");
      

  4.   

    是的。就是想整体字符转换。这个对象里面有很多个属性啊,如果一个个手写代码转换要累死人啊。而且,在webwork的action里,通常没有 request.getParamerts("参数名") 的
    在转到action之前,webwork已经把客户端提交的内容组装到userInfo对象里了。
      

  5.   

    函数是这样:
    public static Object setAllString2GBK(Object obj) {
        BeanInfo beanInfo = null;
        Object tmpObj = obj;
        int i;
        try {
          beanInfo = Introspector.getBeanInfo(obj.getClass());      Method getMethod, setMethod;
          String value;
          String propertyType;
          MethodDescriptor[] methods = beanInfo.getMethodDescriptors();
          PropertyDescriptor[] properties = beanInfo.getPropertyDescriptors();
          for (i = 0; i < properties.length; i++) {
            getMethod = properties[i].getReadMethod();
            setMethod = properties[i].getWriteMethod();
            try {
              propertyType = properties[i].getPropertyType().getName();
              value = (String) getMethod.invoke(obj, new Object[0]);
              if ("java.lang.String".equals(propertyType)) {
                value = new String(value.getBytes("GBK"), "ISO8859_1");
                value = new String(value.getBytes("ISO8859_1"), "utf-8");
                setMethod.invoke(obj, new Object[] {value});
              }        }
            catch (Exception ex) {        }
          }
          return obj;
        }
        catch (IntrospectionException e) {
          e.printStackTrace();
          return tmpObj;
        }
        finally {
          beanInfo = null;
          tmpObj = null;
        }
      }
      

  6.   

    不过最终经测试,还是以utf-8方式比较稳妥。因为转码有些中文全角符号会变成?号