在过滤器中为Spring Controller / Service Class中的每个请求访问数据

时间:2017-07-11 12:21:34

标签: spring spring-mvc

在我们的申请中,所有其他的api都是以下形式:

  

的http:// {上下文} / {PRODUCT_ID} / {rest_url_path}

我必须通过从DB为product_id提取ProductDetails来验证Spring Security Filter / SpringMVC拦截器中的{product_id}。 ProductDetails将在Spring Controllers / Service类中使用。

我不想在控制器/服务中再次获取ProductDetails。所以我想将ProductDetails对象存储在RequestScope的某个位置。

我有三种方法。但每个人都有自己的优点和缺点。请让我知道哪一个更好。另外建议任何替代方法。

方法-1:

ProductDetails对象保存在请求属性中。 在控制器内部,我可以轻松获得HttpRequest。在内部服务中,我可以通过以下方式获取HttpRequest

@Autowired
HttpServletRequest request;

RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = null;
if (attribs instanceof ServletRequestAttributes) {
    request = ((ServletRequestAttributes) attribs).getRequest();
}

但我不想在Service中使用HTTP请求依赖,以使代码更加独立于WebLayer逻辑。

方法-2:

使用基于product_id的任何内存缓存来存储ProductDetails

但是我认为这只是针对这个用例的过度杀戮。增加缓存的不必要依赖性。

方法-3:

将Object存储在ThreadLocal变量中以存储请求范围数据。 但不确定这是否正确。

让我知道解决这个问题的有效方法

2 个答案:

答案 0 :(得分:1)

第1和第3个适用于您的问题陈述,但第一个更优雅,因为数据仅存储在当前请求范围内,并且在服务器发送响应时将自动丢失。你也可以使用threadLocal但你必须小心,如果你忘记删除它将在使用线程池的环境中闲逛。

答案 1 :(得分:0)

您提到的第一种方法是更有效地访问过滤器和控制器中的相同数据,即使您必须在SpringController中注入HttpservletRequest的依赖项。

如果数据非常特定于用户,那么在这种情况下,其他用户将无法访问这些数据,您应该使用ThreadLocal。