Jersey 2.27迁移时如何在Feature中访问HttpServletContext或HttpSession
解决方案
你遇到的核心问题是HttpServletRequest属于请求作用域对象,不能在应用启动阶段初始化Binder时就注入并传递给参数Provider,此时还不存在实际请求上下文,拿到的实例必然无效。你可以选择以下两种方案之一实现需求,均不需要改动现有认证逻辑:
方案1:直接从ContainerRequest中提取原生Servlet请求(最简便)
Jersey在Servlet环境运行时,会自动将原生HttpServletRequest存入ContainerRequest的属性中,固定key为ServletProperties.SERVLET_REQUEST,你可以直接在返回的取值函数中提取:
import org.glassfish.jersey.servlet.ServletProperties; // 你的getValueProvider内返回的函数修改为如下逻辑 return context -> { HttpServletRequest request = (HttpServletRequest) context.getProperty(ServletProperties.SERVLET_REQUEST); HttpSession session = request.getSession(); // 此处沿用你原有从session中取用户的逻辑即可 };
方案2:通过请求作用域注入HttpServletRequest
因为你已经将UserValueParamProvider绑定为请求作用域,直接让Jersey自动注入上下文对象即可,不需要在Binder构造时手动传参:
- 调整Binder中的绑定逻辑,不要手动构造Provider实例:
@Override public boolean configure(final FeatureContext context) { context.register(new AbstractBinder() { @Override protected void configure() { // 先绑定全局的UserManagement实例 bind(userManagement).to(UserManagement.class); // 绑定Provider类,让Jersey完成注入 bind(UserValueParamProvider.class) .to(ValueParamProvider.class) .in(RequestScoped.class); } }); return true; }
- 修改
UserValueParamProvider的构造函数,添加注入注解:
public static class UserValueParamProvider implements ValueParamProvider { private final UserManagement userManagement; private final HttpServletRequest webRequest; @Inject public UserValueParamProvider(final UserManagement userManagement, @Context HttpServletRequest webRequest) { this.userManagement = userManagement; this.webRequest = webRequest; } @Override public Function<ContainerRequest, UserManagement.User> getValueProvider(final Parameter parameter) { if (parameter.getRawType().equals(UserManagement.User.class) && parameter.isAnnotationPresent(SdnUser.class)) { return context -> { // 直接使用注入的webRequest取session即可 HttpSession session = webRequest.getSession(); // 原有逻辑 }; } return null; } }
内容的提问来源于stack exchange,提问作者Manticore
相关产品推荐
相关产品推荐

