从 javax.ws.rs.core.Feature 访问 HttpServletContext 或会话

Access to HttpServletContext or session from javax.ws.rs.core.Feature

上下文

我正在迁移一个旧的遗留球衣应用程序以使用更新的版本 (2.27)。

应用程序使用 jetty servlet 处理身份验证并在 HttpSession 中设置登录信息。

然后我们有一些插件使用球衣并从注释 (@SdnUser) 接收身份验证令牌。

应用比较大,想避开认证方式的迁移过程

迁移前

我正在使用链接到提供 AbstractContainerRequestValueFactory 的 AbstractValueFactoryProvider 的抽象活页夹。

这个 AbstractContainerRequestValueFactory 让我可以访问 RessourceContext,我可以在其中获取 HttpSession。

    private static final class IdentityParamValueFactory extends AbstractContainerRequestValueFactory<UserManagement.User> {

        private final UserManagement userManagement;
        @Context
        private ResourceContext context;

        public IdentityParamValueFactory(final UserManagement userManagement) {
            this.userManagement = userManagement;
        }

        public UserManagement.User provide() {
            final HttpServletRequest request = context.getResource(HttpServletRequest.class);
            HttpSession session = request.getSession();
            //... code ommited
    }

现在

我已调整代码以使用功能和抽象活页夹:


public class UserBinder implements Feature {

    private final UserManagement userManagement;

    public UserBinder(final UserManagement userManagement) {
        this.userManagement = userManagement;
    }

    @Override
    public boolean configure(final FeatureContext context) {
        context.register(new AbstractBinder() {

            @Context
            private HttpServletRequest webRequest;

            @Override
            protected void configure() {
                UserValueParamProvider userValueParamProvider = new UserValueParamProvider(userManagement, webRequest);
                bind(userValueParamProvider)
                        .to(ValueParamProvider.class)
                        .in(RequestScoped.class);
            }
        });

        return true;
    }

    public static class UserValueParamProvider implements ValueParamProvider {

        // SLF4J Logger
        private static final Logger LOG = LoggerFactory.getLogger(UserBinder.class);

        private final UserManagement userManagement;

        private HttpServletRequest webRequest;

        private UserValueParamProvider(final UserManagement userManagement, 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 -> {
                    ContainerRequest containerRequest = (ContainerRequest) context.getRequest();
                    // The next line is invalid, as the request is a ContainerRequest not an HttpServletRequest
                    HttpServletRequest request = (HttpServletRequest) context.getRequest();
                    HttpSession session = request.getSession();
// ... code ommited

但是getValueProvider的功能return没有上下文注入,我无法访问HttpSession。

如何访问注释活页夹中的 HttpSession?

注入javax.inject.Provider<HttpServletRequest>。将提供程序传递给 Function 构造函数并在 Funtion#apply() 方法中调用 provider.get()Provider 用于惰性检索。在这种情况下需要使用它,因为启动时没有请求。