中文乱码问题总结

在这里插入图片描述

以下内容仅供搜索:

思路:
只要出现乱码问题,就要首先要清楚以下两点:
a. 乱码问题大概率是由编码解码方式不同导致的,极少情况是由字体等其他因素导致的
b. 以程序为界限,数据进出程序都可能涉及编码解码。即IO操作一般都涉及编码解码问题,所以无论是哪种IO方式,都要关注编码方式,尤其是涉及中文时。

具体场景示例:

1. 标准IO编解码配置(即从控制台读数据和向控制台写数据)

"-Dfile.encoding=UTF-8" 这个配置可以指定Java虚拟机的默认编码方式,因此它对标准输入、标准输出和标准错误输出都会起作用。对于其他的I/O流,如文件、网络等,需要用其他配置指定编码方式。

配置方式(四种):
	a. 直接在IDEA的安装目录的bin/idea64.exe.vmoptions中添加“-Dfile.encoding=UTF-8”,但这可能只在本地有效且只对普通非web项目有效,对于spring框架等环境,实测会失效。
	
	b. 每次输出时通过以下代码配置
	PrintStream out = new PrintStream(System.out, true, "UTF-8");
	out.println("中文乱码测试");
	
	c. 通过命令行启动项目时,使用 “java -Dfile.encoding=UTF-8 MainClass”,指定标准IO编码方式
	
	d. 在IDEA中,进行如下配置:(只对当前项目有效,这也是最常用的,不存在对所有项目都有效的标准IO流配置)
		i. 打开Run/Debug Configurations界面,一般在执行按钮左侧点击Edit Configuration就可以打开
		ii. 左侧列表中选择需要修改的配置项"
		iii. 右侧找到Environment variables中添加环境变量"JAVA_TOOL_OPTIONS",并将其值设置为"-Dfile.encoding=UTF-8"

2. 文件IO
3. 网络IO
	a. springmvc项目中文乱码
	
	问题背景:
	SpringMVC6.0.6构建的项目中,通过浏览器get和post请求提交数据到服务器,在服务器控制台打印输出接收到的数据并以字符串的形式将数据重新返回给浏览器。
	
	问题:
		§ 浏览器提交的数据中有中文字符,服务器控制台中文乱码;
		§ 重新返回给浏览器回显的中文字符也乱码。
		
	问题分析:
		(1) 第一次编码是在浏览器通过get或post请求提交数据时,
		(2) 第一次解码是在服务器中接收数据的位置,由于我是用SpringMVC框架,所以是用Controller类的方法参数接收数据,
		(3) 第二次编码是把上一步解码后的字面量数据存入String类型的参数(局部变量)中,(由框架完成)。
		因为String底层是Bytes数组,Java中由字面量到Bytes数组,使用Java语言默认的Unicode编码。
		(4) 第二次解码是把局部变量输出到控制台,这个过程属于标准IO,解码方式与项目和运行环境有关,可以为每个项目配置标准IO的字符编码方式,具体参考1. 标准IO编解码配置
		(5) 第三次编码是将局部变量返回给浏览器时
		(6) 第三次解码是浏览器收到数据后进行数据展示时
	
	问题解决:
	上面第一步为get和post请求指定编码方式:
		§ 为get请求指定编码方式:
		地址栏中指定
		http://example.com/path?param1=value1&param2=value2&charset=utf-8
		使用form表单指定get请求的字符编码方式:
		<form method="get" action="/search" accept-charset="UTF-8">
		         <inputtype="text"name="q">
		         <buttontype="submit">Search</button>
		 </form>
		§ 为post请求指定字符编码方式:
		使用form表单提交post请求时设置编码方式:
		<form method="post" action="/submit" accept-charset="UTF-8">
		       <!-- 表单内容 -->
		</form>
	 
	上面第二步和第五步使用同一个配置设置字符编码方式:
		@RequestMapping(value="/getDataByObject", produces="text/plain;charset=UTF-8")
		网上除了这种配置方式还有在web.xml文件中配置过滤器、配置拦截器类等方法,但实测都没用,至少对于返回值是纯字符串类型来讲(使用@ResponseBody注解实现)
		
	上面第六步在这个示例中浏览器会根据响应标头信息中的Content-Type: text/plain;charset=UTF-8推断使用什么解码方式。而响应标头信息中的Content-Type也是由上面第二和第五步的@RequestMapping注解的produces属性配置的。
	如果返回的是一个HTML页面的话,会根据HTML页面的<meta>标签中配置的解码方式进行解码。
	
	注意事项:
	对于重新返回给浏览器显示的字符串中文乱码的问题,网上很多教程都是通过过滤器、拦截器、或者在Controller类的方法参数中获取HttpServletResponse对象设置字符编码,但在返回值为纯字符串时,实测在springMVC6.0.6中都没有用,debug发现当Controller类中的方法执行完后,只会保留对request对象的修改,为response对象设置的字符编码重新变成了“ISO-8859-1”,只有@RequestMapping注解的produces属性是有用的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值