jquery非同期コミットフォームの乱符号化解決方法


最近の開発で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型データの復号のみをサポートしています.