阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

解决全站字符乱码

377次阅读
没有评论

共计 3816 个字符,预计需要花费 10 分钟才能阅读完成。

1、解决全站字符乱码(POST 和 GET 中文编码问题)

servlet:

  • POST:request.setCharacterEncoding(“utf-8”);

  • GET:

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

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

2、说明

乱码问题:

获取请求参数中的乱码问题;

​ POST 请求:request.setCharacterEncoding(“utf-8”);

​ GET 请求:new String(request.getParameter(“xxx”).getBytes(“iso-8859-1”),“utf-8”);

响应的乱码问题:response.setContextType(“text/html;charset=utf-8”)。

基本上在每个 Servlet 中都要处理乱码问题,所以应该把这个工作放到过滤器中来完成。

3、分析

其实全站乱码问题的难点就是处理 GET 请求参数的问题。

如果只是处理 POST 请求的编码问题,以及响应编码问题,那么这个过滤器就太!太!太简单的。

public class EncodingFilter extends HttpFilter {public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {String charset = this.getInitParameter("charset"); if(charset == null || charset.isEmpty()) {charset = "UTF-8"; } request.setCharacterEncoding(charset); response.setContentType("text/html;charset=" + charset); chain.doFilter(request, response); } }

如果是 POST 请求,当执行目标 Servlet 时,Servlet 中调用 request.getParameter() 方法时,就会根据 request.setCharacterEncoding() 设置的编码来转码!这说明在过滤器中调用 request.setCharacterEncoding() 方法会影响在目标 Servlet 中的 request.getParameter() 方法的行为!

但是如果是 GET 请求,我们又如何能影响 request.getParameter() 方法的行为呢?这是不好做到的!我们不可能先调用 request.getParameter() 方法获取参数,然后手动转码后,再施加在到 request 中!因为 request 只有 getParameter(),而没有 setParameter() 方法。

处理 GET 请求参数编码问题,需要在 Filter 中放行时,把 request 对象给“调包”了,也就是让目标 Servlet 使用我们“调包”之后的 request 对象。这说明我们需要保证“调包”之后的 request 对象中所有方法都要与“调包”之前一样可以使用,并且 getParameter() 方法还要有能力返回转码之后的参数。

这可能让你想起了“继承”,但是这里不能用继承,而是“装饰者模式(Decorator Pattern)”!

下面是三种对 a 对象进行增强的手段:

l 继承:AA 类继承 a 对象的类型:A 类,然后重写 fun1() 方法,其中重写的 fun1() 方法就是被增强的方法。但是,继承必须要知道 a 对象的真实类型,然后才能去继承。如果我们不知道 a 对象的确切类型,而只知道 a 对象是 IA 接口的实现类对象,那么就无法使用继承来增强 a 对象了;

l 装饰者模式:AA 类去实现 a 对象相同的接口:IA 接口,还需要给 AA 类传递 a 对象,然后在 AA 类中所有的方法实现都是通过代理 a 对象的相同方法完成的,只有 fun1() 方法在代理 a 对象相同方法的前后添加了一些内容,这就是对 fun1() 方法进行了增强;

l 动态代理:动态代理与装饰者模式比较相似,而且是通过反射来完成的。动态代理会在最后一天的基础加强中讲解,这里就不再废话了。

对 request 对象进行增强的条件,刚好符合装饰者模式的特点!因为我们不知道 request 对象的具体类型,但我们知道 request 是 HttpServletRequest 接口的实现类。这说明我们写一个类 EncodingRequest,去实现 HttpServletRequest 接口,然后再把原来的 request 传递给 EncodingRequest 类!在 EncodingRequest 中对 HttpServletRequest 接口中的所有方法的实现都是通过代理原来的 request 对象来完成的,只有对 getParameter() 方法添加了增强代码!

JavaEE 已经给我们提供了一个 HttpServletRequestWrapper 类,它就是 HttpServletRequest 的包装类,但它做任何的增强!你可能会说,写一个装饰类,但不做增强,其目的是什么呢?使用这个装饰类的对象,和使用原有的 request 有什么分别呢?

HttpServletRequestWrapper 类虽然是 HttpServletRequest 的装饰类,但它不是用来直接使用的,而是用来让我们去继承的!当我们想写一个装饰类时,还要对所有不需要增强的方法做一次实现是很心烦的事情,但如果你去继承 HttpServletRequestWrapper 类,那么就只需要重写需要增强的方法即可了。

4、代码

EncodingRequest

public class EncodingRequest extends HttpServletRequestWrapper {private String charset; public EncodingRequest (HttpServletRequest request, String charset) {super(request); this.charset = charset; } public String getParameter (String name) {HttpServletRequest request = (HttpServletRequest) getRequest(); String method = request.getMethod() ; if(method.equalsIgnoreCase("post")) {try {request.setCharacterEncoding(charset); } catch (UnsupportedEncodingException e) {}} else if(method.equalsIgnoreCase("get")) {String value = request.getParameter(name); try {value = new String(name.getBytes("ISO-8859-1"), charset); } catch (UnsupportedEncodingException e) { } return value ; } return request.getParameter(name); } }

EncodingFilter

public class EncodingFilter extends HttpFilter {
	public void doFilter(HttpServletRequest request,
			HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {String charset = this.getInitParameter("charset"); 
		if(charset == null || charset.isEmpty()) {charset = "UTF-8";} 
		response.setCharacterEncoding(charset);
		response.setContentType("text/html;charset=" + charset);
		EncodingRequest res = new EncodingRequest(request, charset); 
		chain.doFilter(res, response); 
	}
}

web.xml

<filter> <filter-name>EncodingFilter</filter-name> <filter-class>cn.itcast.filter.EncodingFilter</filter-class> <init-param> <param-name>charset</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-06-06发表,共计3816字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7985031
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸 前言 作为天天跟架构图、拓扑图死磕的...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...
开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

  开源 MoneyPrinterTurbo 利用 AI 大模型,一键生成高清短视频! 在短视频内容...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定!

星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定!

星哥带你玩飞牛 NAS-9:全能网盘搜索工具 13 种云盘一键搞定! 前言 作为 NAS 玩家,你是否总被这些...
星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的NAS中!

星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的NAS中!

星哥带你玩飞牛 NAS-10:备份微信聊天记录、数据到你的 NAS 中! 大家对「数据安全感」的需求越来越高 ...
星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

  星哥带你玩飞牛 NAS-16:飞牛云 NAS 换桌面,fndesk 图标管理神器上线! 引言 哈...
星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

  星哥带你玩飞牛 NAS-16:不再错过公众号更新,飞牛 NAS 搭建 RSS 对于经常关注多个微...
小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比

小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比

小白也能看懂:什么是云服务器?腾讯云 vs 阿里云对比 星哥玩云,带你从小白到上云高手。今天咱们就来聊聊——什...