ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HttpServletResponse写入的中文在浏览器乱码

2021-05-24 18:01:41  阅读:171  来源: 互联网

标签:UTF 码表 HttpServletResponse 乱码 import 浏览器 servlet response


Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表响应的response对象。request和response对象既然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。

package com.yyz.response;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServlet;
//输出中文的问题
public class ResponseDemo extends HttpServlet {
    /**
     *     out.write(data.getBytes());这句代码涉及两次查阅码表。
     *    "中国"从字符数据变成字节数据的时候,会查阅gb2312码表。
     *    数据发送到浏览器端要显示的时候,需要再次查阅码表,这时查阅的码表与浏览器的设置有关。
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String data = "中国";
        OutputStream out = response.getOutputStream();
        out.write(data.getBytes());
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

浏览器编码设置为GB2312时的测试结果:

浏览器编码设置为UTF-8时的测试结果:

为了让我们的网站能被国外用户访问,我们在将字符数据变成字节数据时,要指定转换的码表为UTF-8。但这时如果浏览器以GB2312打开,又会出现乱码问题。虽然可以通过改变浏览器的设置来解决这个乱码问题,但不利于增强用户体验。因而我们需要用程序告诉浏览器查阅何种码表显示数据。

package com.yyz.response;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//输出中文的问题
public class ResponseDemo extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //在服务器端,数据是以哪个码表输出的,那么就要控制浏览器以哪个码表打开。
        String data = "中国";
        response.setHeader("content-type", "text/html;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        out.write(data.getBytes("UTF-8"));
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

多学一招:

使用HTML语言里面的标签来控制浏览器行为。

http-equiv模拟了HTTP的响应头,告诉浏览器以UTF-8的码表打开。真正的响应头优先于用http-equiv模拟的响应头。 实际开发中,服务器向浏览器写文本数据应该用字符流。但是通过response的getWriter方法拿到的字符流默认的码表是ISO8859-1,这张码表里是没有中文对应的编码的,因而会把?对应的编码发送给浏览器,浏览器打开后全是问号。通过response的setCharacterEncoding可以修改服务端发送数据时查阅的码表。 复制代码代码如下:
package com.yyz.response;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//输出中文的问题
public class ResponseDemo extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //在服务器端,数据是以哪个码表输出的,那么就要控制浏览器以哪个码表打开。
        String data = "中国";
        response.setHeader("content-type", "text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.write(data);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
 }

这里有几个小细节需要注意:

  1. response.setCharacterEncoding("UTF-8");需要写在PrintWriter out = response.getWriter();的前面。拿到字符流后再设置编码是没有用的。
  2. response.setHeader("content-type", "text/html;charset=UTF-8");有一种更为简单的写法response.setContentType("text/html;charset=UTF-8");。
  3. response.setContentType("text/html;charset=UTF-8");这句代码其实有两个作用:通知response以UTF-8输出和浏览器以UTF-8打开。即等价于response.setHeader("content-type", "text/html;charset=UTF-8");和response.setCharacterEncoding("UTF-8");两句代码。
  4. 通过以上阅读,读者应该能明白为什么response.getOutputStream.write(1);这句代码在浏览器的输出不是1。因为浏览器是一个文本编辑器,收到数据后会拿着1去查码表,然后显示对应字符。想在浏览器输出数字,应该把数字变成字符串,response.getOutputStream.write((1+"").getBytes());

用OutputStream(字节流)发送数据:

  1. response.getOutputStream().write(“中国”.getBytes()); //以默认编码发送数据
  2. response.getOutputStream().write("中国".getBytes("UTF-8")); //以UTF-8编码发送数据,浏览器(默认用GB2312)会出现乱码

解决办法:

1. 通过更改浏览器的编码方式:IE/”查看”/”编码”/”UTF-8”(不可取);
2. 通过设置响应头告知客户端编码方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);//告知浏览器数据类型及编码;
3. 通过meta标签模拟请求头:out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />".getBytes());
4. 通过以下方法:response.setContentType("text/html;charset=UTF-8");

标签:UTF,码表,HttpServletResponse,乱码,import,浏览器,servlet,response
来源: https://www.cnblogs.com/catelina/p/14805543.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有