gpt4 book ai didi

java - 如何装饰所有请求以从 header 中取值并将其添加到正文参数中?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:52:51 24 4
gpt4 key购买 nike

背景

我正在使用 Spring MVC 创建 RESTful 服务。目前,我有以下 Controller 结构:

@RestController
@RequestMapping(path = "myEntity", produces="application/json; charset=UTF-8")
public class MyEntityController {

@RequestMapping(path={ "", "/"} , method=RequestMethod.POST)
public ResponseEntity<MyEntity> createMyEntity(
@RequestBody MyEntity myEntity,
@RequestHeader("X-Client-Name") String clientName) {
myEntity.setClientName(clientName);
//rest of method declaration...
}

@RequestMapping(path={ "/{id}"} , method=RequestMethod.PUT)
public ResponseEntity<MyEntity> updateMyEntity(
@PathVariable Long id,
@RequestBody MyEntity myEntity,
@RequestHeader("X-Client-Name") String clientName) {
myEntity.setClientName(clientName);
//rest of method declaration...
}

@RequestMapping(path={ "/{id}"} , method=RequestMethod.PATCH)
public ResponseEntity<MyEntity> partialUpdateMyEntity(
@PathVariable Long id,
@RequestBody MyEntity myEntity,
@RequestHeader("X-Client-Name") String clientName) {
myEntity.setClientName(clientName);
//rest of method declaration...
}
}

如您所见,所有这三种方法都为 header @RequestHeader("X-Client-Name") String clientName 接收相同的参数,并以相同的方式将其应用于每个方法: myEntity.setClientName(clientName)。我将创建类似的 Controller ,对于 POST、PUT 和 PATCH 操作,将包含几乎相同的代码,但用于其他实体。目前,大多数实体都设计为通过父类(super class)支持此字段:

public class Entity {
protected String clientName;
//getters and setters ...
}
public class MyEntity extends Entity {
//...
}

此外,我使用拦截器来验证是否为请求设置了 header 。

问题

如何避免通过 Controller 类和方法重复相同的代码?有没有一种干净的方法来实现它?还是我应该声明变量并在各处重复这些行?

西类牙社区也有人问过这个问题。这是 the link .

最佳答案

我的建议是将 header 值存储在 Spring 拦截器或过滤器内的请求作用域 bean 中。然后你可以在任何你想要的地方 Autowiring 这个 bean - 服务或 Controller 并使用存储的客户端名称值。

代码示例:

public class ClientRequestInterceptor extends HandlerInterceptorAdapter {

private Entity clientEntity;

public ClientRequestInterceptor(Entity clientEntity) {
this.clientEntity = clientEntity;
}

@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
String clientName = request.getHeader("X-Client-Name");
clientEntity.setClientName(clientName);
return true;
}
}

在你的配置文件中:

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(clientRequestInterceptor());
}

@Bean(name="clientEntity")
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Entity clientEntity() {
return new Entity();
}

@Bean
public ClientRequestInterceptor clientRequestInterceptor() {
return new ClientRequestInterceptor(clientEntity());
}

}

然后,假设我们必须在我们的 Controller 中使用这个 bean:

@RestController
@RequestMapping(path = "myEntity", produces="application/json; charset=UTF-8")
public class MyEntityController {

@Autowired
private Entity clientEntity; // here you have the filled bean

@RequestMapping(path={ "", "/"} , method=RequestMethod.POST)
public ResponseEntity<MyEntity> createMyEntity(@RequestBody MyEntity myEntity) {
myEntity.setClientName(clientEntity.getClientName());
//rest of method declaration...
}
// rest of your class methods, without @RequestHeader parameters

}

我没有编译这段代码,如果有错误请指正。

关于java - 如何装饰所有请求以从 header 中取值并将其添加到正文参数中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36295095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com