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:
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:
<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-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。