英文:
How to create interceptor for transforming http headers to custom dto?
问题
在我的一个应用程序中,有许多具有相同一组标头的端点:
@RequestHeader("foo") String foo,
@RequestHeader("bar") String bar,
@RequestHeader("baz") String baz,
并且在每个控制器方法中,我根据这些标头创建自己的自定义 DTO:
MyDto myDto = new MyDto(foo, bar, baz);
为了避免重复,并且不必在每个方法中添加/删除一个标头 50 次,我希望有一个类似拦截器的类,它将获取 HttpHeaders
并将其转换为 MyDto
,然后我希望能够在控制器方法中替换所有请求标头,只需简单地在幕后创建 MyDto myDto
。
我尝试找到解决方案,但没有找到任何内容。
实际:
@PostMapping("/myEndpoint")
public MyResponse myEndpoint(@RequestHeader("foo") String foo,
@RequestHeader("bar") String bar,
@RequestHeader("baz") String baz,
@RequestBody MyRequest myRequest) {
MyDto myDto = new MyDto(foo, bar, baz);
myService.doSomething(myDto);
...
}
期望:
@PostMapping("/myEndpoint")
public MyResponse myEndpoint(MyDto myDto,
@RequestBody MyRequest myRequest) {
myService.doSomething(myDto);
...
}
我还为此编写了一个方法:
public MyDto transform(HttpHeaders httpHeaders) {
String foo = getHeader(httpHeaders, "foo");
String bar = getHeader(httpHeaders, "bar");
String baz = getHeader(httpHeaders, "baz");
return new MyDto(foo, bar, baz);
}
private String getHeader(HttpHeaders httpHeaders,
String key) {
return Optional.ofNullable(httpHeaders.get(key))
.map(Collection::stream)
.orElseGet(Stream::empty)
.findFirst()
.orElse(null);
}
但我不知道何时可以调用它,以便在每个请求上运行它。
英文:
In one of my app I have many endpoints with the same set of headers:
@RequestHeader("foo") String foo,
@RequestHeader("bar") String bar,
@RequestHeader("baz") String baz,
and in each controller method I am creating my custom dto based on those headers:
MyDto myDto = new MyDto(foo, bar, baz);
To avoid duplicates and adding/removing one header 50 times to each method, I want to have something like interceptor class that will take HttpHeaders
and will transform it MyDto
only once, so then I want to be able to replace all request headers in controller methods by simply MyDto myDto
created behind the scenes.
I tried to find solution, but didn't found anything.
Actual:
@PostMapping("/myEndpoint")
public MyResponse myEndpoint(@RequestHeader("foo") String foo,
@RequestHeader("bar") String bar,
@RequestHeader("baz") String baz,
@RequestBody MyRequest myRequest) {
MyDto myDto = new MyDto(foo, bar, baz);
myService.doSomething(myDto);
...
}
Expected:
@PostMapping("/myEndpoint")
public MyResponse myEndpoint(MyDto myDto,
@RequestBody MyRequest myRequest) {
myService.doSomething(myDto);
...
}
I also have a method for it:
public MyDto transform(HttpHeaders httpHeaders) {
String foo = getHeader(httpHeaders, "foo");
String bar = getHeader(httpHeaders, "bar");
String baz = getHeader(httpHeaders, "baz");
return new MyDto(foo, bar, baz);
}
private String getHeader(HttpHeaders httpHeaders,
String key) {
return Optional.ofNullable(httpHeaders.get(key))
.map(Collection::stream)
.orElseGet(Stream::empty)
.findFirst()
.orElse(null);
}
But I don't know when I can call it to make it runnable on each request.
答案1
得分: 1
我正要说,编写并注册一个“custom HandlerInterceptor”。它将允许您访问头信息,但问题是您将无法访问转换后的@RequestBody对象——至少就我所知。我认为这不容易实现。
英文:
I was about to say , write and register a custom HandlerInterceptor
. It would allow you to access the headers, but the problem is you won't get access to the converted @RequestBody object - at least, as far as I know. I don't think this can easily be done.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论