JSP中文参数传至JavaBean出现乱码

来源:互联网 发布:r语言数据按组距分组 编辑:程序博客网 时间:2024/06/05 14:23

        JSP中文参数传至JavaBean出现乱码

[关键字]:Tomcat,GBK,GB2312,Filter,乱码,JSP,charset,Servlet


[摘要]:书上说的都能看懂,但是真正做起来却会遇到问题。解决这些问题的过程,就是上机练习的意义。以前遇到的乱码问题要么通过request.setCharacterEnconding("GB2312")解决了,要么就是new String(str.getBytes("ISO-8859-1") , "GB2312")。但是这回是JavaBean出问题了。上面的两句行不通了,只能通过设置Filter来解决。希望遇到类似问题的朋友,站在我们的肩膀上,能看的更远。

 

[正文]:

写了一个简单的JavaBean,用于计算加减乘除。
    CalculateBean.java:

    package ch6.calcbean;
    import java.io.*;

    public class CalculateBean{
        private int operandFirst;//操作数1
        private char operator;//运算符
        private int operandSecond;//操作数2
        private double result;//运算结果

        public int getOperandFirst(){
            return this.operandFirst;
        }
        public void setOperandFirst(int op){
            this.operandFirst = op;
        }

        public char getOperator(){
            return operator;
        }
        public void setOperator(char operator){
            this.operator = operator;
        }

        public int getOperandSecond(){
            return this.operandSecond;
        }
        public void setOperandSecond(int op){
            this.operandSecond = op;
        }

        public double getResult(){
            return this.result;
        }
        public void setResult(double result){
            this.result = result;
        }

        public void calculate(){
            double temp;
            switch(operator){
                case '+':
                    temp = getOperandFirst() + getOperandSecond();
                    break;
                case '-':
                    temp = getOperandFirst() - getOperandSecond();
                    break;
                case '×':
                    temp = getOperandFirst() * getOperandSecond();
                    break;
                case '÷':
                    temp = 1.0 * getOperandFirst() / getOperandSecond();
                    break;
                default:
                    temp = 0;
            }

            setResult(temp);
        }
    }


    由Calculate.jsp调用CalculateBean完成计算:
    Calculate.jsp:

    <%@page contentType="text/html;charset=GB2312" pageEncoding="GB2312"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=gb2312">
    </head>
    </body>
    <form method="post" action="Calculate.jsp">
        <input type="hidden" name="action" value="TRUE"/><!-- 表示是否提交 -->
        第一个操作数:
        <input type="text" name="operandFirst" />
        运算符:
        <select name = "operator" >
            <option value="+">+
            <option value="-">-
            <option value="×">×
            <option value="÷">÷
        </select>
        第二个操作数:
        <input type="text" name="operandSecond" />
        <input type="submit" value="提交"/>
    </form>

    <%if(request.getParameter("action")!=null){ %>    

        <jsp:useBean id="calcu" class="ch6.calcbean.CalculateBean" scope="request"/>
        <jsp:setProperty name="calcu" property="*"/>
        <%    calcu.calculate(); %>
        <jsp:getProperty name="calcu" property="operandFirst"/>
        <jsp:getProperty name="calcu" property="operator"/>
        <jsp:getProperty name="calcu" property="operandSecond"/>
        =<jsp:getProperty name="calcu" property="result"/>

    <%}%>

    </body>
    </html>



    为了完成JavaBean的调用,需将编译生成的CalculateBean.class部署到WEB-INF/classes/ch6目录下。然后运行Calculate.jsp即可以看到结果。程序没有什么问题。但是运行结果总是不对,输出的运算结果result总是为0。怀疑<jsp:setProperty name="calcu" property="*"/> 有问题。也怀疑过<%    calcu.calculate();  %> 是否执行到、、、总之,怎么调试也不正确。后来,再仔细看看书,找到了解决办法:"JavaBean部署完成之后,要重启Tomcat"。就这么简单!当然,我没有使用IDE,是手工编译部署的,如果使用IDE,也许就没这问题了。

    一个问题解决了,另一个问题又来了。算加减时,没有问题。算乘除时,JavaBean并不能正确地接收"×"、"÷"。因为"×"、"÷"并不是标准的ASCII字符。在jsp/servlet中直接用request.setCharactorEncoding("gb2312")就可以了。但是这是在JavaBean中,而且用<jsp:setProperty name="calcu" property="*"/>也没办法设置Encoding。这回到网上搜,有人说应该加上<%@page contentType="text/html;charset=GB2312" pageEncoding="GB2312"%>,还有人说用new String(str.getBytes("ISO-8859-1") , "GB2312"),还有server.xml中加上URIEncoding="GB2312"(<Connector ......   port="8080" redirectPort="8443" URIEncoding="GB2312" >)。这些都没能解决问题。

    最后,找到了答案。关于乱码,Skytiger讲述的比较清楚。步骤如下(我用的是JDK1.6/Tomcat6.0,所以对Skytiger的讲述稍作修改):
    1、实现一个Filter,设置处理字符集为GB2312。(Tomcat下Tomcat/webapps/examples/WEB-INF/classes/filters有完整的例子,请参考web.xml和SetCharacterEncodingFilter的配置。)
    a、只要把Tomcat/webapps/examples/WEB-INF/classes/filters /SetCharacterEncodingFilter.class文件拷到你的/WEB-INF/classes/filters下,如果没有filters目录,就创建一个。
    b、在你的web.xml里加入如下几行:

    <filter>
        <filter-name>Set Character Encoding</filter-name>
        <filter-class>filters.SetCharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>GB2312</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>Set Character Encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>



    2、打开tomcat的Tomcat/conf/server.xml文件,加入URIEncodeing="GB2312",完整的如下:    
    <Connector port="8080" protocol="HTTP/1.1" 
               maxThreads="150" connectionTimeout="20000" 
               redirectPort="8443" URIEncodeing="GB2312"/>

    3、别忘了重启Tomcat。

    这样改完,再运行就正确了。
    
    致谢:
        多谢Skytiger。但是关于Skytiger的内容,是在archaic的blog上找到的(archaic也遇到了类似的问题),在此一并致谢。

    正文内容到此结束。
    ==============================
    ==============================
    ==============================
    ==============================
    为了方便大家,再附上SetCharacterEncodingFilter.java 和 archaic原文。

    ==============================
    SetCharacterEncodingFilter.java:
    ==============================

    /*
    * Licensed to the Apache Software Foundation (ASF) under one or more
    * contributor license agreements.  See the NOTICE file distributed with
    * this work for additional information regarding copyright ownership.
    * The ASF licenses this file to You under the Apache License, Version 2.0
    * (the "License"); you may not use this file except in compliance with
    * the License.  You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */

    package filters;


    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;


    /**
     * <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: 500674 $ $Date: 2007-01-28 00:15:00 +0100 (dim., 28 janv. 2007) $
     */

    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);

        }
    }




    ==============================
    archaic原文如下:http://archaic.blog.hexun.com/5576058_d.html    
    ==============================

    JSP 页面传中文到javaBean中出现乱码  [原创 2006.09.12 14:51:31] 
    刚接触JSP..乱码让我头疼了好几天.看了好多贴子.,都没搞对..

在JSP页面中

<%@page contentType="text/html;charset=GBK" language="java"%>

在server.xml文件中加入URIEncoding="GBK"

<Connector ......   port="8080" redirectPort="8443" URIEncoding="GBK" >

        在eclips中编辑好的jsp在publish后竟然不能更新到tomcat v5.0 server运行目录下..百思不得其解.我现在只好编辑完后再另存一次..

郁闷了...~!

关于乱码..Skytiger讲述的比较清楚

·jsp中文乱码问题     -|Skytiger 发表于 2006-3-17 15:56:00
 在tomcat5中发现了以前处理tomcat4的方法不能适用于处理直接通过url提交的请求,上网找资料终于发现了最完美的解决办法,不用每个地方都转换了,而且无论get,和post都正常。写了个文档,贴出来希望跟我有同样问题的人不再像我一样痛苦一次:-)

  问题描述:

  1 表单提交的数据,用request.getParameter(“xxx”)返回的字符串为乱码或者??
  2 直接通过url如http://localhost/a.jsp?name=中国,这样的get请求在服务端用request. getParameter(“name”)时返回的是乱码;按tomcat4的做法设置Filter也没有用或者用request.setCharacterEncoding("GBK");也不管用

  原因:

  1 tomcat的j2ee实现对表单提交即post方式提示时处理参数采用缺省的iso-8859-1来处理
  2 tomcat对get方式提交的请求对query-string 处理时采用了和post方法不一样的处理方式。(与tomcat4不一样,所以设置setCharacterEncoding(“gbk”))不起作用。

  解决办法:

  首先所有的jsp文件都加上:

  1 实现一个Filter.设置处理字符集为GBK。(在tomcat的webapps/servlet-examples目录有一个完整的例子。请参考web.xml和SetCharacterEncodingFilter的配置。)

  1)只要把%TOMCAT安装目录%/ webapps/servlets-examples/WEB-INF/classes/filters /SetCharacterEncodingFilter.class文件拷到你的webapp目录/filters下,如果没有filters目录,就创建一个。
  2)在你的web.xml里加入如下几行:

    <filter>
        <filter-name>Set Character Encoding</filter-name>
        <filter-class>filters.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>

  3)完成.

  2 get方式的解决办法

  1) 打开tomcat的server.xml文件,找到区块,加入如下一行:URIEncoding=”GBK”

  完整的应如下:

  <Connector port="80"  maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               enableLookups="false" redirectPort="8443" acceptCount="100"
               debug="0" connectionTimeout="20000"
               disableUploadTimeout="true"
               URIEncoding="GBK"/>

  2)重启tomcat,一切OK。

0 0
原创粉丝点击