更改java web项目编码的过程记录

最近在java web项目开发过程中遇到了很多非常让人头痛的问题。其中一个就是项目编码更换问题。此篇文章记录了整个项目编码码更换的过程。

本来在项目使用的UTF-8编码,一切是如此的完美,但由于种种原因,项目最终不得不使用GBK编码,各种问题就接踵而至。在项目已开发了大部分的情况需要改变编码(UTF-8转到GBK),更改编码是件不得不慎重的事情,稍有不甚就造成大量的乱码,不仅会引起大家的不满,还会拖延项目的时间。

做这次转码需要考虑和做以下几个事情:

  • 目录和文件的结构
  • 哪些文件本身需要转码
  • 哪些文件内容需要转码
  • 转码之后会代码级乱码问题如何解决
把整个项目的文件结构了解一遍,做过java web项目的同学都知道,一般在项目中的核心文件是src下的java文件,jsp文件,还在一些配置文件。这些文件一般有良好的目录来规划。所以确定了需要转码的文件不是一件费力的事情。

1.改变文件本身的编码

需要编码的文件有很多,不可能手工的去更改每个文件的编码,即使可以能手工去更改,但作为程序员,应该学会让电脑来帮我们去处理这类事情。快速处理文件的工具很多,如Python,Perl等。这里我选择了Python。这里主要是我之前了解过Python 的语法,对Python有那一点熟悉。在只了解语法的情况下来使用Python解决实际问题,这就需要google的帮助了。

基本框架的编写。通过思考之后,自己需要去编写一个文件转码工具,工具的作用就是进入目录后循环遍历目录和子目录,获取文件并转换文件的编码。程序流程如下: “初化化目录-->对文件转码-->继续进入子目录-->对文件转码-->....”。 这是一个循环遍历目录和查找文件的过程。分析之后,程序的算法和结构就基本定下了。现在就根据思路来搭工具的架子。

    import os
    
    #循环遍历目录,对目录中的文件进行转码
    def file_u2g(path):
        for f in os.listdir(path):
    
            #获取文件的磁盘地址
            pathname = os.path.join(path, f)
                        
            #如果为目录,则进入子目录继续遍历
            if os.path.isdir(pathname):
                file_u2g(pathname)
    
            #如果为文件,则对文件进行转码处理
            elif os.path.isfile(pathname):
                #转码过程....
               
    

转码程序的编写。现在要需转码的核心代码了。转码的代码流程如:获取文件内容(UTF-8)-->预存内容-->重新写入文件(GBK)。三个步骤就完成转码。 如何读写文件,查了下Python的API文档就立即明了。

    import os
        
    #循环遍历目录,对目录中的文件进行转码
    def file_u2g(path):
        for f in os.listdir(path):
    
            #获取文件的文件路径
            pathname = os.path.join(path, f)
                        
            #如果为目录,则进入子目录继续遍历
            if os.path.isdir(pathname):
                file_u2g(pathname)
    
            #如果为文件,则对文件进行转码处理
            elif os.path.isfile(pathname):
                #获取文件内容并预存,UTF-8
                content = open(pathname, 'r', -1, 'utf-8').read()
                
                #向文件写内容,GBK
                open(pathname, 'w', -1, 'gbk').write(content)
    

备份程序的编写。上面代码并不完善,转码之后,原始文件将不会存在。为了安全起见,需要对原始文件进行备份。备份过程很简单,只需对原始文件重命名即可。

    import os
        
    #循环遍历目录,对目录中的文件进行转码
    def file_u2g(path):
        for f in os.listdir(path):
    
            #获取文件的文件路径
            pathname = os.path.join(path, f)
                        
            #如果为目录,则进入子目录继续遍历
            if os.path.isdir(pathname):
                file_u2g(pathname)
    
            #如果为文件,则对文件进行转码处理
            elif os.path.isfile(pathname):
                #获取原始文件内容并预存,UTF-8
                content = open(pathname, 'r', -1, 'utf-8').read()
                
                #备份,重命名原始文件
                os.rename(pathname, pathname + "_old")
                
                #向文件(使用原始文件名)写内容,GBK
                open(pathname, 'w', -1, 'gbk').write(content)
    

异常处理的编写。为了防止代码因出现异常终止而无法完成其它文件的转码,则需要处理异常,并以友好的方式显示文件转码是成功还是失败。对不需要转码的文件进行过滤处理。

    import os
        
    #循环遍历目录,对目录中的文件进行转码
    def file_u2g(path, prefix=''):
        for f in os.listdir(path):
            
            #对.svn目录过滤
            if f.startswith("."):
                continue
    
            #获取文件的文件路径
            pathname = os.path.join(path, f)
                        
            #如果为目录,则进入子目录继续遍历
            if os.path.isdir(pathname):
                print(prefix + "+" + f)
            
                file_u2g(pathname, prefix + '    ')
    
            #如果为文件,则对文件进行转码处理
            elif os.path.isfile(pathname):
            
                #对备份文件过滤
                if f.endswith("_old"):
                    continue
            
                try:
                    #获取原始文件内容并预存,UTF-8
                    content = open(pathname, 'r', -1, 'utf-8').read()
                    
                    #备份,重命名原始文件
                    if os.path.exists(pathname + "_old"):
                        os.remove(pathname + "_old")
                    
                    os.rename(pathname, pathname + "_old")
                    
                    #向文件(使用原始文件名)写内容,GBK
                    open(pathname, 'w', -1, 'gbk').write(content)
                except Exception as e:
                    
                    print(prefix + "-" + f + "-----------------------failure")
                    print(prefix + e)
                    
                else:
                    print(prefix + "-" + f + "-----------------------success")
                
    

2.改变文件内容的编码

内容转码,即是将内容中有UTF-8的字样都转换成GBK,对文件内容转码的同时也对文件本身进行转码。有了上面转码的程序的产生,编写内容编码就不在是一件什么困难的事了。 代码如下:

    
    import os

    #utf-8 to gbk
    def content_u2g(path, prefix=''):
    
    for f in os.listdir(path):
        pathname = os.path.join(path, f)
     
        if f.startswith("."):
            continue
                    
        if os.path.isdir(pathname):
            print(prefix + '+' + f)
            content_u2g(pathname, prefix + '    ')

        elif os.path.isfile(pathname):
            if f.endswith("_old"):
                continue

            #只针对JSP页面进行编码
            if not f.endswith(".jsp"):
                continue
            
            try:
                content = open(pathname, 'r', -1, 'utf-8').read()
                
                if os.path.exists(pathname + "_old"):
                    os.remove(pathname + "_old")

                os.rename(pathname, pathname + "_old")
                
                #对内容进行转码
                open(pathname, 'w', -1, 'gbk').write(content.replace("UTF-8", "GBK").replace("utf-8", "gbk"))
                
            except Exception as e:
                print(prefix + '-' + f + "--------failure")
                print(prefix + e)
            else:
                print(prefix + '-' + f + "--------success")
                
    

3.处理代码级的乱码问题

在Java web编程中,乱码一直是一个的问题。解决乱码的一个最有效和最直接的方法就是所有的编码进行统一,如果再出现乱码,就进行个别分析的处理。 Java文件和JSP页面已都转成了GBK编码,剩下统一编码的工作就是对tomcat,filter设置统一编码。

在tomcat中只需在server.xml配置文件,加入URIEncoding="GBK"即可,如下:

        
        <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="GBK"/>
    

编写过滤字符集的filter。 在doGet或doPost方法中设置编码,代码如下:

        request.setCharacterEncoding("gbk");
        response.setCharacterEncoding("gbk");
    

jquery ajax中产生的乱码问题非常让人头痛,因为系统对get和post两种提交方式编码处理方式不同。 jquery对post之后的内容进行了UTF-8编码,在后台java中需要进行UTF-8的解码才能获取中文问题。所在在后台java中单纯统一地设置为GBK是无法解决这种乱码问题。 所以我们需在在过滤器中识别哪些是ajax post提交的请求,对这种请求设置UTF-8编码。其它请求设置GBK编码。

由于时间不足问题,这里我先只提出解决方案,暂时不写思考过程,待以后完善。

  • 修改jquery源代码: 找到jquery处理post代码地方,设置一个post标识请求头,以便在java能够识别。 这里使用的是jquery-1.6.2的版本
                    ajaxSettings: {
                		url: ajaxLocation,
                		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
                		global: true,
                		type: "GET",
                		encoding: "UTF-8",
                		contentType: "application/x-www-form-urlencoded;",
                		processData: true,
                		async: true,
                	....
                	
                	
                    // Set the correct header, if data is being sent
            	if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
            		
            		jqXHR.setRequestHeader("Request-Type", "post");
            		jqXHR.setRequestHeader( "Content-Type", s.contentType + (s.encoding ? "; charset=" + s.encoding : ""));
            		
            	}
            		
                
  • 修改filter代码:
                    String requestType = request.getHeader("request-type");
            	if (requestType != null || "post".equals(requestType)) {
            		request.setCharacterEncoding("utf-8");
            	} else {
            		request.setCharacterEncoding("gbk");
            	}
                

好了,大功告成。对于js文件和css文件等其它文件的转码,只需要参考1与2两点就能很好的解决。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值