终极解决GET方式中文乱码

问题:

 想重定向到错误提示页面, 并带上错误信息, 实现方式是统一的controller异常处理器, 拦截到异常, 获取异常响应类型是Rest(@ResponseBody)还是页面, 若是页面, 则重定向到统一的错误页面, 带上自定义异常的错误信息, 问题来了. 若是中文错误信息, 在异常处理器中拿redirectAttribute好困难啊, 为了实现统一和松耦合, 决定使用get方式, 结果问题更严重的乱码
首先第一步URLEncode.encode中文(页面的话用JS函数也可以编码), 组装url跳转到错误提示Controller, 入参一定是乱码, 正常情况下new String(message.getBytes("ISO8859-1"),"UTF-8")转回来即可, 这取决于Tomcat的默认编码, 也可以改Tomcat编码解决. 

原因:
        但没这么简单, 错误消息为测试, 转码后为%E6%B5%8B%E8%AF%95,   跳转异常action组装的url为: tips/complete?success=false&message=%E6%B5%8B%E8%AF%95
结果action入参为测è¯
        一看就像是转译字符, 找了半天原因是springmvc入参解析器绑定一个转义处理:
	webDataBinder.registerCustomEditor(String.class, new PropertyEditorSupport() {
		@Override
		public void setAsText(String text) {
			setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
		}

		@Override
		public String getAsText() {
			Object value = getValue();
			return value != null ? value.toString() : null;
		}
	});
经过整理大致逻辑为:
		1. String src = "测试";
		2. src = URLEncoder.encode(src);
		3. System.out.println(src); // 转码后变为%E6%B5%8B%E8%AF%95 -> 传到服务器变为 测è¯
		4. src = StringEscapeUtils.escapeHtml4(src);
		5. System.out.println(src); // æµ‹è¯ 变为 æµ‹è¯ 变成这个就不可逆了~~~
第三步传到服务器后乱码可以理解, tomcat使用iso8859编码字符造成的
第四步经过参数解析器绑定的转义处理直接将乱码转义成废屁~~~

解决:
解决想法有了, 在第四步和第三步之间转码, 当然那是不可能的, 受限于框架, 除非你仅仅写个demo, 否则你得花大把时间重写解析器~~~~

想了半天, 能否把%E6%B5%8B%E8%AF%95原样带回, 而不让Tomcat转成测è¯这么个飞机呢~~~
首先想到Tomcat.server.xml, 改吗? 改了不就成小学生了~~

Google了下URLDecoder.encode的原理, 决定两次编码, 看:
		String src = "测试";
		src = URLEncoder.encode(src);
		System.out.println(src); // 第一次变为: %E6%B5%8B%E8%AF%95
		src = URLEncoder.encode(src);
		System.out.println(src); // 第二次变为: %25E6%25B5%258B%25E8%25AF%2595 -> 传到服务器是不变的
		src = StringEscapeUtils.escapeHtml4(src);
		System.out.println(src); // 转义不会改变, 因为没得特殊字符
		src = URLDecoder.decode(src); 
		System.out.println(src); // 第一次解码变为; %E6%B5%8B%E8%AF%95
		src = URLDecoder.decode(src);
		System.out.println(src); // 第二次解码变为: 测试

完美解决~~~

实际web环境, 两次编码后请求, 服务器只需一次解码即可, 原因是tomcat还是按照ISO8859-1将%25E6%25B5%258B%25E8%25AF%2595解码为字符%E6%B5%8B%E8%AF%95, 你拿到%E6%B5%8B%E8%AF%95后在解码一次就是中文了, 所以两次的编码后一次解码你用默认的字符集即可, 不要指定UTF-8














  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值