目前的程序结构大概是这样的:
// base controller 中定义了异常情况下的 API 返回
public class BaseController {
@ExceptionHandler(CodeMessageException.class)
@ResponseBody
protected ResultModel<Long> exception(CodeMessageException e) {
log.error("{}", e.getMessage(), e);
return new ResultModel<>(e.getCode(), e.getMessage());
}
}
// 有一个 Filter 已经实现了打印 Request / Response Body (通过 Filter 实现了一些全局的处理逻辑)
public class HttpLogFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
...
}
}
// 业务 Controller 继承 BaseController
@Controller
public class DeviceController extends BaseController {
@PostMapping("/device/activate")
@ResponseBody
public ResultModel<Long> activateDevice(@RequestBody ActivateDeviceRequest request) {
return deviceService.activateDevice(request.getSn());
}
// Service 层可以进行必要的参数检查,然后直接抛一个异常出来
// 异常被 BaseController 捕捉,然后转成 JSON,这样代码看上去就很干净
public ResultModel<Long> activateDevice(String sn) {
if (sn == null) {
throw new CodeMessageException(ERROR_PARAM_MISSING, "Parameter sn is missing");
}
...
}
问题来了,现在需要给每个 Request 生成一个 RequestID (UUID),这个 ID 是后端生成的,调用者不需要写对应的代码,但是调用者在 Response 中可以看到这个 Request ID
如何以尽量小的侵入性实现这个特性呢?基本的需求是 Service 层以及 BaseController (异常处理逻辑) 都能够比较简单地取到这个值并返回
同时希望打印 Request (包括 url / body)的时候,也能够把 Request ID 打印出来,否则请求量大的时候,日志还是会对不上
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.