Java编码及网络传输中的编码问题
2023-09-11 14:20:35 时间
1、表单数据的编码
现在的问题是,在网络中,不知道客户端发过来的字节流的编码方案(发送前浏览器会对数据编码!!!各个浏览器还不一样!!!)
解决方案如下:
当然URLEncoder.encode(str, "utf-8")和URLDecoder.decode(strReceive,"utf-8")方法中的编码方案要一致。
2、网址的编码
但以上方法只适合表单数据的提交;对于URL则不行!!!原因是URLEncoder把/也编码了,浏览器发送时报错!!!那么,只要http://IP/子目录把http://IP/这部分原封不动(当然这部分不要有中文),之后的数据以/分割后分段编码即可。
代码如下:
* 对{@link URLEncoder#encode(String, String)}的封装,但不编码/字符,对其他字符分段编码 * @param str * 要编码的URL * @param encoding * 编码格式 * @return 字符串以字符/隔开,对每一段单独编码以encoding编码格式编码 * @version: 2012_01_10 * p * 注意:未考虑:,如直接对http://编解码,会产生错误!!!请在使用前将其分离出来,可以使用 * {@link #encodeURLAfterHost(String, String)}方法解决此问题 * p * 注意:对字符/一起编码,导致URL请求异常!! public static String encodeURL(String str, String encoding) {
sb.append(URLEncoder.encode(str.substring(start, i), encoding)); sb.append(splitter); start = i + 1; } } if (start str.length()) sb.append(URLEncoder.encode(str.substring(start), encoding)); return sb.toString();
* 对{@link URLEncoder#encode(String, String)} * 的封装,但不编码/字符,也不编码网站部分(如ftp://a.b.c.d/部分,检测方法为对三个/字符的检测,且要求前两个连续), * 对其他字符分段编码 * @param str * 要编码的URL * @param encoding * 编码格式 * @return IP地址后字符串以字符/隔开,对每一段单独编码以encoding编码格式编码,其他部分不变 * @version: 2012_01_10 * p * 注意:对字符/一起编码,导致URL请求异常!! public static String encodeURLAfterHost(String str, String encoding) {
if (index str.length() str.charAt(index) == splitter) {//检测第一个/之后是否还是/,如ftp:// index++;//从下一个开始 index = str.indexOf(splitter, index);//第三个/;如ftp://anonymous:tmp@g.cn:219.223.168.20/中的最后一个/ if (index 0) {
+ encodeURL(str.substring(index + 1), encoding);//如ftp://anonymous:tmp@g.cn:219.223.168.20/天空 } else return str;//如ftp://anonymous:tmp@g.cn:219.223.168.20 }
* 对IP地址后的URL通过/分割后进行分段编码. * 此方法与{@link #decodeURLAfterHost(String, String)}配对使用 * @param str * 要解码的URL * @param encoding * str的编码格式 * @return IP地址后字符串以字符/隔开,对每一段单独解码以encoding编码格式解码,其他部分不变 * @version: 2012_01_10 * p * 注意:对字符/一起解码,将导致URL请求异常!! public static String decodeURLAfterHost(String str, String encoding) {
if (index str.length() str.charAt(index) == splitter) {//检测第一个/之后是否还是/,如ftp:// index++;//从下一个开始 index = str.indexOf(splitter, index);//第三个/;如ftp://anonymous:tmp@g.cn:219.223.168.20/中的最后一个/ if (index 0) {
+ decodeURL(str.substring(index + 1), encoding);//如ftp://anonymous:tmp@g.cn:219.223.168.20/天空 } else return str;//如ftp://anonymous:tmp@g.cn:219.223.168.20 }
* p * 对{@link URLDecoder#decode(String, String)}的封装,但不解码/字符,对其他字符分段解码 * @param str * 要解码的URL * @param encoding * str的编码格式 * @return 字符串以字符/隔开,对每一段单独编码以encoding编码格式解码 * @version: 2012_01_10 * p * 注意:对字符/一起编码,导致URL请求异常!! public static String decodeURL(String str, String encoding) {
sb.append(URLDecoder.decode(str.substring(start, i), encoding)); sb.append(splitter); start = i + 1; } } if (start str.length()) sb.append(URLDecoder.decode(str.substring(start), encoding)); return sb.toString();
问题如下:
貌似图中的utf-8改成iso8859-1是可以的,utf-8在字符串中有中文时不行(但英文部分仍可正确解析)!!!毕竟GBK的字节流对于utf-8可能是无效的,碰到无效的字符怎么解析,是否可逆那可不好说啊。
测试代码如下:
// .println("出现中文时,如果编码方案不支持中文,每个字符都会被替换为?的对应编码!(如在iso-8859-1中)"); System.out.println("原始字符串:\t\t\t\t\t\t" + str);
System.out.println("用URLEncoder.encode()方法,并用UTF-8编码后:\t\t" + utf8_encoded);
System.out.println("用URLEncoder.encode()方法,并用GBK编码后:\t\t" + gbk_encoded); testEncoding(str, utf8, gbk); testEncoding(str, gbk, utf8); testEncoding(str, gbk, iso); printBytesInDifferentEncoding(str); printBytesInDifferentEncoding(utf8_encoded); printBytesInDifferentEncoding(gbk_encoded); } /** * 测试用错误的编码方案解码后再编码,是否对原始数据有影响 * * @param str * 输入字符串,Java的String类型即可 * @param encodingTrue * 编码方案1,用于模拟原始数据的编码 * @param encondingMidian * 编码方案2,用于模拟中间的编码方案 * @throws UnsupportedEncodingException */ public static void testEncoding(String str, String encodingTrue,
.printf("%s编码的字节数据- 用%s解码并转为Unicode编码的JavaString- 用%s解码变为字节流- 读入Java(用%s解码)后变为Java的String\n", encodingTrue, encondingMidian, encondingMidian, encodingTrue); System.out.println("原始字符串:\t\t" + str);
System.out.println("中间字符串:\t\t" + encodeUseMedianEncoding + "\t\t//即用" + encondingMidian + "解码原始字节流后的字符串");
System.out.println("解码字符串:\t\t" + restored + "\t\t和原始数据相同? " + restored.endsWith(str)); } /** * 将字符串分别编码为GBK、UTF-8、iso-8859-1的字节流并输出 * * @param str * @throws UnsupportedEncodingException */ public static void printBytesInDifferentEncoding(String str)
System.out.println("可见Unicode在之前加了两个字节FE FF,之后则每个字符两字节"); } /** * 将该数组转的每个byte转为两位的16进制字符,中间用空格隔开 * * @param bytes * 要转换的byte序列 * @return 转换后的字符串 */ public static final String bytesToHexString(byte[] bytes) {
String hex = Integer.toHexString(bytes[i] 0xff);// 0xff是byte小于0时会高位补1,要改回0 if (hex.length() == 1)
谷粒学苑项目实战(十四):实现阿里云视频点播功能(java编码实现) 视频点播(ApsaraVideo for VoD)是集音视频采集、编辑、上传、自动化转码处理、媒体资源管理、分发加速于一体的一站式音视频点播解决方案。
Java中将base64编码字符串转换为图片 前一段时间,在做摄像头拍照上传,摄像头拍的照片为base64编码格式的字符串,需要上传至项目中,则需要使用到将base64编码字符串转换为图片
相关文章
- java安全编码指南之:文件和共享目录的安全性
- java安全编码指南之:基础篇
- Java运算符,关系运算符
- Java RESTful Web Service实战(第2版) 2.7 本章小结
- 【Java】java的内存浅析
- java for语句
- Java 14中对switch的增强,终于可以不写break了
- 《Java编码指南:编写安全可靠程序的75条建议》—— 指南8:防止XPath注入
- 《Java编码指南:编写安全可靠程序的75条建议》—— 指南20:使用安全管理器创建一个安全的沙盒
- 《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.8 运行Java程序
- 《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 2.9 总结
- 《Java编码指南:编写安全可靠程序的75条建议(英文版)》—— 6.4 拼接字符串
- Java IDEA中设置导入import java.xx.*和设置导入具体的import java.xx.yy;
- Java 并发工具包 java.util.concurrent 大全
- Java Design Demo -简单的队列-异步多任务队列(java android)
- java中文乱码解决之道(三)—–编码详情:伟大的创想—Unicode编码
- 10个精妙的Java编码最佳实践
- elasticsearch之JAVA环境变量报错:could not find java; set JAVA_HOME or ensure java is in PATH
- java string,需要进行首字母大写改写
- java安全编码指南之:锁的双重检测
- java安全编码指南之:堆污染Heap pollution
- 深入浅出 Java 8 Lambda 表达式
- Java_并发工具包 java.util.concurrent 用户指南(转)
- Java系列实用网文汇总
- Java并发编程(八)同步容器
- [java][db]JAVA分布式事务原理及应用
- 2013编程之美资格赛之长方形(Java实现)
- 深入分析 Java 中的中文编码问题--转
- 【Java笔记】配置文件java.util.Properties类的使用