让我们假设,我已经字符串'=&?/;#+%' 是我的网址,让我们说是这样的:

example.com/servletPath/someOtherPath/myString/something.html?a=b&c=d#asdf

在myString是上述串。我编码的关键部分,以便URL看起来像

example.com/servletPath/someOtherPath/%3D%26%3F%2F%3B%23%2B%25/something.html?a=b&c=d#asdf

到目前为止一切顺利。

当我在servlet和我读过 request.getRequestURI(), request.getRequestURL()request.getPathInfo(), 回值已经解码的,所以我获得strilng喜欢

someOtherPath/=&?/;#+%/something.html?a=b&c=d#asdf

而且我不能区分真实的特殊字符和编码的。

我已经解决了特定的问题通过禁止上面的字符,其工作在这种情况,但我仍然不知道是否有任何方式获得未解码的网址在servlet类。

又一个编辑:当我们打这个问题的最后一个晚上我太累了,要注意什么是真的,这是 甚至更古怪! 我servlet映,说/servletPath/*之后,我可以把我想拿到我的servlet响应取决于其余的路径, 除了 当没%2F在路径。在这种情况下 请求从来没有打servlet, 我404!如果我把'/'代替%2F它的工作确定。我正在Tomcat6.0.14Java1.6.0-04在Linux。

有帮助吗?

解决方案

还有一个之间的根本区别'%2F'和'/',两用浏览器和服务器。

该HttpServletRequest规格说(没有任何逻辑,AFAICT):

  • getContextPath:不解码
  • getPathInfo:解码
  • getPathTranslated:不解码
  • getQueryString:不解码
  • getRequestURI:不解码
  • getServletPath:解码

结果getPathInfo() 应该 被解码,但结果的getRequestURI() 必须不 被解码。如果是,你的小容器被破坏的规范(如Wouter Coekaerts和弗朗索瓦砾石正确地指出的)。这Tomcat版本都要跑?

使问题更加混乱,当前Tomcat版本拒绝路径的编码包含的某些特殊的人物, 由于安全原因.

其他提示

如果有在%2F解码 URL,它指的编码 URL包含%252F

由于为什么不直接劈在%2F,而不必担心URL编码?/"\/"

按照的Javadoc ,getRequestURI不应该解码的字符串。在另一方面,getServletPath返回一个解码的字符串。我测试这个本地使用码头和它的行为与该文档所描述的。

因此,有可能是因为您所描述的Sun文档不符的行为在作怪别的东西在你的情况。

好像你正在尝试做的事情RESTy(使用泽西)。可以是你刚才分析过的URL的开头和结尾的部分,让你正在寻找的数据?

url.substring(startLength,url.length - endLength);

更新: 这个答案原本错误地指出,'/'和'%2F'在一个路径应始终是处理相同。它们实际上是不同的,因为一个路径是一个列表/-分离分段。

你不应该做一个差别编码和编码的字符 路径的一部分 该网址。没有性格内部的道路,可以有一个特殊的意义,在一个网址。E.g。'%2F'必须解释的相同'/',以及浏览器访问这一个网址是免费更换一个由其他的,因为它认为合适的。制作它们之间的差异是突破的标准如何网址的编码。

在完整的网址,必须使之间的差逃和非逃字符用于不同原因,包括:

  • 看到那里的路径部分结束。因为一个?编码中的路径不应被视为结束。
  • 内部查询串。因为一部分的参数值可能包含'&'或'=',...
  • 内部路径,'/'隔开两个分段的同时,'%2F'可以包含在一段

Java交易的现与前两个情况:

  • getPathInfo() 这只返回的路径的一部分,解码
  • getParameter(String) 访问部分的查询部分

它并不处理以及与第三种情况。如果你想让之间的差异'/'的分离的两个路段,和a'/'内的一个路段(%2F),则无法始终所代表的路径作为一个解码串。你可以代表它作为一个编码的字符串(例如"foo/吧%2Fbaz"),或者作为一个列表中的解码分段(例如"foo","bar/baz").但是,因为getPathInfo()API的承诺,以做到这一点(一个解码string),它别无选择,只能享'/'和'%2F'作为同的。

对于通常的网页应用程序,这只是罚款。如果你是,在罕见的情况下你真的需要做出区别,你可以做你自己分析的网址,得到原始版本 getRequestURI().如果这个URL码为你的权利要求,那么这意味着有一个错误在servlet执行情况。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top