Tomcatサーバの下で文字化けしを解決するソリューション


プロジェクトの中で1つの情況に出会って、Tomcatの下で中国語が文字化けしている問題で、最初に解決する時フィルターを使って%tomcat%confserverを修正します.GetとPostの両方に対応するようにxml方式でフォームをコミットしても文字化けが発生しないが、システムで使用するワークフローエンジンなどのプラットフォームについてはURIEncoding="GB 2312"をserverに組み込む.xmlのConnector構成では動作しません.サーバーの構成を変更しないほうがいいようで、カスタムフィルタではPostリクエストとGetリクエストを別々に処理し、Postリクエストであればrequestを直接呼び出します.setCharacterEncoding(「GBK」)では、GetリクエストであればRequestをパッケージして文字化けしの問題を解決する必要があります.
カスタムフィルタの完全なソースコードは次のとおりです.
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.lang.StringUtils;
/**
 *          Tomcat   Get Post                
 * @author leisure
 */
public class TomcatCharsetEncodingFilter implements Filter{
	private String charsetEncoding="GBK";
	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response, 
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest httpRequest=(HttpServletRequest)request;
		String method=httpRequest.getMethod();
		if("POST".equalsIgnoreCase(method)){
			httpRequest.setCharacterEncoding(charsetEncoding);
		}else{
			httpRequest=new CharsetEncodingFixedRequest(httpRequest);
		}
		chain.doFilter(httpRequest, response);
	}

	public void init(FilterConfig config) throws ServletException {
		String charset=config.getInitParameter("charsetEncoding");
		if(StringUtils.isNotBlank(charset)){
			this.charsetEncoding=charset;
		}
	}
	class CharsetEncodingFixedRequest extends HttpServletRequestWrapper{
		private String fixedCharset="iso8859-1";
		private Map paramMap=new HashMap();
		public CharsetEncodingFixedRequest(HttpServletRequest request) {
			super(request);
			try {
				super.setCharacterEncoding(fixedCharset);
				Enumeration nameEnum=request.getParameterNames();
				while(nameEnum.hasMoreElements()){
					String paramName=(String)nameEnum.nextElement();
					String[] values=request.getParameterValues(paramName);
					if(values.length>0){
						List valueList=new ArrayList();
						for(int i=0;i<values.length;i++){
							String value=values[i];
							valueList.add(encode(request.getCharacterEncoding(),value));
						}
						paramMap.put(paramName, valueList.toArray(new String[valueList.size()]));
					}
				}
				System.out.println();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		
		public String getParameter(String name) {
			String[] values=getParameterValues(name);
			if(values!=null && values.length>0) return values[0];
			else return null;
		}
		
		public String[] getParameterValues(String name) {
			return (String[])paramMap.get(name);
		}
		
		public Map getParameterMap() {
			return this.paramMap;
		}

		public Enumeration getParameterNames() {
			final Iterator it=paramMap.keySet().iterator();
			return new Enumeration(){
				public boolean hasMoreElements() {
					return it.hasNext();
				}

				public Object nextElement() {
					return it.next();
				}
			};
		}

		//
		private String encode(String oldCharset,String src){
			if(StringUtils.isBlank(src)) return src;
			if(StringUtils.isBlank(oldCharset)){
				oldCharset=this.fixedCharset;
			}
			try {
				return new String(src.getBytes(oldCharset),charsetEncoding);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				return src;
			}
		}
	}
}

ここで、カスタム要求パッケージクラスにおいて、要求パラメータがキャッシュ処理される.すなわち、getParameter(String paramName)および要求パラメータに関連する他の呼び出しはパッケージの要求を呼び出さない.これは主に,カスタムリクエストパッケージクラスCharsetEncodingFixedRequestがリクエストパラメータに関連する符号化作業を全権で担当できることを根本的に保証するためである.そうでなければ、要求を転送する必要がある場合(典型的にはstrutsのActionクラスでmapping.findForward(String forwardName))に転送するターゲットコンポーネントは、要求パラメータを取得する際に依然として文字化けしてしまいます.これは、主にtomcatが転送を処理する際に要求を再包装し、解包装する必要があることと関係があります.この過程に特別な興味があればorgを見てもいいです.apache.catalina.core.ApplicationDispatcherのソースコードは、その奥義がわかります.
サーバのプロファイルを変更する方法よりも、プロファイルフィルタの方が柔軟で、一部のURLをフィルタして一部をフィルタしないように制御ことができますが、%tomcat%confserverを変更する場合は.xmlの場合、tomcatはすべてのリクエストに対して文字セットの符号化を指定します.これは場合によっては非常に有害です.ISO 8859-1は国際的な基準です.