Web请求和响应的编码问题总结

1. Post获取请求参数导致乱码

案例:提交中文数据,通过servlet回显在浏览器上

结果

在这里插入图片描述

在这里插入图片描述

前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h3>中文回显</h3>
    <form action="demo4" method="post">
        请输入中文:<input type="text" name="chinese"/><br/>
        <input type="submit"  value="提交">
    </form>
</body>
</html>

servlet

package com.zmysna.demo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/demo4")
public class Demo04Show extends HttpServlet{

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //不对request的数据进行编码的情况下获取post提交的汉字
        String value = request.getParameter("chinese");
        PrintWriter writer = response.getWriter();
        //回显到浏览器上
        writer.print(value);
    }
}

分析:post提交时,请求参数放在请求体中,Tomcat对于请求体中的数据,默认的编码是ISO-8859-1欧洲编码,不支持汉字,所以汉字会有乱码的问题。地址栏上使用的是UTF-8编码。因为我们提交数据使用的是UTF-8的编码,而Tomcat服务器使用的是ISO-8859-1编码,所以会出现乱码的问题。

在这里插入图片描述

解决方法:在servlet中添加一行代码request.setCharacterEncoding("utf-8");使页面编码和服务器对请求体使用的编码一致。

2. 打印输出流乱码问题

回显案例添加request.setCharacterEncoding("utf-8")解决post提交请求体乱码问题之后,回显数据依然出现乱码。

代码如下

package com.zmysna.demo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/demo4")
public class Demo04Show extends HttpServlet{

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

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //对request的数据进行编码的情况下获取post提交的汉字
        String value = request.getParameter("chinese");

        //在控制台上打印
        System.out.println(value);

        //回显到浏览器上
        PrintWriter writer = response.getWriter();
        writer.print(value);
    }
}

结果

在这里插入图片描述

分析:打印汉字,输出的是乱码。为什么会有乱码?因为 Tomcat 打印流默认编码是 ISO-8859-1 编码,不支持汉字。设置响应的编码为 UTF-8。指定打印流的编码为 utf-8。

解决方法:添加以下两行代码任意一行。

  1. response.setCharacterEncoding("utf-8");设置打印流的编码

  2. response.setContentType("text/html;charset=utf-8");设置响应类型,打印流和响应的编码。

推荐第二种。

3. 下载中文名文件乱码问题

案例:实现中文名附件下载

效果:

在这里插入图片描述

未编码的情况

package com.zmysna.servlet;

import org.apache.commons.io.IOUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

@WebServlet(urlPatterns = "/downLoad")
public class DownLoadServlet extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //设置字符集
    response.setContentType("image/jpg;charset=utf-8");
    //用输入流读取WEB目录下的一张图片
    ServletContext application = getServletContext();
    InputStream in = application.getResourceAsStream("WEB-INF/e7e49ed2b25a6e9f (1).jpg");
    
	//设置附件形式下载图片资源
    response.setHeader("Content-Disposition", "attachment;filename=" + "苹果手机.jpg");
    //获取一个字节输出流将图片输出到页面
    ServletOutputStream out = response.getOutputStream();
    //IO流工具进行资源的传输(需要导入common.io包)
    IOUtils.copy(in,out);
    out.close();
    in.close();
}

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

结果:默认下载文件名不是 苹果手机.jpg

在这里插入图片描述

分析:filename如果是汉字,需要对汉字进行编码,浏览器会自动进行解码。

解决方案:设置响应头时对文件名进行编码。

response.setHeader("Content-Disposition", "attachment;filename="
        + URLEncoder.encode("苹果手机","utf-8")+".jpg");

4. Cookie中使用非法字符需要编码

  • 在 cookie 值中不能使用分号(;)、逗号(,)、等号(=)以及空格,Tomcat8 中可以直接使用汉字。如果需要使用非法字符需要进行编解码。
java.net.URLEncoder.encode(" 字符串","utf-8") 把字符串使用 utf-8 进行编码
java.net.URLDecoder.decode(" 字符串","utf-8") 把字符串使用 utf-8 进行解码

案例:

  1. 得到用户上次访问的时间

  2. 如果用户是第一次访问,则输出:您好,您是第1次访问,欢迎您的加入!并且把这次访问服务器的时间写到Cookie中。

  3. 如果之前已经访问过,则从Cookie中得到上次访问的时间,显示:您好,欢迎您再次访问。您上次访问的时间是:xxxx

时间显示的字符串包含空格,设置为Cookie值时需要编解码。

代码演示

CookieUtils工具类

package com.zmysna.cookie;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

public class CookieUtils {

    public static String getValue(HttpServletRequest request, String visitor) {
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(visitor)) {
                return cookie.getValue();
            }
        }
        return null;
    }
}
package com.zmysna.cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.Date;

@WebServlet("/visit")
public class VisitServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //从Cookie中获取时间字符串,已经编过码,需要解码
        String visitTime = CookieUtils.getValue(request, "visitTime");
        String count = CookieUtils.getValue(request, "count");
        if(count == null) count = "1";
        //获取当前时间的字符串,包含空格,需要编码
        String now = new Timestamp(new Date().getTime()).toString();
        if(value == null) {
            System.out.println("你好,你第一次登录,现在的时间是" + time + "<hr>");
        }else {
            //对获取的时间字符串进行解码
            value = URLDecoder.decode(value, "utf-8");
            System.out.println("你好,你第" + count + "次登录,现在时间是" + time + "<hr>");
            System.out.println("你上一次登录的登录的时间是" + value);
        }
        //对当前时间字符串进行编码
        Cookie visitor = new Cookie("visitTime", URLEncoder.encode(now,"utf-8"));
        Cookie cntCookie = new Cookie("count", (Integer.parseInt(count) + 1) + "");
       	//添加到Cookie中。
        response.addCookie(visitor);
        response.addCookie(cntCookie);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值