DBMNG数据库管理与应用

抓住自己最有兴趣的东西,由浅入深,循序渐进地学……
当前位置:首页 > 服务器配置 > Resin

resin3.1处理utf-8格式的jsp时存在的问题

 以前一直使用resin-3.0.x作为服务器,最近想升级到resin3.1,于是在官网上下载了resin3.1.7a,解压配置一切正常,但把应用重新部署上去的时候就出了问题,以前一直正常的页面,现在却报错:
 
500 Servlet Exception
 
<script type="text/javascript"></script>
[show] /index.jsp:1: contentType 'text/vnd.wap.wml; charset=utf-8' conflicts with
previous value of contentType 'text/html; charset=UTF-8'.  Check the .jsp
and any included .jsp files for conflicts.
1:  <%@page contentType="text/vnd.wap.wml; charset=utf-8"%>
2:  <%@page import="java.util.*"%>
3:  <%!

    根据上面的提示,意思似乎是我在jsp里面第一行设置的contentType是'text/vnd.wap.wml; charset=utf-8,和前面设置的'text/html; charset=UTF-8'不同导致冲突,但这个文件的第一行就是<%@page contentType="text/vnd.wap.wml;charset=utf-8" %>,根本没有设置过'text/html; charset=UTF-8',这个提示真是让人很摸不着头脑。
    后来想到可能是UTF8文件格式的问题,就用UE打开文件,另存了一次,选的是不带BOM的UTF8格式的文件,这次就可以正常显示了。但服务器上那么多文件,不可能一个一个的改,还得想其他的办法解决。在网上找了很久都没有任何头绪,似乎遇到这个问题的人很少。
    最后实在是没办法,只好把源代码下载下来研究一下看了,还真的找出了原因所在。
    因为resin在处理jsp文件的时候,会首先读取前面的几个字节来判断文件的格式,如果第一个字节是0xef、第二个字节是0xbb、第三个字节是0xbf,那么就认为这个文件是UTF8格式,于是就自作主张的把ContentType设置成了text/html; charset=UTF-8,然后在后面的处理过程中,因为jsp程序里面会有设置ContentType的指令,遇到这个指令会发现和之前的text/html; charset=UTF-8不同,因此就抛出了异常。而如果没有BOM格式的UTF8,前面就不会有那三个字节的标识,所以就不会被处理了。
    相关代码:
Java代码  
   case 0xef:  
     if ((ch = stream.read()) != 0xbb) {  
stream.unread();  
stream.unread();  
     }  
     else if ((ch = stream.read()) != 0xbf) {  
throw error(L.l("Expected 0xbf in UTF-8 header.  UTF-8 pages with the initial byte 0xbb expect 0xbf immediately following.  The 0xbb 0xbf sequence is used by some application to suggest UTF-8 encoding without a directive."));  
     }  
     else {  
_parseState.setContentType("text/html; charset=UTF-8");  
_parseState.setPageEncoding("UTF-8");  
stream.setEncoding("UTF-8");  
     }  
     break;  
 
    判断冲突的代码:
  
Java代码  
else if (CONTENT_TYPE.equals(name)) {  
    String oldContentType = _parseState.getContentType();  
      
    if (oldContentType != null && ! value.equals(oldContentType))  
      throw error(L.l("contentType '{0}' conflicts with previous value of contentType '{1}'.  Check the .jsp and any included .jsp files for conflicts.", value, oldContentType));  
      
    _parseState.setContentType(value);  
    String charEncoding = parseCharEncoding(value);  
    if (charEncoding != null)  
parseState.setCharEncoding(charEncoding);  
  }  
 
真不明白为什么resin要这么做呢,如果是web网站可能影响不大,contentType本来就是text/html,但如果是wap或者其他contentType的站点这么“智能”的编码判断方式问题就比较麻烦了。
 
 
附:UTF-8 编码的文件可以分为no BOM 和 BOM两种格式(转载)
何谓BOM? "EF BB BF" 这三个字节就叫BOM,BOM的全称叫做"Byte Order Mard".在utf-8文件中常用BOM来表明这个文件是UTF-8文件,而BOM的本意实在utf16中用来表示高低字节序列的。
在字节流之前有BOM表示采用低字节序列(低字节在前面),而utf8不用考虑字节序列,所以其实有无BOM都可以。


微软的记事本 Word 等只能正确打开含BOM的UTF8文件,然后UltraEdit却恰恰相反,回把BOMutf8文件 误认为ascii编码。


UTF-8的BOM是 EFBBBF,因为UE载入UTF-8文件会转成Utf16,上述的EFBBBF 在Utf16中是FFFE(Unicode-LE的BOM),UltraEdit不认识BOM又加多一個BOM,所以有2个FFFE。
文件就被它破坏了。
本站文章内容,部分来自于互联网,若侵犯了您的权益,请致邮件chuanghui423#sohu.com(请将#换为@)联系,我们会尽快核实后删除。
Copyright © 2006-2023 DBMNG.COM All Rights Reserved. Powered by DEVSOARTECH            豫ICP备11002312号-2

豫公网安备 41010502002439号