Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弹簧&x27;s UriComponentsBuilder.queryParam问题_Java_Spring_Rest - Fatal编程技术网

Java 弹簧&x27;s UriComponentsBuilder.queryParam问题

Java 弹簧&x27;s UriComponentsBuilder.queryParam问题,java,spring,rest,Java,Spring,Rest,我最近切换到Spring使用ServiceNow托管的RESTAPI调用 我正在构建我的URI,如下所示: UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl.toString()); logger.info("URI before Query Param: " + builder.build().encode().toUri()); builder.queryParam("sysparm_limit",

我最近切换到Spring使用ServiceNow托管的RESTAPI调用

我正在构建我的URI,如下所示:

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(baseUrl.toString());
logger.info("URI before Query Param: " + builder.build().encode().toUri());
builder.queryParam("sysparm_limit", "2000000");
builder.queryParam("sysparm_offset", "0");
builder.queryParam("sysparm_exclude_reference_link", "true");
//this line is the issue because there is a = sign here
builder.queryParam("sysparm_query=user_name", snUser.getUser_name());
logger.info("URI after Query Param: " + builder.build().encode().toUri());
此代码的输出为:

INFO: URI before Query Param: https://sandbox.service-now.com/api/now/v1/table/sys_user
INFO: URI after Query Param: https://sandbox.service-now.com/api/now/v1/table/sys_user?sysparm_limit=2000000&sysparm_offset=0&sysparm_exclude_reference_link=true&sysparm_query%3Duser_name=AX0011
问题在于final builder.queryParam。我得到的输出如下:

sysparm_query%3Duser_name=AX0011
但我想要的是:

sysparm_query=user_name=AX0011
最终的URI如下所示:

INFO: URI after Query Param: https://sandbox.service-now.com/api/now/v1/table/sys_user?sysparm_limit=2000000&sysparm_offset=0&sysparm_exclude_reference_link=true&sysparm_query=user_name=Z001NR6

所以我试着替换

builder.queryParam("sysparm_query=user_name", snUser.getUser_name());
作者:

将原始输出更改为:

INFO: URI after Query Param: https://sandbox.service-now.com/api/now/v1/table/sys_user?sysparm_limit=2000000&sysparm_offset=0&sysparm_exclude_reference_link=true&sysparm_query%3Duser_name=Z001NR6
致:

请注意,sysparm_query%3Duser_name=Z001NR6如何更改为sysparm_query=user_name%3DZ001NR6


是否仍要在输出中看到a=而不是%3D?

该参数看起来很奇怪-但是-您可以使用
UriComponentsBuilder\query
方法手动添加它:

UriComponentsBuilder builder = UriComponentsBuilder
            .fromHttpUrl("https://example.com/api/")
            .queryParam("param1", "12345")
            .queryParam("param2", "abc")
            .query("query=username=JOE");

System.out.println(builder.build().toString()); 
// produces https://example.com/api/?param1=12345&param2=abc&query=username=JOE

System.out.println(builder.build().encode().toString());
// produces https://example.com/api/?param1=12345&param2=abc&query=username%3DJOE
手动连接:

UriComponentsBuilder builder = UriComponentsBuilder
            .fromHttpUrl("https://example.com/api/")
            .queryParam("param1", "12345")
            .queryParam("param2", "abc");
// the parameter has to be properly url-encoded manually (not shown here)
String uri = builder.build().encode().toString() + "&query=username=JOE";

System.out.println(uri);
// produces: https://example.com/api/?param1=12345&param2=abc&query=username=JOE

URL的查询组件经常用于以
key=value
对的形式携带信息;您可以将其视为一张
地图
。在这种情况下,
=
&
是分隔这些对的特殊字符,当它们构成
的一部分时,必须对它们进行编码,以确保以这种方式读取查询字符串的任何内容都能够正确解析它

在您的情况下,如何使用
builder
取决于您以后希望如何检索数据。有两种选择:

// Building the URL:
builder.queryParam("sysparm_query=user_name", snUser.getUser_name());
// URL contains ...&sysparm_query%3Duser_name=AX0011

// Reading the parsed query map:
Map<String, String> query = ...
String data = query.get("sysparm_query=user_name");
// value is AX0011
//构建URL:
queryParam(“sysparm\u query=user\u name”,snUser.getUser\u name());
//URL包含…&sysparm\u查询%3Duser\u name=AX0011
//正在读取已解析的查询映射:
映射查询=。。。
String data=query.get(“sysparm\u query=user\u name”);
//值为AX0011

//构建URL:
queryParam(“sysparm_query”,“user_name=“+snUser.getUser_name());
//URL包含…&sysparm\u query=用户名%3DAX0011
//正在读取已解析的查询映射:
映射查询=。。。
字符串值=query.get(“sysparm_query”);
//值为user\u name=AX0011

在正确编码的URL中,其中一个
=
将始终编码为
%3D
。使用
UriComponentsBuilder
可以确保URL的编码正确,并且任何读取URL的内容都可以正确地进行编码,而不会丢失数据。

我知道查询看起来很奇怪,但事实就是这样。在.query(“query=username=JOE”)中,JOE的值被参数化,我可以用snUser.getUser\u name()替换。我知道我可以创建一个字符串连接来实现这一点,但是UriComponentBuilder中有默认方法吗?没有,没有可用的默认方法。但是继续进行字符串连接(java编译器会将其优化为
StringBuilder
)我合并了您建议的更改,但没有产生预期的效果。这里有我遗漏的东西吗?我修改了原始帖子以反映它。是的,我使用了它
builder.build().encode().toUri()
response=restemplate.exchange(builder.build().encode().toUri(),HttpMethod.GET,snHttpEntity,String.class)恐怕您需要手动对奇怪的查询参数进行编码。
UriComponentsBuilder builder = UriComponentsBuilder
            .fromHttpUrl("https://example.com/api/")
            .queryParam("param1", "12345")
            .queryParam("param2", "abc");
// the parameter has to be properly url-encoded manually (not shown here)
String uri = builder.build().encode().toString() + "&query=username=JOE";

System.out.println(uri);
// produces: https://example.com/api/?param1=12345&param2=abc&query=username=JOE
// Building the URL:
builder.queryParam("sysparm_query=user_name", snUser.getUser_name());
// URL contains ...&sysparm_query%3Duser_name=AX0011

// Reading the parsed query map:
Map<String, String> query = ...
String data = query.get("sysparm_query=user_name");
// value is AX0011
// Building the URL:
builder.queryParam("sysparm_query", "user_name=" + snUser.getUser_name());
// URL contains ...&sysparm_query=user_name%3DAX0011

// Reading the parsed query map:
Map<String, String> query = ...
String value = query.get("sysparm_query");
// value is user_name=AX0011