【发布时间】:2019-12-01 19:39:34
【问题描述】:
当一个 Spring bean 被注解为SCOPE_REQUEST 时,它会在 servlet 每次接收到 HTTP 请求时被创建和销毁。如果此 bean 创建失败,则会将服务器错误发送回调用方。
在这个简单的示例中,MyInputs bean 的创建取决于 HTTP 请求的内容。
@Configuration
class ApplicationConfiguration {
@Bean
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyInputs myInputs(HttpServletRequest request) {
String header1 = request.getHeader("header1");
if (header1 == null) {
throw new MyException("header1 is missing");
}
return new MyInputs(header1);
}
}
如果 HTTP 请求不包含必需的标头,则会抛出 BeanCreationException。这被翻译成无用的“500 Internal Server Error”响应。
我想返回一个对用户更友好的响应代码和正文,例如,带有有用消息的“400 Bad Request”。如何自定义此响应翻译?我找不到任何允许这样做的生命周期钩子。
注意:这是请求范围 bean 的使用方式:
@RestController
public class MyController {
private final Provider<MyInputs> myInputsProvider;
@Autowired
public MyController(Provider<MyInputs> myInputsProvider) {
this.myInputsProvider = myInputsProvider;
}
@GetMapping("/do-stuff")
public void doStuff() {
// Get the inputs for the current request
MyInputs myInputs = myInputsProvider.get();
// ...
}
}
【问题讨论】:
-
只需使用响应状态注释您的异常,如下所示:baeldung.com/spring-response-status-exception
-
@beatrice 我确实尝试过.. 问题是 Spring 将所有内容包装到
BeanCreationException中,因此通常的处理程序不会被触发。 -
请说明您如何尝试在请求处理程序中使用
MyInputsbean。 -
也许使用一个拦截器来调用
MyInput.setHeader在检查它是否存在抛出异常之后。这个例外不会被春天包裹起来。看到这样的@Bean函数,我会感到非常惊讶 - bean 构造通常并不例外 -
@SotiriosDelimanolis 添加了一个示例。
标签: java spring rest spring-boot spring-mvc