发送“?”和 RESTEasy 查询字符串中的“=”字符

Sending "?" and "=" characteres in the query string with RESTEasy

我正在使用 RESTEasy 在我的应用程序中创建 REST API:

@GET
@Path("/api")
public Response getData(@QueryParam("from") String from, 
                        @Context HttpServletRequest httpRequest)
                        throws ProtocolException, MalformedURLException, IOException {

    System.out.println("from: " + from);

    ...
}

此代码属于为以下API提供数据:

http://localhost:8080/LynkBeta/f/query?from=search?q=developer

打印查询参数时,我只得到以下值:

search?q 

但实际值为:

search?q=developer

查询参数包含一个等于的符号(=)。没有它它工作正常。我知道我肯定在这里遗漏了一些东西。

如何处理这种值?我需要包括什么来处理这个?

我研究了一下,但我的搜索没有直接的答案。

简答

要将 search?q=developer 作为查询参数的值发送,该值必须经过 URL 编码。所以,search?q=developer 会变成 search%3Fq%3Ddeveloper.

查询字符串

根据RFC 3986,查询字符串定义如下:

3.4. Query

The query component contains non-hierarchical data that, along with data in the path component, serves to identify a resource within the scope of the URI's scheme and naming authority (if any). The query component is indicated by the first question mark ("?") character and terminated by a number sign ("#") character or by the end of the URI. [...]

字符,例如?(用于开始查询字符串)、&(用于分隔查询参数)和=(用于将参数与其值相关联) ) 是 reserved.

如果需要发送查询字符串参数等字符,需要对它们进行URL编码。有关何时需要编码的更多详细信息,请查看 RFC 3986.

2.4 何时编码或解码 部分

URL编码

URL 编码也称为百分比编码:

2.1. Percent-Encoding

A percent-encoding mechanism is used to represent a data octet in a component when that octet's corresponding character is outside the allowed set or is being used as a delimiter of, or within, the component. A percent-encoded octet is encoded as a character triplet, consisting of the percent character "%" followed by the two hexadecimal digits representing that octet's numeric value. For example, "%20" is the percent-encoding for the binary octet "00100000" (ABNF: %x20), which in US-ASCII corresponds to the space character (SP). [...]

许多语言都支持它。以下是 Java 和 JavaScript 中的示例:

String param = "search?q=developer";
String url = "http://localhost:8080/LynkBeta/f/query?from=" + 
    URLEncoder.encode(param, "UTF-8");
var param = "search?q=developer";
var url = "http://localhost:8080/LynkBeta/f/query?from=" + 
    encodeURIComponent(param);

使用 JAX-RS 编码的参数

考虑一下,例如,您正在请求 http://example.com/api/query?biz=search%3Fq%3Ddeveloper

默认情况下,当使用 @QueryParam 注释时,JAX-RS 将 URL 解码查询参数:

@GET
@Path("/foo")
public Response someMethod(@QueryParam("biz") String biz) {
    ...
}

因此,biz 参数的值将是 search?q=developer

如果需要接收URL编码的参数,使用@Encoded注解:

@GET
@Path("/foo")
public Response someMethod(@QueryParam("biz") @Encoded String biz) {
    ...
}

现在,biz 参数的值将是 search%3Fq%3Ddeveloper