???? 最近的开发中遇到了jquery异步提交表单数据时出现了中文乱码的问题。先说一下开发环境,本地编码格式为GBK(服务器为本机,因此服务器端的编码格式也是GBK了),webwork框架默认编码也是GBK。
??? 第一次出现乱码时,尝试着将webwork的默认编码修改为UTF-8。这样服务器端所接收到的中文字符正常显示,可以确定webwork的参数拦截器在进行参数注入时,客户端所提交的中文数据已经变为乱码,修改webwork的默认编码集显然是不合理的。
?
???? 首先想到的是使用encodeURI()函数在客服端对用户提交的数据项进行编码,服务器端再用URLDecode类解码。但由于客户端所提交的数据项比较多,对每个数据项都进行编解码会产生大量的与业务无关的代码。最终想到了使用webwork中提供的域模型去接收分散的数据类型,这样可以统一在服务器端对domain实体中的每个属性值进行解码。以下是具体的实现:
?
???? 客户端:
$("input[type='text']").each(function(){ $(this).val(encodeURI($(this).val())); }); //表单提交前对每个text控件的value采用encodeURI函数编码 $("#subForm").ajaxSubmit(options); //subForm为要提交的表单的id //表单提交后,立即解码,防止用户看到编码后的数据 $("input[type='text']").each(function(){ $(this).val(decodeURI($(this).val())); });
?
?? 服务器端:
???
import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Type; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import org.apache.commons.beanutils.BeanUtils; /** * @describe: 对javabean中指定类型的属性按照指定的编码集解码 * @author: Nirvana*@version: V1.0 2011-6-20上午10:44:24 create */ public class Decoder<T> { /** * 在指定的Class中获取指定Type的属性名 * @param objClass 指定与对象相关联的Class * @param type 对象的属性类型 * @return */ private List<String> getPropertyNames(Class objClass, Type type) { Field[] fields = objClass.getDeclaredFields(); List<String> propertyNames = new ArrayList<String>(); for (Field f : fields) { if (f.getType().equals(type)) { propertyNames.add(f.getName()); } } return propertyNames; } /** * 按照charset字符解码obj对象中属性类型为指定type的属性值 * @param obj 需解码的javabean * @param charset 解决字符集 * @param type 需解码的属性类型 * @return 返回解码后的javabean */ public T decode(T obj, String charset, Type type) { List<String> propertyNames = getPropertyNames(obj.getClass(), type); for (String name : propertyNames) { try { String str = BeanUtils.getProperty(obj, name); if (str == null) continue; BeanUtils.setProperty(obj, name, URLDecoder .decode(str, charset)); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return obj; } }
??在服务器端构建一个domain对象的Decoder,再调用decode方法对指定类型的属性值进行解码。目前Decoder只支持基本数据类型和String类型数据的解码。
??
?