jquery非同期コミットフォームの乱符号化解決方法
最近の開発でjqueryがフォームデータを非同期でコミットする際に中国語が文字化けしているという問題が発生した.まず開発環境について言えば,ローカル符号化フォーマットはGBK(サーバはネイティブであるため,サーバ側の符号化フォーマットもGBKである),webworkフレームワークのデフォルト符号化もGBKである.
初めて文字化けしが発生した場合は、webworkのデフォルト符号化をUTF-8に変更してみます.このようにサーバ側が受信した中国語文字が正常に表示されると、webworkのパラメータブロックがパラメータ注入を行う際に、クライアントが提出した中国語データが文字化けしていることが判明し、webworkのデフォルトの符号化セットを修正することは明らかに不合理である.
まず,encodeURI()関数を用いて顧客サービス側でユーザが提出したデータ項目を符号化し,サーバ側でURLDecodeクラスで復号することを考える.しかし、クライアントがコミットするデータ項目が多いため、各データ項目を符号化すると、ビジネスに関係のないコードが大量に生成されます.最終的に,webworkで提供されるドメインモデルを用いて分散したデータ型を受信することが考えられ,domainエンティティ内の各属性値をサーバ側で統一的に復号することができる.以下に具体的な実装を示します.
クライアント:
サーバ側:
サーバ側でdomainオブジェクトのDecoderを構築し、指定したタイプの属性値を復号するためにdecodeメソッドを呼び出します.現在、Decoderは基本データ型とString型データの復号のみをサポートしています.
初めて文字化けしが発生した場合は、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型データの復号のみをサポートしています.