【发布时间】:2019-07-30 13:44:34
【问题描述】:
我有一项服务需要读取特殊的 http 查询参数。因此我必须以某种方式访问当前的HttpServletRequest。由于我无法将请求作为参数传递,我必须以某种方式注入或读取它。
有两种可能:要么从RequestContextHolder获取请求,要么直接注入HttpServletRequest。什么是正确的?或者也许还有第三种选择?
@Service
public class MyUserDetailsService implements UserDetailsService {
//TODO is that correct? scope?
@Autowired
private HttpServletRequest req;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
req.getParameter("myparam");
}
}
那是线程安全的吗,因为MyUserDetailsService 显然是单例的,而HttpServletRequest 应该是@RequestScope?
【问题讨论】:
-
为什么不读取控制器中的查询参数并通过服务传递它?
-
因为
UserDetailsService是一个spring 类,因此我无法更改方法signatnure,因为它同样被内部spring 服务调用。 -
public UserDetails loadUserByUsername(String username, HttpServletRequest request) throws UsernameNotFoundException -
不要...您现在已经将您的服务层绑定到您的 Web 层...而依赖关系应该是相反的。你需要这个参数是为了什么?看起来您使用了错误的组件(
UserdetailsService来实现某些目标)。话虽这么说,它会起作用吗,是的,它会起作用,因为HttpServletRequest是当前执行线程请求的实际代理,因此被隔离了。你应该这样做,不,你不应该这样做。 -
@M.Deinum 我正在用两个
AuthenticationProvider配置AuthenticationManagerBuilder。一种用于数据库查找,另一种用于旧文件查找。每个提供者都是一个DaoAuthenticationProvider,它使用自定义UserDetailsService,这是我从数据库或遗留文件中获取用户的策略。但在遗留服务查找的情况下,我需要查询中的附加参数来支持遗留查找。这就是为什么我必须访问HttpServletRequest,并且不能将其作为参数传递。
标签: java spring spring-mvc