javaweb项目中遇到的一些乱码问题

来源:互联网 发布:mac充电器插头怎么拆开 编辑:程序博客网 时间:2024/05/14 20:37

在做javaweb项目时,我们经常会遇到一些乱码问题:


首先,确定一点思想:要想不乱码,你要保证编码一致就行了,即统一编码~


其一,jsp等页面中的中文显示乱码(这里不只是说jsp文件,其它文件也有这种情况)

这时你要注意2点,一是你这个jsp文件是不是用utf-8编写的,在所有的编写工具中你都能进行设置的,比如在EditPlus中,




或者在myeclipse中,都能设置的,MyEclipse编码设置

另外,你还要在jsp头部添加这个(有的形式可能不一样,但意思一样就行了),



其二,服务器响应乱码

服务器发送给客户端数据!响应是由response对象来完成,response是响应对象,向客户端输出响应正文(响应体)可以使用response的响应流,repsonse一共提供了两个响应流对象,

PrintWriter out = response.getWriter():获取字符流;

ServletOutputStream out = response.getOutputStream():获取字节流;

当然,如果响应正文内容为字符,那么使用response.getWriter(),如果响应内容是字节,例如下载时,那么可以使用response.getOutputStream()。注意,在一个请求中,不能同时使用这两个流!也就是说,要么你使用repsonse.getWriter(),要么使用response.getOutputStream(),但不能同时使用这两个流。不然会抛出IllegalStateException异常。

如果响应的数据不是字符数据,那么就无需去考虑编码问题。当然,如果响应的数据是字符数据,那么就一定要考虑编码的问题了。

response.getWriter().print(“博客”);

上面代码因为没有设置repsonse.getWriter()字符流的编码,所以服务器使用默认的编码(ISO-8859-1)来处理,因为ISO-8859-1不支持中文,所以一定会出现乱码的。
所以在使用response.getWriter()发送数据之前,一定要设置response.getWriter()的编码,这需要使用response.setCharacterEncoding()方法:

response.setCharacterEncoding(“utf-8”);

response.getWriter().print(“博客”);

上面代码因为在使用response.getWriter()输出之前已经设置了编码,所以输出的数据为utf-8编码。但是,因为没有告诉浏览器使用什么编码来读取响应数据,所以很可能浏览器会出现错误的解读,那么还是会出现乱码的。

当然,通常浏览器都支持来设置当前页面的编码,如果用户在看到编码时,去设置浏览器的编码,如果设置的正确那么乱码就会消失。


在静态页面中,使用<meta>来设置content-type响应头,例如:
<meta http-equiv="content-type" content="text/html; charset=UTF-8">

但是我们不能让用户总去自己设置编码,而且应该直接通知浏览器,服务器发送过来的数据是什么编码,这样浏览器就直接使用服务器告诉他的编码来解读!这需要使用content-type响应头。

response.setContentType(“text/html;charset=utf-8”);

response.getWriter().print(“博客”);

上面代码使用setContentType()方法设置了响应头content-type编码为utf-8,这不只是在响应中添加了响应头,还等于调用了一次response.setCharacterEncoding(“utf-8”),也就是说,通过我们只需要调用一次response.setContentType(“text/html;charset=utf-8”)即可,而无需再去调用response.setCharacterEncoding(“utf-8”)了。


其三,请求编码乱码

页面的编码就是页面中输入数据的编码。


当客户端通过POST请求发送数据给服务器时,可以在使用request.getParameter()获取请求参数之前先通过request.setCharacterEncoding()来指定编码,然后再使用reuqest.getParameter()方法来获取请求参数,那么就是用指定的编码来读取了。
也就是说,如果是POST请求,服务器可以指定编码!但如果没有指定编码,那么默认还是使用ISO-8859-1来解读。

request.setCharacterEncoding(“utf-8”);

String name = request.getParameter(“name”);


当客户端通过GET请求发送数据给服务器时,使用request.getParameter()获取的数据是被服务器误认为ISO-8859-1编码的,也就是说客户端发送过来的数据无论是UTF-8还是GBK,服务器都认为是ISO-8859-1,问题本质是get方式传递的参数内容默认编码方式问ISO8859-1,而且使用request.setCharacterEncoding("utf-8")也无法解决问题,要解决这个问题我用过3种办法;

(1)我们需要在使用request.getParameter()获取数据后,再转发成正确的编码。例如客户端以UTF-8发送的数据,使用如下转码方式:

String name = request.getParameter(“name”);

name = new String(name.getBytes(“iso-8859-1”), “utf-8”);

这种是什么时候遇到乱码再解决(解码),但不推荐,每次都要弄,麻烦;

(2)在web.xml总配置filter,filter自己写,

web.xml中:

<filter><filter-name>EncodingFilter</filter-name><filter-class>xx.xx.xx.EncodingFilter</filter-class></filter><filter-mapping><filter-name>EncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

filter相关类:

//EncodingFilter类:

import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;public class EncodingFilter implements Filter {private String charset = "UTF-8";@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;if(req.getMethod().equalsIgnoreCase("GET")) {if(!(req instanceof GetRequest)) {req = new GetRequest(req, charset);//处理get请求编码}} else {req.setCharacterEncoding(charset);//处理post请求编码}chain.doFilter(req, response);}@Overridepublic void init(FilterConfig fConfig) throws ServletException {String charset = fConfig.getInitParameter("charset");if(charset != null && !charset.isEmpty()) {this.charset = charset;}}}
//GetRequest类:
import java.io.UnsupportedEncodingException;import java.util.Enumeration;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;/** * 对GET请求参数加以处理! * @author qdmmy6 * */public class GetRequest extends HttpServletRequestWrapper {private HttpServletRequest request;private String charset;public GetRequest(HttpServletRequest request, String charset) {super(request);this.request = request;this.charset = charset;}@Overridepublic String getParameter(String name) {// 获取参数String value = request.getParameter(name);if(value == null) return null;//如果为null,直接返回nulltry {// 对参数进行编码处理后返回return new String(value.getBytes("ISO-8859-1"), charset);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}}@SuppressWarnings({ "unchecked", "rawtypes" })@Overridepublic Map getParameterMap() {Map<String,String[]> map = request.getParameterMap();if(map == null) return map;// 遍历map,对每个值进行编码处理for(String key : map.keySet()) {String[] values = map.get(key);for(int i = 0; i < values.length; i++) {try {values[i] = new String(values[i].getBytes("ISO-8859-1"), charset);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}}}// 处理后返回return map;}@Overridepublic String[] getParameterValues(String name) {String[] values = super.getParameterValues(name);for(int i = 0; i < values.length; i++) {try {values[i] = new String(values[i].getBytes("ISO-8859-1"), charset);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);}}return values;}}
(3)改变tomcat的编码

在conf/server.xml中,将

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

改为

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


其四,url编码

这里需要注意的问题是,

通过页面传输数据给服务器时,如果包含了一些特殊字符是无法发送的。这时就需要先把要发送的数据转换成URL编码格式,再发送给服务器。
其实需要我们自己动手给数据转换成URL编码的只有GET超链接,因为表单发送数据会默认使用URL编码,也就是说,不用我们自己来编码。
因为URL默认只支持ISO-8859-1,这说明在URL中出现中文和一些特殊字符可能无法发送到服务器。所以我们需要对包含中文或特殊字符的URL进行URL编码。
服务器会自动识别数据是否使用了URL编码,如果使用了服务器会自动把数据解码,无需我们自己动手解码。


还是那句话吧,编码这个问题是挺复杂的,很多地方都容易出错,做个项目不能保证一开始就都对,但出错之后要能及时改正,一条线中,看看2端的编码是否一致,或者起点和终点的编码是否对应,一一排查,很容易就能找到问题所在~

也要多在网上看看解决办法,有可能一下就懂了~

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被螃蟹扎了肿了怎么办 手指被海鲜刺了怎么办 被海鲜刺进去了怎么办 手被海鲜扎了怎么办 环评设备写错了怎么办 物业对高空抛物怎么办 如果法官不公平判案我该怎么办? 民事案夸省审理案件不公平怎么办 积目头像未通过审核怎么办 电压不稳空调带不动怎么办 孩子吃了塑料珠怎么办 美的电压力锅打不开盖子怎么办 瓶盖打不开怎么办 瓶子是玻璃的 杯子口关错位了怎么办 大玻璃瓶的玻璃瓶盖拧不开怎么办 按压式洗发水瓶盖打不开怎么办 向下按压的瓶盖打不开怎么办 玻璃罐头开过了打不开怎么办 玻璃瓶的塑料盖子打不开怎么办 泡酒玻璃瓶盖子打不开怎么办 罐头的塑料瓶盖打不开怎么办 塑料水杯盖紧了怎么办 拧不开矿泉水瓶盖怎么办 新暖壶盖吸住了怎么办 暖瓶盖被吸住了怎么办 做面包和面粘手怎么办 面包面和稀了怎么办 鱼缸氧气泵声音大怎么办 中班安全遇到火灾怎么办反思 汤洒了怎么办活动反思 下水道被塑料盖堵了怎么办 卫生间地漏盖子掉到下水道怎么办 洗手池下水道翻盖打不开了怎么办 培乐多彩泥吃了怎么办 超轻橡皮泥干了怎么办 脑梗脾气大怎么办好啊 牙齿喝饮料烂了怎么办 大门牙缝里黑了怎么办 椰汁拧不开瓶盖怎么办 装蜂蜜的玻璃罐打不开怎么办 蚂蚱没有草吃了怎么办