如何创建拦截器以将 HTTP 标头转换为自定义 DTO?

huangapple go评论93阅读模式
英文:

How to create interceptor for transforming http headers to custom dto?

问题

在我的一个应用程序中,有许多具有相同一组标头的端点:

  1. @RequestHeader("foo") String foo,
  2. @RequestHeader("bar") String bar,
  3. @RequestHeader("baz") String baz,

并且在每个控制器方法中,我根据这些标头创建自己的自定义 DTO:

  1. MyDto myDto = new MyDto(foo, bar, baz);

为了避免重复,并且不必在每个方法中添加/删除一个标头 50 次,我希望有一个类似拦截器的类,它将获取 HttpHeaders 并将其转换为 MyDto,然后我希望能够在控制器方法中替换所有请求标头,只需简单地在幕后创建 MyDto myDto

我尝试找到解决方案,但没有找到任何内容。

实际:

  1. @PostMapping("/myEndpoint")
  2. public MyResponse myEndpoint(@RequestHeader("foo") String foo,
  3. @RequestHeader("bar") String bar,
  4. @RequestHeader("baz") String baz,
  5. @RequestBody MyRequest myRequest) {
  6. MyDto myDto = new MyDto(foo, bar, baz);
  7. myService.doSomething(myDto);
  8. ...
  9. }

期望:

  1. @PostMapping("/myEndpoint")
  2. public MyResponse myEndpoint(MyDto myDto,
  3. @RequestBody MyRequest myRequest) {
  4. myService.doSomething(myDto);
  5. ...
  6. }

我还为此编写了一个方法:

  1. public MyDto transform(HttpHeaders httpHeaders) {
  2. String foo = getHeader(httpHeaders, "foo");
  3. String bar = getHeader(httpHeaders, "bar");
  4. String baz = getHeader(httpHeaders, "baz");
  5. return new MyDto(foo, bar, baz);
  6. }
  7. private String getHeader(HttpHeaders httpHeaders,
  8. String key) {
  9. return Optional.ofNullable(httpHeaders.get(key))
  10. .map(Collection::stream)
  11. .orElseGet(Stream::empty)
  12. .findFirst()
  13. .orElse(null);
  14. }

但我不知道何时可以调用它,以便在每个请求上运行它。

英文:

In one of my app I have many endpoints with the same set of headers:

  1. @RequestHeader("foo") String foo,
  2. @RequestHeader("bar") String bar,
  3. @RequestHeader("baz") String baz,

and in each controller method I am creating my custom dto based on those headers:

  1. 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:

  1. @PostMapping("/myEndpoint")
  2. public MyResponse myEndpoint(@RequestHeader("foo") String foo,
  3. @RequestHeader("bar") String bar,
  4. @RequestHeader("baz") String baz,
  5. @RequestBody MyRequest myRequest) {
  6. MyDto myDto = new MyDto(foo, bar, baz);
  7. myService.doSomething(myDto);
  8. ...
  9. }

Expected:

  1. @PostMapping("/myEndpoint")
  2. public MyResponse myEndpoint(MyDto myDto,
  3. @RequestBody MyRequest myRequest) {
  4. myService.doSomething(myDto);
  5. ...
  6. }

I also have a method for it:

  1. public MyDto transform(HttpHeaders httpHeaders) {
  2. String foo = getHeader(httpHeaders, "foo");
  3. String bar = getHeader(httpHeaders, "bar");
  4. String baz = getHeader(httpHeaders, "baz");
  5. return new MyDto(foo, bar, baz);
  6. }
  7. private String getHeader(HttpHeaders httpHeaders,
  8. String key) {
  9. return Optional.ofNullable(httpHeaders.get(key))
  10. .map(Collection::stream)
  11. .orElseGet(Stream::empty)
  12. .findFirst()
  13. .orElse(null);
  14. }

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.

huangapple
  • 本文由 发表于 2020年4月9日 03:27:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/61108515.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定