Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >解决全站字符乱码

解决全站字符乱码

作者头像
星哥玩云
发布于 2022-09-14 13:19:41
发布于 2022-09-14 13:19:41
34000
代码可运行
举报
文章被收录于专栏:开源部署开源部署
运行总次数:0
代码可运行

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请求的编码问题,以及响应编码问题,那么这个过滤器就太!太!太简单的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  <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>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
LeetCode 0300 - Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence.
Reck Zhang
2021/08/11
2130
leetcode 300. Longest Increasing Subsequence
找到整数数组中最长的递增子数组。该子数组可以为不连续的。如题目中例子所示,[10, 9, 2, 5, 3, 7, 101, 18]得到的最长子数组为[2,3,7,101]。
眯眯眼的猫头鹰
2018/10/31
4300
LeetCode 300. Longest Increasing Subsequence (Tag:Binary Search)
Given an unsorted array of integers, find the length of longest increasing subsequence.
用户7447819
2021/07/23
2800
leetcode-674-Longest Continuous Increasing Subsequence
题目描述: Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). Example 1: Input: [1,3,5,4,7] Output: 3 Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. Even though
chenjx85
2018/05/22
5370
Array - 334. Increasing Triplet Subsequence
Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.
ppxai
2020/09/23
4340
LeetCode 300. Longest Increasing Subsequence (DP)
有O(n^2)效率,还有O(n*logn)效率的。 O(n^2)的效率很好理解的啦,就是大家最常见的那种DP
ShenduCC
2020/06/01
4140
Leetcode 128 Longest Consecutive Sequence
Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example, Given [100, 4, 200, 1, 3, 2], The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should run in
triplebee
2018/01/12
6270
leetcode334. Increasing Triplet Subsequence
假设有一个无序的数组,如果数组中从左到右存在三个由小到大的数字,则返回true。否则返回false。
眯眯眼的猫头鹰
2019/03/13
5080
【DP】300. Longest Increasing Subsequence
Given an unsorted array of integers, find the length of longest increasing subsequence.
echobingo
2019/06/14
5020
LeetCode 0329 - Longest Increasing Path in a Matrix
Given an integer matrix, find the length of the longest increasing path.
Reck Zhang
2021/08/11
1790
76. 最长上升子序列动态规划+二分查找
给定一个整数序列,找到最长上升子序列(LIS),返回LIS的长度。 说明 最长上升子序列的定义: 最长上升子序列问题是在一个无序的给定序列中找到一个尽可能长的由低到高排列的子序列,这种子序列不一定是连续的或者唯一的。 https://en.wikipedia.org/wiki/Longest_increasing_subsequence 样例 给出 [5,4,1,2,3],LIS 是 [1,2,3],返回 3 给出 [4,2,4,5,3,7],LIS 是 [2,4,5,7],返回 4 挑战 要求时间复杂度为O(n^2) 或者 O(nlogn)
和蔼的zhxing
2018/09/04
1.3K0
算法细节系列(7):354. Russian Doll Envelopes
在做这道题之前,我们先来看一道它的简化版本300. Longest Increasing Subsequence,官网给出了两种解法,时间复杂度分别为O(n2)O(n^2)和O(nlogn)O(n \log n).
用户1147447
2019/05/26
6270
Leetcode 300. Longest Increasing Subsequence
**解析:**Version 1,最长递增子序列,典型的动态规划问题,定义状态:以nums[i]作为结尾元素的最长递增子序列的长度,状态转移方程:遍历nums[i]之前的元素nums[j],如果nums[i] > nums[j],则其最长递增子序列的长度为max(dp[i], dp[j] + 1),遍历之后,可以找到以nums[i]作为结尾元素的最长递增子序列长度,最终返回的是所有元素的最长递增子序列长度中最长的一个。Version 2是一种技巧,使用order作为有序序列保持最长递增子序列长度,当新元素比有序序列的最后一个元素大时,此时增加新元素到有序序列中,否则,则将新元素插入到当前序列中,替换比其大或相等的元素,保证左侧元素都比它小,此时长度不变,order中始终保留较小的元素,这样利于插入新元素。order的长度等于最长递增子序列长度,但order的数据不一定等于最长递增子序列的数据。
Tyan
2021/07/29
3800
Leetcode 300. Longest Increasing Subsequence
674. Longest Continuous Increasing Subsequence
LWC 49:674. Longest Continuous Increasing Subsequence Problem: Given an unsorted array of integers, find the length of longest continuous increasing subsequence. Example 1: Input: [1,3,5,4,7] Output: 3 Explanation: The longest continuou
用户1147447
2019/05/26
3840
《剑指offer》第28天:最长上升子序列(高频)
首先我们分析题目,要找的是最长上升子序列(Longest Increasing Subsequence,LIS)。因为题目中没有要求连续,所以 LIS可能是连续的,也可能是非连续的。 同时,LIS符合可以从其子问题的最优解来进行构建的条件。所以我们可以尝试用动态规划来进行求解。首先我们定义状态:
程序员小浩
2020/09/14
4780
LeetCode 0334 - Increasing Triplet Subsequence
Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array.
Reck Zhang
2021/08/11
2860
LWC 49:673. Number of Longest Increasing Subsequence
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77923593
用户1147447
2019/05/26
3730
【leetcode刷题】T165-最长上升子序列
https://leetcode-cn.com/problems/longest-increasing-subsequence/
木又AI帮
2019/09/17
4410
[LeetCode]Longest Continuous Increasing Subsequence 最长连续增长序列 [LeetCode]Longest Continuous Incr
链接:https://leetcode.com/problems/longest-continuous-increasing-subsequence/description/ 难度:Easy 题目:674. Longest Continuous Increasing Subsequence Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray). Example 1:
尾尾部落
2018/09/04
3800
<dp>求最长的公共子串
Given an unsorted array of integers, find the length of longest increasing subsequence.
大学里的混子
2018/11/18
1K0
推荐阅读
相关推荐
LeetCode 0300 - Longest Increasing Subsequence
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验