Tomcat+MySql+Struts中文問題絕妙的解決方案

來源:互聯網
上載者:User

    開發Web應用程式時,無論是用什麼樣的架構技術來開發,一碰從資料庫存取涉及到中文的資料,就要面對中文亂碼或者是各種編碼方式不匹配的異常,今天晚上終於搞定了Tomcat+MySql+Struts的中文問題,用到了很簡單的方法,很快就能搞定。

    在做以下工作之前,所有的HTML/JSP的charset都設為charset=gb2312。

    第一個要解決的是表單提交亂碼問題。在使用Struts提供的ActionForm過程中,無論表單採用的是Struts標籤還是Html標籤,都可以用ActionForm的Get/Set來擷取和設定表單的元素值(它們的作用效果與request.getParameter()方法一樣),但提取出來的資料不經過處理的話就是亂碼,主要的原因是1.Tomcat的J2EE實現對錶單提交即Post方法提交時,處理參數採用預設的ISO8859_1來處理2.Tomcat對Get方法提交的請求在query-string處理時採用了和Post方法不一樣的處理方式。所以如果要正確地顯示和擷取中文資料採用的解決方案:(1)對於Post方法提交的表單通過編寫一個過濾器(filer)的方法解決,過濾器在使用者提交的資料被處理之前被調用,可以通過這個Java代碼改變參數的編碼方式(目標編碼方式可以通過Web.xml檔案裡面的參數指定)。過濾器的代碼如下:

import java.io.IOException;
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.UnavailableException;

/**
 * <p>Example filter that sets the character encoding to be used in parsing the
 * incoming request, either unconditionally or only if the client did not
 * specify a character encoding.  Configuration of this filter is based on
 * the following initialization parameters:</p>
 * <ul>
 * <li><strong>encoding</strong> - The character encoding to be configured
 *     for this request, either conditionally or unconditionally based on
 *     the <code>ignore</code> initialization parameter.  This parameter
 *     is required, so there is no default.</li>
 * <li><strong>ignore</strong> - If set to "true", any character encoding
 *     specified by the client is ignored, and the value returned by the
 *     <code>selectEncoding()</code> method is set.  If set to "false,
 *     <code>selectEncoding()</code> is called <strong>only</strong> if the
 *     client has not already specified an encoding.  By default, this
 *     parameter is set to "true".</li>
 * </ul>
 *
 * <p>Although this filter can be used unchanged, it is also easy to
 * subclass it and make the <code>selectEncoding()</code> method more
 * intelligent about what encoding to choose, based on characteristics of
 * the incoming request (such as the values of the <code>Accept-Language</code>
 * and <code>User-Agent</code> headers, or a value stashed in the current
 * user's session.</p>
 *
 * @author Craig McClanahan
 * @version $Revision: 1.2 $ $Date: 2004/03/18 16:40:33 $
 */

public class SetCharacterEncodingFilter implements Filter {

    // ----------------------------------------------------- Instance Variables

    /**
     * The default character encoding to set for requests that pass through
     * this filter.
     */
    protected String encoding = null;

    /**
     * The filter configuration object we are associated with.  If this value
     * is null, this filter instance is not currently configured.
     */
    protected FilterConfig filterConfig = null;

    /**
     * Should a character encoding specified by the client be ignored?
     */
    protected boolean ignore = true;

    // --------------------------------------------------------- Public Methods

    /**
     * Take this filter out of service.
     */
    public void destroy() {

        this.encoding = null;
        this.filterConfig = null;

    }

    /**
     * Select and set (if specified) the character encoding to be used to
     * interpret request parameters for this request.
     *
     * @param request The servlet request we are processing
     * @param result The servlet response we are creating
     * @param chain The filter chain we are processing
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain)
 throws IOException, ServletException {

        // Conditionally select and set the character encoding to be used
        if (ignore || (request.getCharacterEncoding() == null)) {
            String encoding = selectEncoding(request);
            if (encoding != null)
                request.setCharacterEncoding(encoding);
        }

 // Pass control on to the next filter
        chain.doFilter(request, response);

    }

    /**
     * Place this filter into service.
     *
     * @param filterConfig The filter configuration object
     */
    public void init(FilterConfig filterConfig) throws ServletException {

 this.filterConfig = filterConfig;
        this.encoding = filterConfig.getInitParameter("encoding");
        String value = filterConfig.getInitParameter("ignore");
        if (value == null)
            this.ignore = true;
        else if (value.equalsIgnoreCase("true"))
            this.ignore = true;
        else if (value.equalsIgnoreCase("yes"))
            this.ignore = true;
        else
            this.ignore = false;

    }

    // ------------------------------------------------------ Protected Methods

    /**
     * Select an appropriate character encoding to be used, based on the
     * characteristics of the current request and/or filter initialization
     * parameters.  If no character encoding should be set, return
     * <code>null</code>.
     * <p>
     * The default implementation unconditionally returns the value configured
     * by the <strong>encoding</strong> initialization parameter for this
     * filter.
     *
     * @param request The servlet request we are processing
     */
    protected String selectEncoding(ServletRequest request) {

        return (this.encoding);

    }

}

編繹後把class檔案放在classes目錄下,並在Web應用的web.xml檔案中添加如下代碼:

<filter>
  <filter-name>Set Character Encoding</filter-name>
  <filter-class>com.neusoft.equipment.controller.SetCharacterEncodingFilter</filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>gbk</param-value>
  </init-param>
 </filter>
 <filter-mapping>
  <filter-name>Set Character Encoding</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>只要是gb2312,gbk,utf8等支援多位元組編碼的字元集都可以儲存漢字,當然,gb2312中的漢字數量遠少於gbk,而gb2312,gbk等都可在utf8下編碼,這裡指定目標編碼方式是gbk,重新啟動Tomcat後就可以了。
(2)對Get方法提交的表單,由於參數是緊跟在使用者的URL請求後面,Tomcat對其的處理方法與Post方法不一樣。所以上面設定的過濾器對Get方法沒有作用,它需要在其他地方設定。找到Tomca的server.xml設定檔,找到對80(或者是8080等別的,這個是自己修改後的)的Connector組件的設定部分,給這個Connector組件添加一個屬性:URIEncoding="GBK"。修改後的Connector組件是這樣的:

 <!-- Define a non-SSL HTTP/1.1 Connector on port 80-->
    <Connector port="80" maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               connectionTimeout="20000" disableUploadTimeout="true"  URIEncoding="GBK"/>這樣修改後,重啟Tomcat就可以正確處理GET方法提交的表單資料了。

    第二個要解決的是資料庫存取資料出現的亂碼等情況。對於不同的資料庫往往支援不同的編碼,造成了應用時比較混亂,不同的資料庫的解決方案往往是不同的,針對MySql,網上也有各種各樣的解決方案,但個人覺得那些太繁了,現在有一個極其簡單的解決辦法:修改MySql的設定檔,開啟MySql安裝後的根目錄,找到my.init檔案,把[mysqld]區的如下語句:default-character-set=latin1修改為:default-character-set=gbk,然後在[client]區增加:default-character-set=gbk,修改後記得做一件事情,到Widows控制台的管理工具下的服務程式,把Mysql服務停止了重新啟動,這樣就根本解決了MySql的資料庫亂碼問題,很簡單~~~~

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.