servlet之编码问题

本文详细探讨了Servlet中出现编码问题的原因,包括浏览器发送请求和服务器响应的两个阶段。针对GET和POST请求的不同处理方式,分析了解决中文乱码的关键在于设定正确的字符集。文中提出了解决方案,包括在Servlet中设置请求和响应的编码字符集,以及修改Tomcat配置文件以支持UTF-8编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编码问题分析:
计算机底层通信以二进制0、1作为识别传输数据的,浏览器和服务器的通信过程中就需要编码和解码,而编码、解码需要指定字符集。
为了不出现中文乱码必须指定编码、解码字符集一致。
常见的字符集有:ASCII、 GB2312、GBK、BIG5、Unicode、 UTF-8,字符集说白了就是一套规则,就像是密码本一样。

/**
    ASCII:7位(bits)表示一个字符,共128字符,字符值从0到127,其中32到126是可打印字符。
    拓展ASCII:使用8位(bits)表示一个字符,共256字符。
    GB2312:双字节表示16(bits)
    GBK:GB2312的升级版
    BIG5:使用了双字节储存方法,以两个字节来编码一个字
    Unicode:国家标准码 2个字节
    UTF-8:最多使用3个字节表示一个字符

*/

=======================

浏览器和服务器的通信分为2个过程:
浏览器发送请求报文到服务器
服务器发送响应报文到浏览器

这里写图片描述

=====================

首先来看下浏览器发送请求报文到服务器的情况:
对于浏览器而言,浏览器要做的是将数据传输到服务器,浏览器传输数据时必须进行编码工作,将文本文件编码成二进制文件让计算机网络通信识别。而编码的时候需要指定编码字符集,那么浏览器编码是如何指定的呢,主要在网页指定。

<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>

对于服务器而言,服务器主要做的就是将浏览器传过来的二进制文件解码成文本文件。然而,解码工作并不像浏览器直接在网页指定编码那样简单。服务器针对不同的请求,解码的时候指定解码字符集的时间点是不一样的。
如果post请求,请求参数封装在请求体内,这个时候服务器需要手动在servlet中通过httpservletrequest对象指定解码字符集对浏览器传输过来的二进制文件进行解码。

protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");

    }

如果是get请求,get请求是通过url地址传递参数,服务器的解码工作并不需要在servlet当中手动进行解码,而是通过服务器即tomcat自动解码。而tomcat默认的解码字符集是iso8859-1,该字符集不支持中文,如果要识别浏览器传输过来的二进制文件必须自己修改tomcat配置文件。修改Tomcat的默认字符集,在server.xml配置文件的Connector标签中,添加如下属性 URIEncoding=”utf-8”。

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

============================

服务器发送响应报文到浏览器的过程:
对于服务器而言,需要将文本文件编码成二进制文件然后通过计算机网络通信传输到浏览器,即编码工作。如何指定服务器的编码字符集工作呢,可以在servlet中通过httpserlvetresponse对象指定编码字符集。

protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        response.setCharacterEncoding("utf-8");
    }

对于浏览器而言,需要将服务器传输过来的二进制文件(响应报文)解码成文本文件,即解码工作。所以我们可以手动设置浏览器解码服务器传输过来的二进制文件的解码字符集。但是,前提条件是服务器的编码字符集你得知道,才可以设置浏览器的解码字符集。这样未免也太麻烦了,并且不同的浏览器的默认的解码字符集还是不一样的,为了正确获得响应报文不出现乱码,在不同的浏览器自己都得手动设置。所以出现了这样的一种解决方案,那就是能不能在服务器指定浏览器接收到二进制文件(响应报文)时的解码字符集。答案是可以的。可以在servlet中通过httpserlvetresponse对象指定浏览器解码字符集。

protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        response.setHeader("content-type", "utf-8");
    }

为了保证服务器发送响应数据到浏览器不出现乱码,需要在servlet中加入:

protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");//服务器端指定编码字符集
        response.setHeader("content-type", "utf-8");//服务器端指定浏览器端解码字符集

    }

为了更加简便的书写,可以将这2条语句合成一句。

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

    }

意思是设置浏览器解码接收到服务器传输过来的二进制文件的指定字符集的同时还指定了服务器编码时的字符集。这种也是最终的解决方案。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值