- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们的一个外部 API 使用带有特殊字符的查询参数名称(不要问我为什么,我不知道)。我的假客户端对此 API 的方法声明如下:
@GetMapping("/v1/user/{userId}/orders")
List<Order> getOrders(
@PathVariable("userId") String userId,
@RequestParam("page[number]") Integer pageNumber,
@RequestParam("page[size]") Integer pageSize);
正如我所提到的,请求参数包含特殊字符 [
和 ]
。我正在使用 Spock 进行测试,我想像这样设置 Wiremock stub :
wiremock.stubFor(
get(urlPathMatching('/v1/users/' + userId + '/orders'))
.withQueryParam("page[number]", new EqualToPattern("1"))
.withQueryParam("page[size]", new AnythingPattern())
.willReturn(
status(200)
.withHeader("Content-type", "application/json")
.withBody("""[]""")
))
但我得到:
--------------------------------------------------------------------------------------------------
| Closest stub | Request |
--------------------------------------------------------------------------------------------------
|
GET | GET
/v1/users/123/orders | /v1/users/123/orders?page%5Bnumber%5D=%7Bpage%5Bnumber%5
| D%7D&page%5Bsize%5D=%7Bpage%5Bsize%5D%7D
|
Query: page[number] = 1 | <<<<< Query is not present
Query: page[size] [anything] (always) | <<<<< Query is not present
|
--------------------------------------------------------------------------------------------------
经过大量的试验和错误,我想出了一个在 feign 客户端方法中使用 @PathVariable
代替 @RequestParam
的解决方案:
@GetMapping("/v1/users/{userId}/orders?page[number]={pageNumber}&page[size]={pageSize}")
List<Order> getOrders(
@PathVariable("userId") String userId,
@PathVariable("pageNumber") Integer pageNumber,
@PathVariable("pageSize") Integer pageSize);
并在 Wiremock 中对所有查询参数进行编码
wiremock.stubFor(
get(urlPathMatching('/v1/users/' + userId + '/orders'))
.withQueryParam("page%5Bnumber%5D", new EqualToPattern("1"))
.withQueryParam("page%5Bsize%5D", new AnythingPattern())
.willReturn(
status(200)
.withHeader("Content-type", "application/json")
.withBody("""[]""")
))
然后就可以了。但这看起来像是一种黑客行为。使用可选查询参数也是有问题的。
有没有办法将@RequestParam
与特殊字符一起使用?看起来像是 Spring 中的一个错误?
同时我会尝试调试它以了解问题出在哪里。
最佳答案
首先,这不是 Spring 中的错误。这些类似 spring 的注释(来自 spring-web
的 @RequestParam
、@RequestMapping
等)的主要目标是在 Spring MVC 中使用它们服务器端的 Controller ,而不是为请求创建 url。
对于 Feign 客户端,还有另一个库 spring-cloud-openfeign
,它允许您将它们放在 Feign 客户端中进行请求映射,而不是原始 Feign 注释(例如 @RequestLine
、@Param
等)。 SpringMvcContract 负责它,it is used by default in Spring applications 。但这只是为了方便使用 Feign 和 Spring 的特定开发人员群体,因此并不是更改这些注释的签名或添加一些新设置的理由。
关于所描述的问题 - 似乎没有任何“官方”方法来禁用 url 编码,即使您使用原始 Feign 注释进行请求映射 - 目前(版本 10.7.4 ),您只能对斜杠执行此操作(例如,检查 this issue )。
我进行了一些进一步的调查并得出以下几点:
RequestInterceptor
(通过反射,f.e.)来修复构造的网址,但这实际上毫无意义,因为 after applying all interceptors the request is built 并且目前它再次隐式编码括号( check幕后发生的事情,基本上它使用 queryTemplate.toString()
,而它又在使用 UriUtils 类的方法时对括号进行编码)Client
开始执行,我实际上在这一步成功修复了url。我从标准 Client.Default
继承了一个类,注册了它而不是原来的自动配置类,然后在实际调用客户端之前完成了我的工作(ofc 可以对客户端执行相同的操作)不同的客户端,例如 LoadBalancerFeignClient
):import feign.Client;
import feign.Request;
import feign.Response;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.io.IOException;
import java.lang.reflect.Field;
@Component
public class MyClient implements Client {
private Client delegate;
public MyClient() {
this.delegate = new Client.Default(null, null);
}
@Override
public Response execute(Request request, Request.Options options) throws IOException {
fixRequestUrlIfPossible(request);
return delegate.execute(request, options);
}
private void fixRequestUrlIfPossible(Request request) {
try {
Field urlField = ReflectionUtils.findField(Request.class, "url");
urlField.setAccessible(true);
String encodedUrl = (String) urlField.get(request);
String url = encodedUrl.replace("%5B", "[").replace("%5D", "]");
urlField.set(request, url);
} catch (Exception e) {
/*NOP*/
}
}
}
但是由于反射,它很容易出错(在更高版本的 Feign 中可能会停止工作)。
所以,这取决于你 - 如果你不害怕做这种事情,就使用这种方法。其实我更喜欢你的版本。主要问题是:您的真实服务器是否能够处理带有编码括号的请求?在我看来,Wiremock 的问题不太重要。
关于spring - Spring feign 客户端中 @QueryParam 名称中的特殊字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58380784/
我使用 vuejs-axios 从客户端获取数据并将其发布到服务器端。在服务器端,我使用了 java,而我使用 SparkJAVA 框架来处理请求响应。下面提到的代码块是我用来将表单数据从 vuejs
您好,使用多路由构建 Angular 应用。 导航到页面 > queryParams 触发订阅。 当我在页面中时,我需要更改页面内的 queryParams 但不会再次触发订阅功能。 (因为我不想再次
我正在寻找在 Spring 中使用 @QueryParam 的简单示例。我的想法是有一个像这样的链接,它将获取 id 值,运行我的 java 类并显示返回的字符串。我的问题是没有找到返回值。 http
我有以下格式从浏览器发送的查询参数 sort[0][field]:prodId sort[0][dir]:asc 如何使用@QueryParam在服务器中检索上述参数? 从 Chrome 控制台 ta
我正在创建一个端点(使用 Jersey 注释),该端点接收字符串列表作为参数。字符串需要包含一个键和一个值。所以在 url 上它看起来像 ?params=key1=value1¶ms=key2
我正在尝试从 REST Web 服务的 URL 请求中获取请求参数。 @Path 能够映射方法。但 QueryParam 无法从查询参数中获取值。 我的请求网址是 192.168.20.147:808
我必须从客户端 java 类调用一个 Restful Web 服务。 我需要传递 HashMap、String,它必须返回一个 bean 列表。我正在使用 Jersey Restful 网络服务 我的
我正在使用 Jersey for Rest 并有一个接受 @QueryParam. 的方法 但是,用户可以像这样发送@QueryParam.: contractName# 其中 # 是 0-155 之
这是函数头 @GET @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Path("/getxyz") pub
我正在尝试更新(添加、删除)组件中的 queryParams。在 angularJS 中,它曾经是可能的,这要归功于: $location.search('f', 'filters[]'); // s
我有一个 Express 服务器,并且在我的路由中配置了: app.use(express.urlencoded({ extended: false })); 在前端,我使用 Angular 发送请求
给出以下代码: newtype HelloMessage = HelloMessage { msg :: String } deriving (Generic) instance ToJSON H
我有一个 RESTful 服务。这需要两个参数:开始日期和结束日期。 如果我使用 @RequestParam 注释,我就会得到我需要的东西。但如果我使用 @QueryParam,我注意到即使传递它,它
有没有办法在不使用 @QueryParam 注释显式声明其名称的情况下获取任何查询参数? 我有一个字符串,其中可能包含诸如 {animal} 之类的标记,然后将其替换为发布的查询参数,例如?anima
当我在 JAX-RS 中添加字符串的默认值时,它不会获取该值。它保持为 null 或空。 @QueryParam("status") private String status = "confirme
例如,我有课 class MyQuery { Date start; Date end; ChronoUnit scale; // ChronoUnit is enum } 我想声明
对于以下示例(使用 Jersey 2.6),百分比编码的查询参数未解码,相反,+ 被空格替换。 @Path("test") public class TestResource { @Path(
我目前正在尝试了解如何在 Angular 组件中收集 queryParameters。因为我只想在初始化期间收集它们一次,所以我首先尝试了快照模式: ngOnInit() { console.
我想在我的应用程序中提供一个基于来自 url 的 QueryParam 的常量。 localhost:4200?flag=true 在我添加的模块提供者中 { provide: FLAG, useFa
我正在尝试使用 Angular 2.0 捕获查询字符串参数,但遇到了困难。我有一个这样的网址 http://localhost:5000/?id_token=eyJ0eXAiO .... 而且我希望能
我是一名优秀的程序员,十分优秀!