我有一个场景,我需要在每个Web请求开始时运行一些db检查,并且在成功的情况下我需要存储对象以供控制器稍后在请求中使用,或者在失败我需要渲染错误页面。
一个非常类似的现实世界的例子是SaaS应用程序根据虚荣网址检查和加载帐户,然后存储帐户供控制器使用以避免多个数据库请求。
在Spring启动应用中实现此目的的最佳方法是什么?我已经尝试了过滤器,但我认为拦截器可能在任务上更好,包括运行检查但是如何存储对象供以后使用?是否存在某种我可以存储的请求生命周期上下文?
答案 0 :(得分:1)
Spring supports request
scope for beans。您可以使用它们来存储请求执行期间使用的数据。
答案 1 :(得分:1)
根据我的经验,我做过类似工作的最好方法是HandlerMethodArgumentResolver
。
基本上假设您有自定义类型,我们将其称为UserContext
,您可以在其中存储请求所需的信息。你有一个UserContextService
让我们说它有一个方法getUserContext(HttServletRequest)
,它用于根据请求检索上下文,你可以根据请求参数调用你的数据库/ header / path-variable等。您可以根据需要进行优化。但基于这个简单的假设,您可以拥有一个如下所示的控制器:
@RequestMapping("/some/url")
public SomeResponse someMethod(UserContext userContext, ...) {
//do something here with UserContext
}
Spring会将此UserContext注入您的控制器的方式是使用这样的自定义HandlerMethodArgumentResolver
:
@Component
public class UserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
UserContextService
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(UserContext.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest req = (HttpServletRequest)webRequest.getNativeRequest();
UserContext userContext = userContextService.getUserContext(req);
if (userContext != null) {
return userContext;
} else {
return WebArgumentResolver.UNRESOLVED;
//Or throw exception
}
}
}
您将通过覆盖WebMvcConfigurer.addArgumentResolvers
bean / config-class中的WebMvcConfigurer
方法进行注册。
此机制与@PathVariable
,@RequestParam
等使用的机制相同......