如何在Java中判断URL参数是否需要进行编码

3
我正在编写一个Java应用程序,接受URL参数值,这些值可能已经被编码或未编码。我需要一种简单的方法来判断是否需要对参数字符串进行编码。
换句话说,我想要一个函数boolean needsEncoding(String param),如果我传入字符串"foo@test.com",则返回true;如果我传入字符串"foo%40test.com",则返回false。但是这个想法存在歧义。我怎么知道后者字符串中的"%"符号是否应该被编码?一种处理方法是修改我的合同——要求客户端传递未编码的字符串,以便我知道我始终需要对它们进行编码。有什么想法吗?
5个回答

6

我想把这个作为拟议答案,以便人们可以投票:

处理这种情况的一种方法是修改我的合同——要求客户传递未编码的字符串,这样我就知道我总是需要对它们进行编码。


最好不要猜测。 - Rontologist
如果用户设置为foo%40test.com,无法检测出用户是想要foo%40test.com还是foo@test.com。需要更改合同。 - Horcrux7
如果客户端是人类呢?你无法控制人们在输入URL字段中输入什么。 - gamliela

1

解码字符串,检查原始字符串和解码后的字符串之间的所有差异是否是有效的URL实体,这个方案怎么样?


可能行得通。你能再详细说明一下吗?如果我解码"test%40geek.com",我会得到"test@geek.com" - 我该如何比较这两者?你有代码片段的想法吗? - Julie
一个简单的n^2差异算法应该可以解决问题:使用两个指针指向字符串,比较它们,如果它们匹配,则迭代两个指针,否则迭代长字符串中的一个指针,并将指针刚刚指向的字符保存到缓冲区中。当它们再次匹配时,如果缓冲区不等于"",则将其保存为差异。 - rcreswick
听起来像是一个动态规划的方法来解决这个问题。那么,如果我传入"1+2"并确定"+"被解码为" ",接下来怎么办?我仍然不知道这是否是一个预编码的字符串,或者我是否应该真正将"+"编码为"%2B"。我认为这个问题是棘手的。 - Julie

0

字符串已进行URL编码的迹象:

  1. 没有空格,但有很多加号符号。
  2. 所有百分号后面都跟着两个数字。
  3. 其中没有a..b、A..B、0..9、"."、"_"、"-"、"*"、"%"和"+"以外的字符。

然而,我认为在这里更推荐改变合同。


感谢您的输入。看着所有丑陋(可能也不可靠)的代码,我认为你是对的,最好改变合同! - Julie

0

您可以使用java.net.URLDecoder对输入进行处理,并通过比较输入和输出字符串的值来查看是否发生更改。查看URLDecoderJavadocs,它描述了应用于输入字符串的业务逻辑,以确定是否需要进行URL解码。

如果您必须获得一个boolean结果,并且不想承担尝试解码以获取该boolean结果的开销,您可以打开URLDecoder类的源代码,并使用它用于确定是否需要进行URL解码的相同业务逻辑。


从Javadoc来看,如果我将“1+2”传递给我的布尔方法,URLDecoder会返回“1 2”。我仍然无法确定客户端是否意味着字符串“1+2”应该被编码,还是只有已经被编码的“1 2”。 - Julie

0
这是我处理这个问题的常规方法。首先,由于“+”是一个令人讨厌的特殊情况,我禁止它作为编码的一部分。如果他们输入加号,则是加号,如果他们想要空格,则可以按下键盘底部的大条。 (是的,我已经将其作为某些合同的一部分)。但实际上,您可以解释为您为客户工作得如此努力,以至于他们不需要担心自己进行编码。
然后,我重写了java.net.URLDecoder.decode以删除“+”情况。(实际上只是将其剪切并粘贴到我正在使用该项目的任何实用程序类中,并删除了约4行)。
然后,对于我获得的所有内容,我只需通过解码器,然后通过编码器运行它。如果已编码,则会解码和重新编码它,如果未编码,则会对其进行编码。 我几年前从SO上的某个人那里得到了这个提示,无法记住要给予适当的信用。
所以最终我得到:
String properlyencodedstring = 
java.net.URLEncoder.encode(LocalDecoder.localdecode(someformdatastring),"UTF-8");

唯一需要调整的情况是有大量URL需要输入和处理的数据,此时我会改变我的假设并使用 input type="url"(对于旧浏览器使用某种JavaScript polyfill),并预处理使用.replaceAll("+", " ") ,因为在这种情况下不允许输入任何空格。(而且很可能无论如何都要使用java.net.URI

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接