关于Java:查询字符串中Hash(#)的行为是什么

What is the behavior of Hash(#) in query string

我正在发送以下带有查询字符串的网址。在查询字符串中一个参数
" approverCmt"具有带哈希值(#)的值。

1
   "/abc/efd/xyz.jas?approverCmt=Transaction Log #459505&batchNm=XS_10APR2015_082224&mfrNm=Timberland"

在服务器端,当我尝试从请求中获取它时,

1
2
3
    approverCmt = Transaction Log  ----->"#459505" is missing
    batchNm = null
    mfrNm = null

并且如果我从查询字符串中删除哈希(#),或者如果我将#替换为#,那么一切都会正常运行

我不明白为什么另一个参数包含一个井号(#)却无法获得空值的原因。

感谢任何人都可以解释。


这被称为"片段标识符"。

如维基百科所述:

The fragment identifier introduced by a hash mark # is the optional last part of a URL for a document. It is typically used to identify a portion of that document.

#之后的部分是client的信息。它不会发送到服务器。将仅浏览器需要的所有内容放在此处。

您可以在JavaScript中使用encodeURIComponent()函数对URL中的特殊字符进行编码,以便将#字符转换为其他字符,从而可以确保将整个URL发送到服务器。 >


Hash值用于锚,因此它仅是客户端,它通常在客户端框架中使用,例如angular进行客户端路由。

锚点在服务器端不可用。

在您的情况下,您不需要锚点,但是带有#的参数值会打断查询字符串,该值为"事务日志#459505 "。

编辑无法使用的天真的解决方案,只需将其作为历史记录即可,请参见下面的实际解决方案

解决方案是对客户端进行编码,对服务端进行解码

使用javascript编码

1
2
   encodeURI("Transaction Log #459505")
   //result value"Transaction%20Log%20#459505"

用Java解码

1
2
 java.net.URLDecoder.decode("Transaction%20Log%20#459505");
  //result "Transaction Log #459505"

编辑:但是:Javascript编码的方式与Java不同
因此,正确的答案(我希望)是用#手动替换所有的#,然后Java将对其进行正常解码,或者按照注释中的建议使用encodeURIComponent。根据您的需要,替换解决方案似乎就足够了。

使用JavaScript编码:

1
2
encodeURI("yourUrl/Transaction Log #459505").replace(/#/,"%23")
//result: yourUrl/Transaction%20Log%20%23459505

Java中的解码不会改变

1
2
java.net.URLDecoder.decode("Transaction%20Log%20#459505")
// result (java.lang.String) Transaction Log #459505

很抱歉,我没有看到Java和JavaScrip Url编码之间的区别


哈希是锚点:

有关更多信息,请参见Wikipedia