java中常见的中文乱码总结

所属分类: 软件编程 / java 阅读数: 35
收藏 0 赞 0 分享

1.IO流中读取文件时出现乱码问题

1,先记录从文件中(new File()的时候)读取数据逐级包装直至缓冲字节输入流(new BufferReader())并设置编码格式

//文件路径
String path = "??????????????????";
//读取文件
File file = new File(path);
//包装成文件字节输入流
FileInputStream fis = new FileInputStream(file);
//下边这个流可以理解为从字节流迈向字符流的一个桥梁 
//并且InputStreamReader在创建对象的时候可以传入想要的字符编码的参
//数这里是“utf-8”
InputStreamReader isr = new InputStreamReader(fis,"utf-8");
//再将InputStreamReader包装进BufferReader中
BufferedReader br = new BufferedReader(isr);

2.字节码文件读取时出现的乱码问题

遇到了一个在eclipse使用过程中发生的转码问题 ,安装完eclipse后Project→Properties→Resource中写着默认的编码格式为GBK,我一直没有改成UTF-8,在学习过程中因为一直统一使用GBK编码 所以一直也没有出现问题

在这里插入图片描述

直到有一天我在汤姆猫上运行我学习Servlet中写的代码时发现一个有趣的现象
如果我使用response直接向服务器发送中文内容不会出现乱码

`resp.getWriter().println("<h1>我喜欢吃</h1>");

但是在使用BufferReader的readline()方法读取到中文内容时会出现乱码情况,我试过无论我修改IO流中读取字符的编码格式 还是修改整个项目的编码格式 都不能改变这个乱码问题

BufferedReader br = new BufferedReader(fr);
br.readLine()//下图中“tom!”的那一行

在这里插入图片描述

请教了老师,得到了新的解决办法
在本类中加入一行代码,这句代码的意思是查看VM启动参数,运行后在控制台上就可以看到下图中的信息(只截了部分片段)可以看到有一个属性叫file.encoding它的值是GBK
意思我个人分析可能是我创建项目的时候使用的是GBK编码 然后自己也运行过这个项目 .class的字节码文件已经生成了 这时候如果只在项目右键Properties进去修改编码格式为时已晚

//查看VM启动参数
System.getProperties().list(System.out);

在这里插入图片描述

老师给出了一个临时解决办法,在本类中将要出现乱码的那一行之前加上一行

System.setProperty("file.encoding", "utf-8");

将上文中提到的VM参数中file.encoding的值现改成utf-8
其实最根本的解决办法就是在项目创建之初就设定好编码格式,如果出现像我这样来不及的情况的话可以临时使用这个方法

3.使用Servlet过滤器Filter统一设置整个Servlet项目中的各种编码格式

Servlet提供了三大组件 servlet filer listener
在设置编码格式时 我们就可以预先设定一个全局范围内的过滤器,
创建Filter类 添加注解@WebFilter(eclipse在创建Filter类时会自动创建该注解) 注解的内容我这里直接写了/* ,表示本项目中所有请求都必须先经过这个Filter过滤

@WebFilter("/*")
public class EncodingFilter implements Filter {
    
	public EncodingFilter() {
    
    }

	 @Override
	public void init(FilterConfig fConfig) throws ServletException {
		//当Filter被初始化的时候调用,打印输出
		//Servlet默认是懒加载模式
		System.out.println("encodingfilter is initialized........");
	}
	 @Override
    public void destroy() {
    	//当filter被销毁的时候调用,打印输出
    	System.out.println("encodingfilter is destoryed.......");
    }
	
	//doFilter方法就相当于一个筛子 
	//一共四行代码 分别是我们提出的三个要求,和一条放行代码
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	
		//设置解析报文的编码格式
		request.setCharacterEncoding("utf-8");
		//设置返回响应使用的编码格式
		response.setCharacterEncoding("utf-8");
		//告诉浏览器响应内容是text和html类型的文件 编码格式是utf-8
		response.setContentType("text/html;charset=utf-8");
		
		//放行请求
		//其中包含了请求从哪里来  准备到哪里去的相关信息
		chain.doFilter(request, response);
	}
}

过滤器的功能除了简介的注解形式之外,Servlet中还有一种基于web.xml文件的形式,打开web.xml文件,在根目录下加入以下代码

	<filter>
		<!-- 标签的name -->
		<filter-name>encode</filter-name>
		<!-- 标签的类的位置 -->
		<filter-class>com.zyj.day02.EncodingFilter</filter-class>
	</filter>

	<filter-mapping>
		<!-- 对应得标签的name -->
		<filter-name>encode</filter-name>
		<!-- 声明作用域的范围 -->
		<url-pattern>/*</url-pattern>
	</filter-mapping>

虽然内容比较简单 但写起来也算是比较繁琐 所以建议还是使用注解的形式来实现功能
值得一提的是
通过在filter类的init方法中添加了一句打印语句我们发现,如果你既在类名上标明注解 又在web.xml文件中添加了配置,那么当有请求过来的时候,我们会在控制台上发现init方法执行了两次,虽然目前看来没有什么问题 但总的来说 二者有一个即可。

4,从阿里云服务器上的mysql数据库中读取数据产生的中文乱码

问题描述:
当我在servlet中连接好数据库 打算实现一个写入的功能 一个读取的功能
本来是可以通过sql语句顺利的写入中文,在数据库中查询到中文,还可以读取数据打印在控制台上 整个过程中都没有出现乱码问题 但当我想使用直接从数据库中读取中文 “小张” 作为我项目中登录功能的账号时 发现无法读取到正确的数据 以至于判定我在账号框输入的“小张”不存在 正在初学阶段 大体知道各个流程中的各个编码环境 但还是没有找到是哪个环节的编码格式与众不同

找到了一个解决办法 :
在项目中druid-config.properties(阿里云德鲁伊的配置文件)中的url属性后拼接一个?characterEncoding=utf-8 设置读取mysql数据库中数据的时候的编码格式

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://你的端口号:3306/estore?characterEncoding=utf-8
username=???mysql数据库的账号
password=???mysql数据库的密码
maxActive=30
maxWait=3000

下面在给大家补充介绍:java中常见的中文乱码总结

乱码现象产生的原因:由于编码方式的不同,才会出现乱码的情况。

哪里会产生乱码:1.页面  2.url地址  3.数据库乱码  4.数据提交(form,ajax)  5.开发工具

怎么解决:

1.统一开发工具的编码设置

2.设置应用服务器的编码方式,如:端口号,编码方式

3.数据库本身的编码方式

4.强制设置request和response的数据编码方式(同时也可以采用过滤器的方式拦截所有的编码方式)

5.采用代码方式强转数据编码方式(UrlEncode.encode("你好","utf-8"))

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!

更多精彩内容其他人还在看

Java的面向对象编程基本概念学习笔记整理

这篇文章主要介绍了Java的面向对象编程基本概念学习笔记整理,包括类与方法以及多态等支持面向对象语言中的重要特点,需要的朋友可以参考下
收藏 0 赞 0 分享

Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法

这篇文章主要介绍了Eclipse下编写java程序突然不会自动生成R.java文件和包的解决办法 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

基于Java实现杨辉三角 LeetCode Pascal's Triangle

这篇文章主要介绍了基于Java实现杨辉三角 LeetCode Pascal's Triangle的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Java中Spring获取bean方法小结

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架,如何在程序中获取Spring配置的bean呢?下面通过本文给大家介绍Java中Spring获取bean方法小结,对spring获取bean方法相关知识感兴趣的朋友一起学习吧
收藏 0 赞 0 分享

如何计算Java对象占用了多少空间?

在Java中没有sizeof运算符,所以没办法知道一个对象到底占用了多大的空间,但是在分配对象的时候会有一些基本的规则,我们根据这些规则大致能判断出来对象大小,需要的朋友可以参考下
收藏 0 赞 0 分享

剖析Java中的事件处理与异常处理机制

这篇文章主要介绍了Java中的事件处理与异常处理机制,讲解Java是如何对事件或者异常作出响应以及定义异常的一些方法,需要的朋友可以参考下
收藏 0 赞 0 分享

详解Java的Struts2框架的结构及其数据转移方式

这篇文章主要介绍了详解Java的Struts2框架的结构及其数据转移方式,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

Java封装好的mail包发送电子邮件的类

本文给大家分享了2个java封装好的mail包发送电子邮件的类,并附上使用方法,小伙伴们可以根据自己的需求自由选择。
收藏 0 赞 0 分享

在Java的Struts中判断是否调用AJAX及用拦截器对其优化

这篇文章主要介绍了在Java的Struts中判断是否调用AJAX及用拦截器对其优化的方法,Struts框架是Java的SSH三大web开发框架之一,需要的朋友可以参考下
收藏 0 赞 0 分享

java多线程Future和Callable类示例分享

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。今天我们就来研究下Future和Callab
收藏 0 赞 0 分享
查看更多