到 Google 资讯主页   
EasyJF首页   资料   源码   软件    论坛   网站    
   使用帮助    
    该信息为本站MyRSS系统缓存内容,部分图片及附件有可能无法正常使用.easyjf.comwww.javaresearch.org无关,不对该信息负责.通过http://www.javaresearch.org/article//showarticle.jsp?column=106&thread=48007访问该信息的原始内容.
页面功能  【加入收藏】 【推荐给朋友】 【字体:  】 【关闭】   
Web应用中的中文问题
作者:dongzc 来源:www.javaresearch.org  发布时间:2006-03-19 12:45:14.533


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

/** 
* 解密方法 
* zhg 
* 创建日期 (2002-12-15 10:17:08) 
* strCode 需解密的字符串 
* 解密后的字符串 
* 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; 

/** 
* 加密方法.随机取得加密的循环次数,使得每次加密所得的秘文会有所不同 
* zhg 
* 创建日期 (2002-12-15 10:17:08) 
* strOriginal 需加密的字符串 
* 加密后的字符串 
* 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字符集.

 
相关文章
 
页面功能  【加入收藏】 【推荐给朋友】 【字体:  】 【关闭】   


EasyJF.com 2006 隐私政策 使用EasyJF前必读