【问题标题】:Best way to inject HttpServletResponse into service layer将 HttpServletResponse 注入服务层的最佳方法
【发布时间】:2014-01-10 00:48:59
【问题描述】:

我知道这可能不是解决此类问题的最佳设计,但仅适用于特定要求。

当前应用程序需要ServletContextHttpServletRequestHttpServletResponse 进入服务层以获得customized authentication provider

显然没有任何特定的配置或继承以下代码:

@Component("myAuthenticaionProvider")
public class MyAuthenticaionProvider implements AuthenticationUserDetailsService {
    @Autowired private ServletContext context;
    @Autowired private HttpServletRequest request;
    @Autowired private HttpServletResponse response;
        .......
}

必须抛出异常:

nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [javax.servlet.http.HttpServletResponse] found for dependency:

我能想到的可能解决方案:

  1. 使用过滤器拦截 HttpServletRequest,但这需要 URL 模式,否则会拦截我认为可能存在性能问题的所有 URL?

  2. 在 spring-security.xml 或 application-context.xml 中创建一个 request 范围 bean,然后注入当前的身份验证提供程序类,使其能够获取 HttpServletRequest。但是我觉得这里有问题,如何发起请求范围bean?

那么最好的做法是什么?

【问题讨论】:

  • 你到底想达到什么目的?
  • 这是个坏主意,但在适当的环境中它会起作用。 ((ServletWebRequest) RequestContextHolder.getRequestAttributes()).getResponse();适当的环境是指getRequestAttributes()返回的RequestAttributesServletWebRequest类型的环境。
  • 如果您描述了您想要实现的目标,获得一个好的解决方案的机会会高得多。对我来说,您似乎需要一个过滤器(尤其是因为响应对象),但您不想要那个。所以我真的很想知道谁调用了这项服务以及何时(以及为什么)。

标签: java spring spring-mvc


【解决方案1】:

除了是一个“坏主意”之外,请求对象的寿命与请求一样长。由于生命周期的差异,您不能将其注入单例中。可以通过方法参数传入。

与您的请求最接近的解决方案是在 catch all 过滤器中创建一个 ThreadLocal 变量并将其设置在那里,然后将该过滤器或代理注入到您的服务中的本地线程中。我强烈建议您避免这种情况。

【讨论】:

  • 有趣的是,我发现HttpServletRequest 能够自动连接到服务层。但不确定它是如何启动的。感谢您的建议。
【解决方案2】:

您是否尝试在身份验证提供程序中实现 HttpRequestHandler 接口以及 AuthenticationUserDetailsS​​ervice?

【讨论】:

  • 谢谢,所以使用拦截器是目前最好的选择吗?
  • 我不知道,但是您需要在需要 http servlet 的自定义 authprovider 中实现什么?
猜你喜欢
  • 2020-03-17
  • 1970-01-01
  • 2012-11-12
  • 2014-03-31
  • 1970-01-01
  • 2021-01-04
  • 2020-07-31
  • 2013-12-18
  • 1970-01-01
相关资源
最近更新 更多