当前位置: 首页 > 知识库问答 >
问题:

在筛选器中注入SessionScoped CDIBean-不为不同会话重新注入?

文国发
2023-03-14

我有这个问题,我不确定这是否是“预期”行为,但我的问题是:

我有一个Http筛选器:

@WebFilter(filterName = "VerificationFilter", urlPatterns = {"/activation/*"})
public class VerificationFilter implements Filter {
    private static final Logger logger = LoggerFactory.getLogger(VerificationFilter.class);
    private static final String ACTIVATION_CODE_PARAM_KEY = "vc";
    @Inject
    private UserInfo userInfo;
    @Inject
    private ActivationInfo activationInfo;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        logger.debug("************VerificatoniFilter initializing*************");
    }

    /**
     * This filter filters requests by path - anything in the /activate/ namespace will
     * be filtered to first determine if the user has already passed through this filter once.
     * If the user has been "filtered" and the validation code was deemed to be valid, navigation will
     * be permitted to pass through.  If not, then they will be redirected to an error page
     * 
     *  If the user has not yet been filtered, (determined by the presence of details available in the user's
     *  current session), then the filter will check the validation code for validity and/or allow or reject
     *  access.
     *
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (!activationInfoPopulated()) {
            String activationCode = request.getParameter(ACTIVATION_CODE_PARAM_KEY);
            if (StringUtils.isEmpty(activationCode)) {
                throwActivationInvalid();
            } else {
                try {
                    ActivationService aService = new ActivationService();
                    ClPersonInfo info = aService.findActivationCodeUser(activationCode);
                    if (info == null) {
                        throwActivationInvalid();
                    }
                    userInfo.setClPersonInfo(info);
                    setActivationInfoPopulated();
                    setActivationValid();
                } catch (ServiceUnavailableException sue) {
                    throw new IamwebApplicationException(sue.getMessage());
                } 
            }
        } else {
            // if the validationCode is not valid, send the user directly to error page.  Else, continue...
            if (!activationInfo.getValidationCodeIsValid()) {
                throw new ActivationCodeInvalidException();
            } 
        }
        // if all is good, continue along the chain
        chain.doFilter(request, response);
    }

    private boolean activationInfoPopulated() {
        return (activationInfo.getValidationCodeChecked());
    }

    private void setActivationInfoPopulated() {
        activationInfo.setValidationCodeChecked(Boolean.TRUE);
    }

    private void setActivationValid() {
        activationInfo.setValidationCodeIsValid(Boolean.TRUE);
    }

    private void setActivationInvalid() {
        activationInfo.setValidationCodeIsValid(Boolean.FALSE);
    }

    private void throwActivationInvalid() throws ActivationCodeInvalidException {
        setActivationInfoPopulated();
        setActivationInvalid();
        throw new ActivationCodeInvalidException();
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    /**
     * @return the activationInfo
     */
    public ActivationInfo getActivationInfo() {
        return activationInfo;
    }

    /**
     * @param activationInfo the activationInfo to set
     */
    public void setActivationInfo(ActivationInfo activationInfo) {
        this.activationInfo = activationInfo;
    }

    /**
     * @return the userInfo
     */
    public UserInfo getUserInfo() {
        return userInfo;
    }

    /**
     * @param userInfo the userInfo to set
     */
    public void setUserInfo(UserInfo userInfo) {
        this.userInfo = userInfo;
    }   
}

UserInfo和ActivationInfo都是@SessionScope,如下所示:

@Named("activationInfo")
@SessionScoped
public class ActivationInfo implements Serializable {
    private static final Logger logger = LoggerFactory.getLogger(ActivationInfo.class);
    private static final long serialVersionUID = -6864025809061343463L;
    private Boolean validationCodeChecked = Boolean.FALSE;
    private Boolean validationCodeIsValid = Boolean.FALSE;
    private String validationCode;

    @PostConstruct
    public void init() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext().getSession(true);
        logger.debug("ActivationInfo being constructed for sessionId:  " + (session == null ? " no session found " : session.getId()));
    }

@Named("userInfo")
@SessionScoped
public class UserInfo implements Serializable {
    private static final Logger logger = LoggerFactory.getLogger(UserInfo.class);
    private static final long serialVersionUID = -2137005372571322818L;
    private ClPersonInfo clPersonInfo;
    private String password;

    /**
     * @return the clPersonInfo
     */
    public ClPersonInfo getClPersonInfo() {
        return clPersonInfo;
    }

    @PostConstruct
    public void init() {
        FacesContext context = FacesContext.getCurrentInstance();
        HttpSession session = (HttpSession) context.getExternalContext().getSession(true);
        logger.debug("UserInfo being constructed for sessionId:  " + (session == null ? " no session found" : session.getId()));
    }

当我尝试访问调用过滤器的页面时,我在控制台上看到以下内容:

2014-02-20 21:32:22 DEBUG UserInfo:35 - UserInfo being constructed for sessionId:   no session found
2014-02-20 21:32:22 DEBUG ActivationInfo:27 - ActivationInfo being constructed for sessionId:   no session found 
2014-02-20 21:32:22 DEBUG VerificationFilter:38 - ************VerificatoniFilter initializing*************

如果我转到不同的浏览器并输入“坏”校验码,用户信息/激活信息永远不会重新注入。IE,与不同的会话,我没有看到一个新的UserInfo/ActivationInfo.

我的问题是:1。为什么在构造UserInfo/ActivationInfo时找不到会话(请参阅日志消息)2。我如何实现这一点,以便稍后可以将UserInfo和ActivationInfo注入到我的其他cdibean中,以便它们拥有我需要的user/ActivationInfo?目前由于这个问题,我在VerificationFilter中直接在用户的会话上设置activationInfo,但是当我注入我的CDIBean时,会注入不同的UserInfo和activationInfo。

我正在使用Tomcat7和JEE6,WELD。

提前谢谢!

共有1个答案

孔梓
2023-03-14

如果您使用的是Tomcat 7,那么您没有完整的JavaEE 6容器,因此默认情况下JSF和CDI不可用,并且不清楚您是如何设置它们的。

实际上,我希望context.getExtranalContext()在会话范围的bean中抛出一个NullPointerExcture,因为当过滤器调用bean方法时没有FacesContext

FacesServlet有机会设置FacesContext之前调用过滤器。

因此,你的问题似乎是基于不清楚和/或不正确的假设。

 类似资料:
  • 8.3. 会话注入 一个与会话暴露类似的问题是会话注入。此类攻击是基于你的WEB服务器除了对会话存储目录有读取权限外,还有写入权限。因此,存在着编写一段允许其他用户添加,编辑或删除会话的脚本的可能。下例显示了一个允许用户方便地编辑已存在的会话数据的HTML表单: <?php session_start(); ?> <form action="inject.php" method="POST"> <

  • 我使用了著名的Dagger ViewModelFactory模式,以便能够为所有活动中的所有视图模型注入工厂。 我遇到的问题是,当我将工厂注入到匕首时失败了,因为我不打算使用的对象的提供者并不总是可访问的。他们不是因为包含提供者的模块没有添加。 例如,我有一个LogIn活动和一个SignUp活动,这是我为它们添加子组件的方式: 请注意,当我为SignUpActivity创建子组件时,我没有添加模块

  • 问题内容: 我使用SpringBeanAutowiringSupport在某些对象中进行bean注入。问题是,在jUnit测试中无法注入bean。为了进行测试,使用了SpringJUnit4ClassRunner。 有谁知道,为什么使用注入在jUnit测试中不起作用? 问题答案: 感谢M. Denium的帮助,他的解决方案得以奏效。

  • 我正在尝试使用Guice 3.0,它不会实例化工厂。 SSCCE代码: < code>BarImpl与< code>FooImpl非常相似。这里出了什么问题?还要注意,我在这里尝试了< code>@AssistedInject和< code>@Inject,两者都会导致错误。 输出: 请注意,第 9 行是对 的第一次调用的行

  • 我正在开发一个现有的Java代码库,该代码库使用Guice进行依赖注入。我有一个新的类 Foo,其中包含一个我想注入的成员字段(bar)。喜欢这个: 然而,有两件事: 使用Foo的注射器无法直接进入 客户端希望使用“new”创建Foo 当客户端执行以下操作时,是否仍然可以将Bar注入Foo对象: 我对DI和Guice非常陌生,不太明白如何在不调用injector.createInstance()的