在 Java 中解码 URI 查询字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2632175/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Decoding URI query string in Java
提问by Jason S
I need to decode a URI that contains a query string; expected input/output behavior is something like the following:
我需要解码包含查询字符串的 URI;预期的输入/输出行为类似于以下内容:
abstract class URIParser
{
/** example input:
* something?alias=pos&FirstName=Foo+A%26B%3DC&LastName=Bar */
URIParser(String input) { ... }
/** should return "something" for the example input */
public String getPath();
/** should return a map
* {alias: "pos", FirstName: "Foo+A&B=C", LastName: "Bar"} */
public Map<String,String> getQuery();
}
I've tried using java.net.URI, but it seems to decode the query string so in the above example I'm left with "alias=pos&FirstName=Foo+A&B=C&LastName=Bar" so there is ambiguity whether a "&" is a query separator or is a character in a query component.
我试过使用java.net.URI,但它似乎对查询字符串进行解码,因此在上面的示例中,我只剩下 "alias=pos&FirstName=Foo+A&B=C&LastName=Bar" 所以是否存在歧义 "& " 是查询分隔符或查询组件中的字符。
Edit:I just tried URI.getRawQuery()and it doesn't do the encoding, so I can split the query string with a &
, but then what do I do? Javascript has decodeURIComponent, I can't seem to find the corresponding method in Java.
编辑:我刚刚尝试了URI.getRawQuery()并且它不进行编码,所以我可以用 a 拆分查询字符串&
,但是我该怎么办?Javascript 有decodeURIComponent,我好像在 Java 中找不到对应的方法。
Any suggestions? I would prefer not to use any new libraries.
有什么建议?我不想使用任何新的库。
采纳答案by Maurice Perry
See class URLDecoder
回答by janb
Use
用
URLDecoder.decode(proxyRequestParam.replace("+", "%2B"), "UTF-8")
.replace("%2B", "+")
to simulate decodeURIComponent
. Java's URLDecoder
decodes the plus sign to a space, which is not what you want, therefore you need the replace statements.
来模拟decodeURIComponent
。JavaURLDecoder
将加号解码为空格,这不是您想要的,因此您需要替换语句。
Warning:the
.replace("%2B", "+")
at the end willcorrupt your data ifthe original (pre-x-www-form-urlencoded) contained that string, as @xehpuk pointed out.
警告:将
.replace("%2B", "+")
在年底会破坏你的数据,如果原始(预X WWW的形式,进行了urlencoded)含有该字符串,如@xehpuk指出。
回答by IHeartAndroid
Regarding the issue with the + sign :
关于 + 号的问题:
I made a helper class that wraps the URLDecoder function based on the answer of @janb
我根据@janb 的回答做了一个封装了 URLDecoder 函数的辅助类
import android.net.Uri;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class DateDecoder {
private static final String KEY_DATE = "datekey";
private static final SimpleDateFormat SIMPLE_DATE_FORMAT =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.US);
public static void main(String[] args) throws UnsupportedEncodingException {
try {
Uri uri = Uri.parse("http://asdf.com?something=12345&" +
KEY_DATE +"=2016-12-24T12:00:00+01:00");
System.out.println("parsed date: " + DateDecoder.createDate(uri)); // parsed date: Sat Dec 24 12:00:00 GMT+01:00 2016
} catch (Exception e) {
e.printStackTrace();
}
}
@Nullable
public static Date createDate(@Nullable Uri data) {
if (data != null) {
try {
String withPlus = decodeButKeepPlus(KEY_DATE, data.getEncodedQuery());
if (!TextUtils.isEmpty(withPlus)) {
return SIMPLE_DATE_FORMAT.parse(withPlus);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* copied from android.net.Uri.java
*/
@Nullable
public static String decodeButKeepPlus(String encodedKey, String completeEncodedQuery)
throws UnsupportedEncodingException {
final int length = completeEncodedQuery.length();
int start = 0;
do {
int nextAmpersand = completeEncodedQuery.indexOf('&', start);
int end = nextAmpersand != -1 ? nextAmpersand : length;
int separator = completeEncodedQuery.indexOf('=', start);
if (separator > end || separator == -1) {
separator = end;
}
if (separator - start == encodedKey.length()
&& completeEncodedQuery.regionMatches(start, encodedKey, 0, encodedKey.length())) {
if (separator == end) {
return "";
} else {
String encodedValue = completeEncodedQuery.substring(separator + 1, end);
if (!TextUtils.isEmpty(encodedValue)) {
return URLDecoder.decode(encodedValue.replace("+", "%2B"), "UTF-8").replace("%2B", "+");
}
}
}
// Move start to end of name.
if (nextAmpersand != -1) {
start = nextAmpersand + 1;
} else {
break;
}
} while (true);
return null;
}
}
回答by Bhaskara Arani
var reqParam = URLDecoder.decode(reqParam, "UTF-8")
回答by vipcxj
new java.net.URI(proxyRequestParam).getPath()
The string encoded by js encodeURIComponent should just be a path, without schema and other things. However it still a valid input for java.net.URI. So java.net.URI will do everything for us and then the path of it is what we want.
js encodeURIComponent 编码的字符串应该只是一个路径,没有模式和其他东西。然而,它仍然是 java.net.URI 的有效输入。所以 java.net.URI 会为我们做一切,然后它的路径就是我们想要的。