今天在利用URI来创建文件对象的时候出现了异常

说是urI中包含了非法字符,一看发现URI中有一个空格字符

RFC3986文档规定,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符,这些字符被称为未保留字符

以及所有保留字符。

Url中只允许使用可打印字符。US-ASCII码中的10-7F字节全都表示控制字符,这些字符都不能直接出现在Url中。同时,对于80-FF字节(ISO-8859-1),由于已经超出了US-ACII定义的字节范围,因此也不可以放在Url中。

  保留字符

Url可以划分成若干个组件,协议、主机、路径等。有一些字符(:/?#[]@)是用作分隔不同组件的。例如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和查询参数,等等。还有一些字符(!$&'()*+,;=)用于在每个组件中起到分隔作用的,如=用于表示查询参数中的键值对,&符号用于分隔查询多个键值对。当组件中的普通数据包含这些特殊字符时,需要对其进行编码。

RFC3986中指定了以下字符为保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ]

  不安全字符

还有一些字符,当他们直接放在Url中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符,原因有很多。

  • 空格:Url在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Url的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉。
  • 引号以及<>:引号和尖括号通常用于在普通文本中起到分隔Url的作用
  • #:通常用于表示书签或者锚点
  • %:百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码
  • {}|\^[]`~:某一些网关或者传输代理会篡改这些字符

那么我们就知道了,因为URI中有非法字符,为了避免引起歧义,要进行转义才可以,然后我就想当然的请出了URLEncoder,然后发现,错的严重了。

这下连协议都解析不到了,为什么?因为URLEncoder将我们URL中合法的保留符也给转义了(其会将传入的字符串中的所有非保留字符之外的字符进行转义),就得到了上面的结果,那要怎么办?难道非得要将文件名部分取出来对其进行Encoding?可以是可以,但是感觉不够灵活 ,有点麻烦。

就此我发现,我对URLEncoder的理解出现了问题,此前一直以为只要URL中有非法字符,直接使用该类进行一次编码就可以了,之前一直这样使用也没有问题,因为此前一直转义的是URL的query部分,且只包含一个参数,对前面的path和host没有造成影响,不会对URL中的保留字符出现什么影响从而造成URL解析错误(保留字符被转义了就会导致URL格式错误,URL格式的解析就是靠保留字符进行划分)。

URLEncoder的编码就是将你给定的字符中的每一个非保留字符都进行编码了,对其中的出现的字母"a-zA-Z"、数字"0-9"、特殊字符-_.~等不会进行编码,但是遇到保留字符,非法字符等就会进行编码,所以我们上面把整个URL进行编码,就把“/”也编码了,最终就导致格式解析出现问题。

所以说,我们在使用URLEncoder的时候,要注意避免其将URL本身的保留字符给转义了,而是去转义非法字符和不安全字符

那JAVA中有什么灵活的方式能解决上面的问题呢?

之所以出现上面的问题是因为uri在解析字符串的时候出现了非法字符,导致其解析失败。我们创建的创建的每一个URI对象其都会去解析成出URL中的几个部分。

但是在解析过程中出现非法字符的话,就导致了解析异常,所以我们需要对URL中的非法字符进行转义

但是我们可能也不清楚到底在我们的URI的哪个位置会出现非法的字符,所以想要进行编码也不知道去编码哪个部分(host,path,query等部分),又或者说我们直接对每一个部分都进行一次编码

URL url = new URL("file:///D:/tomcat/a .mp4");
// 利用URL解析出来的几个部分直接创建URI,这样URI就不会进行解析了
// 直接就利用了你给定的部分
URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery());

之所以能像上面这样是因为Java中的URL类在解析URL的时候,其不会去检测每个部分具体的字符,其只是根据保留字符解析出一个URL的几部分。对于我们URL每一个部分之中的非法字符其并不会去扫描(当然,你的非法字符不能是保留字符,否则会导致URL解析每个部分的时候出错,也会出现异常,因为保留字符是区分一个URL的几个部分的关键)

URL类中解析一个URL的类是URLStreamHandler这个类,有兴趣的可以去debug一下

所以说最终的解决办法其实还是要去避免在uri中出现上面特殊的字符

JAVA中的URL和URI类的使用出现的非法字符问题相关推荐

  1. java中常用的包、类、以及包中常用的类、方法、属性----sql和text\swing

    java中常用的包.类.以及包中常用的类.方法.属性 常用的包 java.io.*; java.util.*; java.lang.*; java.sql.*; java.text.*; java.a ...

  2. java urlencoder,java中的URLEncoder和URLDecoder类

    java中的URLEncoder和URLDecoder类 URLEncoder类包含将字符串转换为application/x-www-form-urlencoded MIME 格式的静态方法. 为了解 ...

  3. java 为什么有匿名类_全面了解Java中的内部类和匿名类

    Java内部类(Inner Class),类似的概念在C++里也有,那就是嵌套类(Nested Class),乍看上去内部类似乎有些多余,它的用处对于初学者来说可能并不是那么显著,但是随着对它的深入了 ...

  4. Java 中的线程安全的类

    Java 中的线程安全的类 3 个线程安全的类 它们对应的非线程安全的类 它们延伸的类 其它 它们对应的非线程安全的类 3 个线程安全的类   Java 中的 3 个基本的线程安全的类为:Hashta ...

  5. java面试题27 java中下面哪些是Object类的方法()

    java面试题27 java中下面哪些是Object类的方法() A notify() B notifyAll() C sleep() D wait() 蒙蔽树上蒙蔽果,蒙蔽树下你和我.遇到这种题,我 ...

  6. jAvA中deprecate,在Java中使用Deprecated方法或类是错误的吗?

    1.在Java中使用Deprecated方法或类是错误的吗? 从已弃用的定义 : 注释@Deprecated的程序元素是程序员不鼓励使用的程序元素,通常是因为它是危险的,或者是因为存在更好的selec ...

  7. 解决java中对URL编码的问题

    解决java中对URL编码的问题 参考文章: (1)解决java中对URL编码的问题 (2)https://www.cnblogs.com/a198720/p/4210763.html 备忘一下.

  8. JAVA中同目录下定义类,以及对象的创建与使用,内存图的原理

    JAVA中同目录下定义类,以及对象的创建与使用(听课笔记) JAVA中对象的创建与使用(听课笔记) 示例一 同文件目录下,创建了三个类OOTest01,User,Address类,之间的调用 示例二 ...

  9. java中常用的日期工具类

    java中常用的日期工具类 日期相关的类: package net.yto.ofclacct.core.util;import java.text.ParseException; import jav ...

最新文章

  1. ASCII、Unicode、GBK和UTF-8字符编码的区别联系
  2. python3 post 文件 消息
  3. Luogu 1941 飞扬的小鸟
  4. Django2.0中文文档
  5. 26条C++的经典语录,哪几句戳中你的心!
  6. 如鹏网 net高级技术 第二章 委托和事件(复习)
  7. Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp
  8. trie树 mysql_Trie树详解(转)
  9. 照片尺寸大小对照表_贴片led灯珠型号对照表在手,贴片灯珠选型从此不愁!
  10. oracle的启动与关闭原理-数据路的分阶段启动
  11. KMP复习之poj 3461 Oulipo
  12. eNSP路由器启动不了
  13. Unity ProjectTiny用纯ECS写个跃动的小球
  14. 吴恩达新课快来了!万字博客回顾机器学习算法起源
  15. 小米4 第三方re奇兔_雷军:小米10 Pro已经结单 至尊版货也不多了
  16. 电商专题-电商项目开发规模
  17. 武汉微软认证考点及考试流程 与 微软认证考试流程
  18. java哪座城市好就业_Java开发工程师在哪些城市比较好就业?
  19. win10系统用友软件服务器,win10系统怎么安装用友软件所需要的IIS的图文教程
  20. ZXR10交换机命名规则

热门文章

  1. 定义一个Triangle类表示三角形,测试这个三角形类的所有方法
  2. UML类图绘制_常见设计模式
  3. 报告指出,中国市场巩固了作为智利车厘子全球主要出口目的国的市场地位
  4. httpClient源码如何下载呢?
  5. Java编码ASCII、GB2312、GBK、Unicode、UTF-8、UTF-16 编码方式详解
  6. 如何在码云获取token呢?
  7. 猫眼api html,Requests库+正则爬取猫眼电影Top100
  8. Hadoop各配置文件详解
  9. vue+express+websocket+mongodb在线群聊工具
  10. sca java_SCA客户端以及基于Java的模型实现(一)