我需要使用一个Tracer
请求范围的 bean 来记录跟踪信息,既用于我的 REST 方法,也用于异常处理程序。Tracer
在 REST 方法中,该 bean 被用来在开始处理请求时记录跟踪信息,当发生异常时,我希望在异常处理程序中使用相同的跟踪消息。
但是,我在异常处理程序中访问请求范围的Tracer
bean 时遇到了困难。我尝试了@ExceptionHhandler
REST 控制器中的 rest 控制器注释和 @ControllerAdvice
,但都无法支持对范围 bean 的访问。
这是我的设置:
@RestController
public class MyController {
@Bean
@RequestScope
Tracer tracer(){
return new Tracer();
}
@GetMapping(path = "list")
public String list(Tracer trace){
return trace.getCorrelationId();
}
@GetMapping(path = "throw")
public String throwEx(Tracer trace,HttpServletRequest req){
throw new RuntimeException("Ops");
}
@ExceptionHandler({Exception.class})
ResponseEntity<String> defaultExceptionHandler(Tracer tracer, HttpServletRequest req, Exception ex) {
return ResponseEntity
.internalServerError()
.body("ERROR: " + tracer.getCorrelationId());
}
}
追踪器(为了完整性):
@Getter
public class Tracer {
private final String requestId;
private final String correlationId;
public Tracer() {
requestId = null;
correlationId = UUID.randomUUID().toString();
}
public Tracer(String requestId, String correlationId) {
this.requestId = requestId;
this.correlationId = correlationId;
}
}
这里是测试:
@SpringBootTest
@AutoConfigureMockMvc
class MyControllerTest {
@Autowired
protected MockMvc mockMvc;
@Test
void testExceptionHandler() throws Exception {
mockMvc
.perform(MockMvcRequestBuilders.get("/throw")
)
.andDo(MockMvcResultHandlers.print())
.andReturn()
.getResponse()
.getContentAsString();
}
}
问题如下:
无法解析 org.springframework.http.ResponseEntity<java.lang.String> com.baeldung.scopes.MyController.defaultExceptionHandler(com.baeldung.scopes.Tracer,jakarta.servlet.http.HttpServletRequest,java.lang.Exception) 中的参数 [0]:没有合适的解析器
看来我无法将 Tracer bean 直接注入到异常处理程序方法中。
我是不是漏掉了什么?还有其他方法可以解决这个问题吗?
任何帮助或建议都将不胜感激!
也许很“肮脏”,但至少它有效:
其他解决方案是 ThreadLocal (spring web-mvc 使用每个请求一个线程模型)
Ps:由于我现在没有 IDE,因此请修复编译错误(如果有)
另一种方法。将注释
@RequestScope
和@Component
添加到Tracer
:将其注入您的控制器并删除
trace
方法参数。