原文地址:http://dev2dev.bea.com.cn/techdoc/200311546.html
由于近来论坛中经常碰到中文问题的咨询,所以在下在百忙之中赶出这篇文章,希望能给大家一点指引.如有纰漏,请及时指正!
Web应用中的中文问题
1. 静态页面中文信息不能正确显示
浏览器端看到中文不能正确显示,首先应该检查浏览器是否支持中文,浏览器的编码是否设置正确.为保证静态页面中文信息正确显示可以在HTML <HEAD> 部分增加:
<meta http-equiv="Content-Type" content="text/html" charset="GBK">
2. JSP里的中文提示信息不能正确显示
JSP里的中文提示信息不能正常显示,最直接的原因是WebLogic的默认字符集不是中文字符集(Weblogic8.1里是setlocal,Weblogic7.0sp3,sp4为UTF-8),因此可以在JSP页面中设置字符集,加入如下脚本:
<%@ page contentType="text/html; charset=GBK" %>
这种做法需要对每个JSP页面进行设置,下面的做法针对所有的jsp页面进行设置,比较通用.
3. JSP文件中的提示信息不能正确编译
JSP文件中的提示信息正确编译,可以在weblogic.xml里设置如下脚本,同时也可以解决上面说的第二个问题:
<jsp-descriptor>
<jsp-param>
<param-name>compileCommand</param-name>
<param-value>javac</param-value>
</jsp-param>
<jsp-param>
<param-name>compilerSupportsEncoding</param-name>
<param-value>true</param-value>
</jsp-param>
<jsp-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</jsp-param>
</jsp-descriptor>
4. JSP文件之间不能正确传递中文数据
JSP文件之间不能正确传递中文数据,可以有两种方法解决.
其一:在web.xml里加上如下脚本:
<context-param>
<param-name>weblogic.httpd.inputCharset./*</param-name>
<param-value>GBK</param-value>
</context-param>
其二:在weblogic.xml里加上如下脚本:
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>GBK</java-charset-name>
</input-charset>
</charset-params>
当然这种问题也可以自己用java.net.URLEncoder和java.net.URLDecoder来处理中文.
以上都没有涉及到数据库操作,所以当出现乱码时,逐一分析,
必能找到问题所在.另外可能还需要修改WebLogic应用服务器所在操作系统的字符集,确保支持中文.
文件名和目录中的中文问题
如果你的文件名或者目录是中文怎么办呢?上面提到的方法不能解决你的问题了.这时需要使用java.net.URLEncoder编码.举个例子,在test.jsp里,你需要提供一个超链接到 ./测试/测试.jsp,你可以这么写:
<p><a href="<%=java.net.URLEncoder.encode("./测试/测试.jsp")%>">go</p>
JDBC中的中文问题
如果以上的方法还不能解决你的乱码问题,那么可能是JDBC操作中的失误.这里以Oracle9I为例来说明jdbc中的中文问题.首先查询数据库:
select * from v$nls_parameters where parameter='NLS_CHARACTERSET';
得到数据库的字符集,如果ZHS16GBK,则JDBC的操作不需要转码;如果是us7ascii,则需要转码或者作相关配置.下面以使用不同的数据库驱动程序为例来介绍.
1. 使用Thin Driver
如果使用Thin Driver,那么需要在查询数据库的时候将字符集由ISO转换为GBK,写入数据库的时候将字符集由GBK转换为ISO.
举个例子:
插入一条记录:
Connection conn=null;
PreparedStatement pstmt = null;
try {
String strSql="insert into tabA(A,B) values('1111','王超')";
conn=ds.getConnection();
strSql = new String(strSql.getBytes("GBK"), "ISO-8859-1");
pstmt = conn.prepareStatement(strSql);
pstmt.executeUpdate();
}
catch (Exception e) {
//logger.error(e, e);
}
finally {
disconn(conn, pstmt);
}
查询一条记录:
Connection conn=null;
PreparedStatement pstmt = null;
ResultSet rs=null;
try {
String strSql="select B from tabA where A='1111'";
conn=ds.getConnection();
strSql = new String(strSql.getBytes("GBK"), "ISO-8859-1");
pstmt = conn.prepareStatement(strSql);
rs=pstmt.executeQuery();
String strB;
if (rs.next()){
strB=new String(rs.getString(1) .getBytes("ISO-8859-1"), "GBK");
}
catch (Exception e) {
//logger.error(e, e);
}
finally {
disconn(conn, pstmt, rs);
}
这里建议你在属性文件里设置oracle字符集,根据字符集判断
是否转码,以增加应用的移植性.
2.使用OCI Driver
直接使用WebLogic提供的driver,在配置连接池时设置Properties属性:
weblogic.codeset=GBK,如下图所示:
当你采用了上面的两个方法还不能解决你的乱码时,你检查一下是否仅仅是孤僻字不能正常显示呢?这种情况你需要使用oracle的字符集包: nls_charset12.zip,将该包加入到WebLogic classpath中.
加密中的中文问题
对于不含中文信息的加密和解码,我想有很多算法可以实现.但由于中文为两个字符,普通的加密算法在一次加密一次解密之后无法复原.采用BASE64对中文信息进行编码后再加密可以轻松解决这个问题.当然解密之后同样需要用BASE64解码.示例如下:
String pw="中文";
System.out.println(pw);
pw=new sun.misc.BASE64Encoder().encode(pw.getBytes());
System.out.println(pw);
//加密
String pw1=encode(pw);
System.out.println(pw1);
//解密
String pw2=decode(pw1);
System.out.println(pw2);
byte[] bt=new sun.misc.BASE64Decoder().decodeBuffer(pw2);
pw2=new String(bt);
System.out.println(pw2);
下面给出一个完整的使用kaiser算法加密的源代码:
package test;
/**
* 加密类
*/
import java.lang.Math;
public class SecurityTest {
interface Constants{
public static final int INT_PRIM_NUMBER = 95;
public static final int INT_RETURN_LOOP = 94;
}
/**
* SysBean constructor comment.
*/
public SecurityTest() {
super();
}
/**
* 解密方法
* @author zhg
* 创建日期 (2002-12-15 10:17:08)
* @param strCode 需解密的字符串
* @return 解密后的字符串
* @version 1.0
*/
public static String decode(String strCode) {
String strOriginal;
int intRnd;
String strRnd;
int intStrLen;
String strDecodeMe = "";
if (strCode.equals(""))
return strDecodeMe;
intStrLen = strCode.length() - 1;
strRnd = strCode.substring(intStrLen / 2, intStrLen / 2 + 1);
intRnd = strRnd.hashCode() - new SecurityTest().startChar();
strCode =
strCode.substring(0, intStrLen / 2)
+ strCode.substring(intStrLen / 2 + 1, intStrLen + 1);
strOriginal =
new SecurityTest().loopCode(
strCode,
Constants.INT_RETURN_LOOP - intRnd);
strDecodeMe = strOriginal;
return strDecodeMe;
}
/**
* 加密方法.随机取得加密的循环次数,使得每次加密所得的秘文会有所不同
* @author zhg
* 创建日期 (2002-12-15 10:17:08)
* @param strOriginal 需加密的字符串
* @return 加密后的字符串
* @version 1.0
*/
public static String encode(String strOriginal) {
String strCode;
int intRnd;
char rnd;
int intStrLen;
String strCodeMe = "";
if (strOriginal.equals(""))
return strCodeMe;
//2 到 93 之间的随即数,即同一原文可能获得93种不同的秘文
intRnd = (int) (Math.random() * (Constants.INT_RETURN_LOOP - 2) + 2);
strCode = new SecurityTest().loopCode(strOriginal, intRnd);
//对随机数作偏移加密
rnd = (char) (intRnd + new SecurityTest().startChar());
intStrLen = strCode.length();
strCodeMe =
strCode.substring(0, intStrLen / 2)
+ rnd
+ strCode.substring(intStrLen / 2, intStrLen);
if (strCodeMe.indexOf("'") >= 0)
return encode(strOriginal);
else
return strCodeMe;
}
//基础的凯撒算法,并对于每一位增加了偏移
private String kaiserCode(String strOriginal) {
int intChar;
String strCode;
int i;
int intStrLen;
int intTmp;
intStrLen = strOriginal.length();
strCode = "";
for (i = 0; i < intStrLen; i++) {
intChar = strOriginal.substring(i, i + 1).hashCode();
intTmp = intChar - this.startChar();
intTmp =
(intTmp * Constants.INT_PRIM_NUMBER + i + 1) % this.maxChar()
+ this.startChar();
strCode = strCode + (char) (intTmp);
}
return strCode;
}
//循环调用凯撒算法一定次数后,可以取得原文
private String loopCode(String strOriginal, int intLoopCount) {
String strCode;
int i;
strCode = strOriginal;
for (i = 0; i < intLoopCount; i++)
strCode = this.kaiserCode(strCode);
return strCode;
}
public static void main(String[] args) throws Exception {
String pw = "中文";
System.out.println(pw);
pw = new sun.misc.BASE64Encoder().encode(pw.getBytes());
System.out.println(pw);
//加密
String pw1 = encode(pw);
System.out.println(pw1);
//解密
String pw2 = decode(pw1);
System.out.println(pw2);
byte[] bt = new sun.misc.BASE64Decoder().decodeBuffer(pw2);
pw2 = new String(bt);
System.out.println(pw2);
}
private int maxChar() {
String str1 = "~";
String str2 = "!";
return str1.hashCode() - str2.hashCode() + 1;
}
private int startChar() {
String str1 = "!";
return str1.hashCode();
}
}
总结
本文列举了WebLogic中经常碰到的一些中文问题的解决方法.希望读者能够灵活运用.需要提醒的是GBK字符集比GB2312的字库大,有些不常用字在GB2312里是没有的.所以请尽量使用GBK字符集.
由于近来论坛中经常碰到中文问题的咨询,所以在下在百忙之中赶出这篇文章,希望能给大家一点指引.如有纰漏,请及时指正!
Web应用中的中文问题
1. 静态页面中文信息不能正确显示
浏览器端看到中文不能正确显示,首先应该检查浏览器是否支持中文,浏览器的编码是否设置正确.为保证静态页面中文信息正确显示可以在HTML <HEAD> 部分增加:
<meta http-equiv="Content-Type" content="text/html" charset="GBK">
2. JSP里的中文提示信息不能正确显示
JSP里的中文提示信息不能正常显示,最直接的原因是WebLogic的默认字符集不是中文字符集(Weblogic8.1里是setlocal,Weblogic7.0sp3,sp4为UTF-8),因此可以在JSP页面中设置字符集,加入如下脚本:
<%@ page contentType="text/html; charset=GBK" %>
这种做法需要对每个JSP页面进行设置,下面的做法针对所有的jsp页面进行设置,比较通用.
3. JSP文件中的提示信息不能正确编译
JSP文件中的提示信息正确编译,可以在weblogic.xml里设置如下脚本,同时也可以解决上面说的第二个问题:
<jsp-descriptor>
<jsp-param>
<param-name>compileCommand</param-name>
<param-value>javac</param-value>
</jsp-param>
<jsp-param>
<param-name>compilerSupportsEncoding</param-name>
<param-value>true</param-value>
</jsp-param>
<jsp-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</jsp-param>
</jsp-descriptor>
4. JSP文件之间不能正确传递中文数据
JSP文件之间不能正确传递中文数据,可以有两种方法解决.
其一:在web.xml里加上如下脚本:
<context-param>
<param-name>weblogic.httpd.inputCharset./*</param-name>
<param-value>GBK</param-value>
</context-param>
其二:在weblogic.xml里加上如下脚本:
<charset-params>
<input-charset>
<resource-path>/*</resource-path>
<java-charset-name>GBK</java-charset-name>
</input-charset>
</charset-params>
当然这种问题也可以自己用java.net.URLEncoder和java.net.URLDecoder来处理中文.
以上都没有涉及到数据库操作,所以当出现乱码时,逐一分析,
必能找到问题所在.另外可能还需要修改WebLogic应用服务器所在操作系统的字符集,确保支持中文.
文件名和目录中的中文问题
如果你的文件名或者目录是中文怎么办呢?上面提到的方法不能解决你的问题了.这时需要使用java.net.URLEncoder编码.举个例子,在test.jsp里,你需要提供一个超链接到 ./测试/测试.jsp,你可以这么写:
<p><a href="<%=java.net.URLEncoder.encode("./测试/测试.jsp")%>">go</p>
JDBC中的中文问题
如果以上的方法还不能解决你的乱码问题,那么可能是JDBC操作中的失误.这里以Oracle9I为例来说明jdbc中的中文问题.首先查询数据库:
select * from v$nls_parameters where parameter='NLS_CHARACTERSET';
得到数据库的字符集,如果ZHS16GBK,则JDBC的操作不需要转码;如果是us7ascii,则需要转码或者作相关配置.下面以使用不同的数据库驱动程序为例来介绍.
1. 使用Thin Driver
如果使用Thin Driver,那么需要在查询数据库的时候将字符集由ISO转换为GBK,写入数据库的时候将字符集由GBK转换为ISO.
举个例子:
插入一条记录:
Connection conn=null;
PreparedStatement pstmt = null;
try {
String strSql="insert into tabA(A,B) values('1111','王超')";
conn=ds.getConnection();
strSql = new String(strSql.getBytes("GBK"), "ISO-8859-1");
pstmt = conn.prepareStatement(strSql);
pstmt.executeUpdate();
}
catch (Exception e) {
//logger.error(e, e);
}
finally {
disconn(conn, pstmt);
}
查询一条记录:
Connection conn=null;
PreparedStatement pstmt = null;
ResultSet rs=null;
try {
String strSql="select B from tabA where A='1111'";
conn=ds.getConnection();
strSql = new String(strSql.getBytes("GBK"), "ISO-8859-1");
pstmt = conn.prepareStatement(strSql);
rs=pstmt.executeQuery();
String strB;
if (rs.next()){
strB=new String(rs.getString(1) .getBytes("ISO-8859-1"), "GBK");
}
catch (Exception e) {
//logger.error(e, e);
}
finally {
disconn(conn, pstmt, rs);
}
这里建议你在属性文件里设置oracle字符集,根据字符集判断
是否转码,以增加应用的移植性.
2.使用OCI Driver
直接使用WebLogic提供的driver,在配置连接池时设置Properties属性:
weblogic.codeset=GBK,如下图所示:
当你采用了上面的两个方法还不能解决你的乱码时,你检查一下是否仅仅是孤僻字不能正常显示呢?这种情况你需要使用oracle的字符集包: nls_charset12.zip,将该包加入到WebLogic classpath中.
加密中的中文问题
对于不含中文信息的加密和解码,我想有很多算法可以实现.但由于中文为两个字符,普通的加密算法在一次加密一次解密之后无法复原.采用BASE64对中文信息进行编码后再加密可以轻松解决这个问题.当然解密之后同样需要用BASE64解码.示例如下:
String pw="中文";
System.out.println(pw);
pw=new sun.misc.BASE64Encoder().encode(pw.getBytes());
System.out.println(pw);
//加密
String pw1=encode(pw);
System.out.println(pw1);
//解密
String pw2=decode(pw1);
System.out.println(pw2);
byte[] bt=new sun.misc.BASE64Decoder().decodeBuffer(pw2);
pw2=new String(bt);
System.out.println(pw2);
下面给出一个完整的使用kaiser算法加密的源代码:
package test;
/**
* 加密类
*/
import java.lang.Math;
public class SecurityTest {
interface Constants{
public static final int INT_PRIM_NUMBER = 95;
public static final int INT_RETURN_LOOP = 94;
}
/**
* SysBean constructor comment.
*/
public SecurityTest() {
super();
}
/**
* 解密方法
* @author zhg
* 创建日期 (2002-12-15 10:17:08)
* @param strCode 需解密的字符串
* @return 解密后的字符串
* @version 1.0
*/
public static String decode(String strCode) {
String strOriginal;
int intRnd;
String strRnd;
int intStrLen;
String strDecodeMe = "";
if (strCode.equals(""))
return strDecodeMe;
intStrLen = strCode.length() - 1;
strRnd = strCode.substring(intStrLen / 2, intStrLen / 2 + 1);
intRnd = strRnd.hashCode() - new SecurityTest().startChar();
strCode =
strCode.substring(0, intStrLen / 2)
+ strCode.substring(intStrLen / 2 + 1, intStrLen + 1);
strOriginal =
new SecurityTest().loopCode(
strCode,
Constants.INT_RETURN_LOOP - intRnd);
strDecodeMe = strOriginal;
return strDecodeMe;
}
/**
* 加密方法.随机取得加密的循环次数,使得每次加密所得的秘文会有所不同
* @author zhg
* 创建日期 (2002-12-15 10:17:08)
* @param strOriginal 需加密的字符串
* @return 加密后的字符串
* @version 1.0
*/
public static String encode(String strOriginal) {
String strCode;
int intRnd;
char rnd;
int intStrLen;
String strCodeMe = "";
if (strOriginal.equals(""))
return strCodeMe;
//2 到 93 之间的随即数,即同一原文可能获得93种不同的秘文
intRnd = (int) (Math.random() * (Constants.INT_RETURN_LOOP - 2) + 2);
strCode = new SecurityTest().loopCode(strOriginal, intRnd);
//对随机数作偏移加密
rnd = (char) (intRnd + new SecurityTest().startChar());
intStrLen = strCode.length();
strCodeMe =
strCode.substring(0, intStrLen / 2)
+ rnd
+ strCode.substring(intStrLen / 2, intStrLen);
if (strCodeMe.indexOf("'") >= 0)
return encode(strOriginal);
else
return strCodeMe;
}
//基础的凯撒算法,并对于每一位增加了偏移
private String kaiserCode(String strOriginal) {
int intChar;
String strCode;
int i;
int intStrLen;
int intTmp;
intStrLen = strOriginal.length();
strCode = "";
for (i = 0; i < intStrLen; i++) {
intChar = strOriginal.substring(i, i + 1).hashCode();
intTmp = intChar - this.startChar();
intTmp =
(intTmp * Constants.INT_PRIM_NUMBER + i + 1) % this.maxChar()
+ this.startChar();
strCode = strCode + (char) (intTmp);
}
return strCode;
}
//循环调用凯撒算法一定次数后,可以取得原文
private String loopCode(String strOriginal, int intLoopCount) {
String strCode;
int i;
strCode = strOriginal;
for (i = 0; i < intLoopCount; i++)
strCode = this.kaiserCode(strCode);
return strCode;
}
public static void main(String[] args) throws Exception {
String pw = "中文";
System.out.println(pw);
pw = new sun.misc.BASE64Encoder().encode(pw.getBytes());
System.out.println(pw);
//加密
String pw1 = encode(pw);
System.out.println(pw1);
//解密
String pw2 = decode(pw1);
System.out.println(pw2);
byte[] bt = new sun.misc.BASE64Decoder().decodeBuffer(pw2);
pw2 = new String(bt);
System.out.println(pw2);
}
private int maxChar() {
String str1 = "~";
String str2 = "!";
return str1.hashCode() - str2.hashCode() + 1;
}
private int startChar() {
String str1 = "!";
return str1.hashCode();
}
}
总结
本文列举了WebLogic中经常碰到的一些中文问题的解决方法.希望读者能够灵活运用.需要提醒的是GBK字符集比GB2312的字库大,有些不常用字在GB2312里是没有的.所以请尽量使用GBK字符集.
发表评论
-
ant 编译,内存溢出
2010-12-21 19:43 4361当使用Ant编译大量的Java源文件时,会出现java.lan ... -
Tomcat线程池apr和threadPool
2010-10-15 11:47 2744Tomcat是使用最广的Java We ... -
displaytag外部翻页和排序
2009-05-28 22:07 0显然,displaytag标签在进行排序和分页时,默认行为是针 ... -
友好的错误提示页面,我们可以自定义错误页面:
2008-11-13 13:19 5200转载,原地址:http://xuxiangpan888.ite ... -
MSAgent 详细解说(下)
2007-04-22 01:14 1673七、我的菜单 右键点击 ... -
MSAgent 详细解说(上)
2007-04-22 00:46 3255转:http://www.blueidea.com/tech/ ... -
网页内嵌播放器
2007-04-18 12:42 9380原址:http://caoxiaoyong.spaces ... -
中文文件下载失败的前因后果
2007-04-17 09:36 1683问题如下:客户的论坛 ... -
jar命令的简单应用
2007-04-17 09:24 2469环境假设: 1、假设你在硬盘的某个目录下需要创佳jar/war ... -
转:JBoss技术支持文档
2007-03-26 13:09 2068文章来源:http://java.ccidnet.com/ar ... -
转载-在JBoss中配置多个数据库和数据源
2007-03-13 10:02 2167JBoss是一款非常强大的J2EE应用程序服务器,但是这种强 ... -
安全:编写自己的登录与访问控制模块
2007-03-05 17:04 1534http://java.ccidnet.com/art/375 ...
相关推荐
weblogic 8.1 plugin for Eclipse 3.4 weblogic 8.1 plugin for Eclipse 3.4 weblogic 8.1 plugin for Eclipse 3.4
Weblogic8.1使用说明Weblogic8.1使用说明Weblogic8.1使用说明
配置weblogic 8.1
weblogic8.1完整安装包,解压即可安装
weblogic 8.1,9.2,10破解
weblogic8.1版本_1 BEA WebLogic是用于开发、集成、部署和管理大型分布式Web应用、 网络应用和数据库应用的Java应用服务器。 这个版本很难找哦......
Weblogic 8.1安装手册pdf 详细介绍了Weblogic 8.1安装步骤。
很多初学者多不是很了解配置WEBLOGIC的详细要求,此文档是WEBLOGIC8.1详细安装及配置,演示文稿,希望能解决对WEBLOGIC的初步认识。
weblogic8.1配置说明,别人的共享一下,免费的啊,呵呵嗬嗬嗬嗬
weblogic 8.1部署应用程序(图解)
Weblogic 8.1中如何配置JDBC
WebLogic Platform 8.1 whith sp3 WebLogic 8.1
word文档,Weblogic 8.1的安装与配置
weblogic8.1服务器性能参数优化
Weblogic 8.1 +SP2破解版
weblogic 8.1基础知识--安装与设置
weblogic8.1 JNDI ORACLE 配置 部署
这是一个Weblogic8.1的应用部署的应用部署文档,里面详细介绍了部署步骤。图形文字结合说明,有需要的同学可以下载。
WebLogic8.1服务器证书安装配置指南.pdf
AIX下运行的weblogic8,weblogic8.1sp5补丁,修复该版本服务无故停止响应的问题