http://www.lanceyan.com/tech/arch/web_luanma.html记得刚做javaweb开发的时候被这个编码问题搞得晕头转向,经常稀里糊涂的编码正常了一会编码又乱了。那个时候迫于项目进度大多都是知其然不知其所以然。后来有时间就把整个体系搞了个遍,终于摸通了来龙去脉。

在C++的CGI开发时大家喜欢用latin,这个属于字节方式的编码格式,存储mysql节约空间,而C++也是比较容易控制到byte级别的语言。所以经过框架封装基本也问题不大。

在Java语言中,要涉及修改编码问题的地方还真多。一个地方没有设好就会乱码满天飞。大概总结包括以下这几部分:浏览器、服务器、数据库、操作系统。

浏览器:
如果使用模板语言,html需要设置显示的字符集。这个适用于浏览器判断什么编码显示。

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

扩展,浏览器识别编码的顺序:
1.如果HTTP头部申明了charset,则会使用HTTP头部的,
2.让HTTP头部没有设置,则会去解析meta标签的,
3.如果meta也没有的话,浏览器会根据是否设置了auto detect来进行编码识别,
4.否则会使用本地UI的字符编码。

服务器:
对于JSP等动态语言,需要在jsp头部设置编码格式,J2EE服务器解析这个JSP的时候才会把整个页面编码为UTF-8输出,不然就按照系统默认编码格式ISO-8859-1输出了。JSP设置格式如下:

<%@ page language= "java" contentType = "text/html; charset=UTF-8"
      pageEncoding ="UTF-8" %>

大家都知道,JSP对应的就是servlet。servlet的编码对应如下设置:

public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException{
response.setContentType("text/html;charset=utf-8");
}

还有不要漏掉大家常用的spring工具类,编码转换filter,很实用。在你用struts、spring mvc时这个过滤器帮你转换没有设置的编码过滤。如下设置:

       <filter>
             <filter-name> Set Character Encoding</filter-name>
             <filter-class>
                  org.springframework.web.filter.CharacterEncodingFilter
             </filter-class>
             <init-param>
                   <param-name> encoding</param-name>
                   <param-value> UTF-8</param-value>
             </init-param>
       </filter>

万一还有乱码怎么办呢?doGet方式的参数传递肯定会有乱码问题。只需要在tomcat的监听器里设置编码字符集如下(文件一般存储在 /tomcat安装目录/conf/server.xml ):

<Connector port="80" protocol="HTTP/1.1" 
              connectionTimeout="20000" 
              redirectPort="8443" URIEncoding="utf-8"   />

大家在开发的时候别忘了java文件本身也是有编码格式的。在类文件右键查看属性。

如果开发时忘记更改文件的编码格式,windows默认是GBK的,后来又要一直到utf8编码的linux怎么办。文件巨多,总不能一个一个去更改吧。其实很简单,只需要在java命令的环境参数设置 -Dfile.encoding=GBK 解决。

编译java代码时,如果使用ant需要在javac里设置编译的字符集。这样打印的log输出到文件或者控制台上就不会乱码了。

<javac debuglevel= "source,lines" source= "1.6"   encoding= "utf-8">

maven编译时设置的字符集:

 < artifactId> maven-compiler-plugin </artifactId >
       < version> 2.5 </version >
                        
         < configuration>
           < optimize> true </optimize >
           < showDeprecation> false </showDeprecation >
           < debuglevel> lines,source </debuglevel >
            < source> 1.6 </source >
            < target> 1.6 </target >
            < encoding> UTF-8 </encoding >
            < meminitial> 128m </meminitial >  
             < maxmem> 768m </maxmem >
                        
         </ configuration>

sqlmap的sql xml,sping的xml 也是需要设置的,因为涉及到跨平台。 顶上添加:

<!--?xml version="1.0" encoding="UTF-8"?-->

数据库:
这里列出大家用的最多的Mysql字符集设置。打开mysql的配置文件( linux 一般在 /etc/my.cnf ,windows在mysql的安装目录 my.ini)。设置如下:

[mysqld]
default-character-set = utf8

[ mysql]
character_set_server = utf8

jdbc需要设置
jdbc : mysql://192.168.0.237:3306/dzh_db?useUnicode=true&characterEncoding=UTF-8

这些都设置了一般的中文是不会有问题的。

不过最近出现了一个问题很搞怪。以前以为所有的字符只要设置好了所有数据都可以录入数据库,结果有些字符就不行,比如●■★这类型的。后来把这些字符变成字节码,居然不是三位utf8的,我擦,大汗淋漓。后来查询可以通过过滤utf8 特殊字符的方式处理。

public static String Utf2String (byte buf[]) {
int len = buf.length ;
StringBuffer sb = new StringBuffer(len / 2);
for (int i = 0; i &lt; len; i++) {

if (by2int(buf[i]) &lt;= 0x7F)
sb.append(( char ) buf[i]);
else if (by2int(buf[i]) &lt;= 0xDF &amp;&amp; by2int(buf[i]) &gt;= 0xC0) {
int bh = by2int(buf[i] &amp; 0x1F);
int bl = by2int(buf[++i] &amp; 0x3F);

bl = by2int(bh &lt;&lt; 6 | bl); bh = by2int(bh &gt;&gt; 2);
int c = bh &lt;&lt; 8 | bl;
sb.append(( char ) c);
} else if (by2int(buf[i]) &lt;= 0xEF &amp;&amp; by2int(buf[i]) &gt;= 0xE0) {
int bh = by2int(buf[i] &amp; 0x0F);
int bl = by2int(buf[++i] &amp; 0x3F);
int bll = by2int(buf[++i] &amp; 0x3F);

bh = by2int(bh &lt;&lt; 4 | bl &gt;&gt; 2);
bl = by2int(bl &lt;&lt; 6 | bll);

int c = bh &lt;&lt; 8 | bl;
// 空格转换为半角
if (c == 58865) {
c = 32;
}
sb.append(( char ) c);

}
}
return sb.toString();
}

或者把mysql的字符集改为 utf8mb4 ,记得这个只有mysql55支持哦!

[mysqld]
default-character-set =utf8mb4

[ mysql]
character_set_server = utf8mb4

操作系统:
windows默认是gbk,一般不需要变动。不过大家又想每个文件都要建立为utf8格式怎么办,不可能我们每个文件建立后都去用属性改变一下?太麻烦!直接在eclipse设置后,同种类型的文件建立都会是utf8格式。

linux,可以有两个地方修改基本就足够了:
vi /etc/sysconfig/i18n
修改

LANG="zh_CN.GB3212"
LANGUAGE="zh_CN.GB18030:zh_CN.GB2312:zh_CN"
SUPPORTED="zh_CN.GB18030:zh_CN:zh:en_US.UTF-8:en_US:en"

vi /etc/profile

export LC_ALL="zh_CN.GB2312"
export LANG="zh_CN.GB2312"

原创文章,转载请注明: 转载自LANCEYAN.COM

谈谈WEB开发中的苦大难字符集问题的更多相关文章

  1. [译]如何在Web开发中使用Python

    [译]如何在Web开发中使用Python 原文:HOWTO Use Python in the Web 摘要 这篇文档展示了Python如何融入到web中.它介绍了几种Python结合web服务器的方 ...

  2. Web开发中的18个关键性错误

    前几年,我有机会能参与一些有趣的项目,并且独立完成开发.升级.重构以及新功能的开发等工作. 本文总结了一些PHP程序员在Web开发中经常 忽略的关键错误,尤其是在处理中大型的项目上问题更为突出.典型的 ...

  3. 【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

    提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OS ...

  4. WEB开发中的字符集和编码

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  5. 今日推荐:10款在 Web 开发中很有用的占位图片服务

    设计网站时,将要使用的图像在一开始通常还不存在,这个时候布局是最重要的.然而,图像的尺寸通常是预先设置,实用一些占位图像可以帮助我们更好地预览和分析布局. 如今,有免费的占位图片自动生成工具可以使用, ...

  6. Web 开发中应用 HTML5 技术的10个实例教程

    HTML5 作为下一代网站开发技术,无论你是一个 Web 开发人员或者想探索新的平台的游戏开发者,都值得去研究.借助尖端功能,技术和 API,HTML5 允许你创建响应性.创新性.互动性以及令人惊叹的 ...

  7. Redis在WEB开发中的应用与实践

    Redis在WEB开发中的应用与实践 一.Redis概述: Redis是一个功能强大.性能高效的开源数据结构服务器,Redis最典型的应用是NoSQL.但事实上Redis除了作为NoSQL数据库使用之 ...

  8. 人们对Python在企业级开发中的10大误解

    From : 人们对Python在企业级开发中的10大误解 在PayPal的编程文化中存在着大量的语言多元化.除了长期流行的C++和Java,越来越多的团队选择JavaScript和Scala,Bra ...

  9. (转)Web开发中最致命的小错误

    Web开发中最致命的小错误 现在,有越来越多所谓的“教程”来帮助我们提高网站的易用性.本文收集了一些在 Web 开发中容易出错和被忽略的小问题,并且提供了参考的解决方案,以便于帮助 Web 开发者更好 ...

随机推荐

  1. Windows基础-使用XAudio2播放音频(本质是WASAPI)

    对于常见的音频播放,使用XAudio2足够了. 时间是把杀猪刀,滑稽的是我成了猪 早在Windows Vista中,M$推出了新的音频架构UAA,其中的CoreAudio接替了DSound.WaveX ...

  2. linux硬盘分区表为gpt

    由于mbr最大支持2T不够用,给5T的新硬盘弄成GPT的 yum install -y parted#指定硬盘parted /dev/#p 查看分区#rm 1p 删除指定分区#改成gptmklabel ...

  3. Android studio配置使debug签名和release签名一致

    在module的build.gradle中添加 android { //重要部分 signingConfigs { release { keyAlias 'jxt' keyPassword '1234 ...

  4. 你不知道的 JavaScript 基础细节

    语法部分 type 属性: 默认的 type 就是 javascript, 所以不必显式指定 type 为 javascript javascript 不强制在每个语句结尾加 “:” , javasc ...

  5. Python与数据结构[1] -> 栈/Stack[0] -> 链表栈与数组栈的 Python 实现

    栈 / Stack 目录 链表栈 数组栈 栈是一种基本的线性数据结构(先入后出FILO),在 C 语言中有链表和数组两种实现方式,下面用 Python 对这两种栈进行实现. 1 链表栈 链表栈是以单链 ...

  6. JSK 11: 移除数组中的重复元素

    题目描述 给定一个升序排列的数组,去掉重复的数,并输出新的数组的长度. 例如:数组 $A = \{1, 1, 2\}$,你的程序应该输出 $2$ 即新数组的长度,新数组为 $\{1, 2\}$. 要求 ...

  7. 洛谷 P4538 收集邮票

    题目描述 有n种不同的邮票,皮皮想收集所有种类的邮票.唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n.但是由于凡凡也很喜欢邮票,所 ...

  8. [CF526G]Spiders Evil Plan

    题目大意: 给出一个$n(n\leq 10^5)$个结点的带边权的树,$q(q\leq 10^5)$个询问,每次询问用$y$条路径覆盖整棵树且覆盖$x$至少一次,最多能覆盖的道路长度是多少? 强制在线 ...

  9. [COCI2015]TRAKTOR

    题目大意: 一个$X\times Y(X,Y\leq10^5)$的格子中,每秒钟依次$n(n\leq10^6)$个蘑菇, 告诉你每个蘑菇出现的时间和位置,问何时第一次出现$k(2\leq k\leq ...

  10. Thread.Join(int millisecondsTimeout)

    Join 就是加入的意思,也就是说新创建的线程加入到进程中,并马上执行. 看下面这段代码 Console.WriteLine("start"); Thread myTask = n ...