我有一组用 java 编写的 rest 控制器。最初的要求是为某些端点添加一些标头,但是我们决定在几乎所有 rest 控制器中添加这些标头字段。现在该项目包含 100 多个类似的 api:
@getmapping("/products/{comp}")
public responseentity> getallproducts(
@requestheader(user_hdr) string user,
@requestheader(guid_hdr) string guid,
@requestheader(value = caller_hdr, required = false) string caller,
@requestheader(value = lang_hdr, required = false) string language,
@pathvariable @notnull integer comp
) {
return responseentity.ok(service.get(comp, productutils.processheaders(user,guid,caller,language)));
}
@getmapping("/products")
public responseentity> getallproducts(
@requestheader(user_hdr) string user,
@requestheader(guid_hdr) string guid,
@requestheader(value = caller_hdr, required = false) string caller,
@requestheader(value = lang_hdr, required = false) string language
) {
return responseentity.ok(service.getallrecords(productutils.processheaders(user,guid,caller,language)));
}
从代码中可以明显看出,元组用户、guid、调用者、语言在源代码中无处不在,但是,如何重构并将代码放在“一个地方”或尝试使其更丰富,这不是很明显吗?可维护。例如,如果我们需要添加第 5 个参数,则需要使用 100 个 api。
在 java spring boot 中执行此操作的规范方法是什么?
理想情况下,我想要这样的东西:
@GetMapping("/products/{comp}")
public ResponseEntity> getAllProducts(
"common handling"
@PathVariable @NotNull Integer comp
) {
return ResponseEntity.ok(service.get(comp, ProductUtils.processHeaders(user,guid,caller,language)));
}
@GetMapping("/products")
public ResponseEntity> getAllProducts(
"common handling"
) {
return ResponseEntity.ok(service.getAllRecords(ProductUtils.processHeaders(user,guid,caller,language)));
}
有什么想法吗?控制器建议?还有别的吗?
立即学习“Java免费学习笔记(深入)”;
正确答案
为了解决代码重复问题并使代码在 spring boot 应用程序中更易于维护,您可以创建一个自定义过滤器来在公共标头到达控制器之前提取和处理它们。另外,您还可以将头参数封装成对象,以增强代码的可读性和可维护性。
总之,通过创建 requestheaders dto、实现 customheaderfilter 并将其注册到 filterregistrationbean 来集中标头处理,以在 spring boot 控制器中统一应用通用标头。
以下是建议的方法:
-
创建标头 dto(数据传输对象):
定义一个表示公共标头参数的类。此类将保存从标头中提取的值。
创想商务B2B网站管理系统下载本次升级更新内容:优化分类置顶功能处理机制;修复域名变化带来的cookie域问题;文件上传js的兼容ie9,ie10问题;更新内容编辑器版本;会员服务权限新增求购信息的发布总量限制,求购信息的每日发布量限制;新增供应信息的每日发布量限制;新增分类信息的审核机制控制;新增分类信息的每日发布量限制;新增分类信息的重发刷新功能;优化会员中心的服务类型内容;优化模板运行处理机制;优化会员商铺模板运行机制;
public class requestheaders { private string user; private string guid; private string caller; private string language; // getters and setters } -
创建过滤器:
实现过滤器来拦截传入请求并提取公共标头,然后将它们存储在请求属性中。
import org.springframework.web.filter.onceperrequestfilter; import javax.servlet.filterchain; import javax.servlet.servletexception; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import java.io.ioexception; public class customheaderfilter extends onceperrequestfilter { @override protected void dofilterinternal(httpservletrequest request, httpservletresponse response, filterchain filterchain) throws servletexception, ioexception { requestheaders headers = new requestheaders(); headers.setuser(request.getheader("user")); headers.setguid(request.getheader("guid")); headers.setcaller(request.getheader("caller")); headers.setlanguage(request.getheader("language")); request.setattribute("requestheaders", headers); filterchain.dofilter(request, response); } } -
使用 filterregistrationbean 注册过滤器:
在主应用程序类中使用
filterregistrationbean注册自定义过滤器。import org.springframework.boot.web.servlet.filterregistrationbean; import org.springframework.context.annotation.bean; import org.springframework.context.annotation.configuration; @configuration public class webconfig { @bean public filterregistrationbeancustomheaderfilter() { filterregistrationbean registrationbean = new filterregistrationbean<>(); registrationbean.setfilter(new customheaderfilter()); registrationbean.addurlpatterns("/api/*"); // adjust the url pattern as needed return registrationbean; } } 自定义
addurlpatterns方法以匹配您希望应用过滤器的 url。 -
修改控制器以使用 dto:
修改您的控制器以使用
requestheadersdto 而不是单独的标头参数。@GetMapping("/products/{comp}") public ResponseEntity- > getAllProducts(@PathVariable @NotNull Integer comp,
@ModelAttribute("requestHeaders") RequestHeaders headers) {
return ResponseEntity.ok(service.get(comp, headers));
}
@GetMapping("/products")
public ResponseEntity
- > getAllProducts(@ModelAttribute("requestHeaders") RequestHeaders headers) {
return ResponseEntity.ok(service.getAllRecords(headers));
}
现在,如果您需要添加新的标头参数或进行更改,您只需更新 requestheaders 类和过滤器逻辑。这种方法集中了标头处理并增强了可维护性。










