2014-02-21 2 views
2

У меня есть этот вопрос, и я не уверен, если это «ожидается» поведение, но вот моя проблема:SessionScoped cdi bean, введенный в фильтр, - не повторно вводить для разных сеансов?

У меня есть 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 являются как @SessionScoped следующим образом:

@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************* 

И если я иду на другой браузер и введите «плохой» код подтверждения, UserInfo/ActivationInfo является никогда не вводили повторно. IE, с другим сеансом, я НЕ вижу новую UserInfo/ActivationInfo.

Мои вопросы: 1. Почему там нет сессии найден, когда UserInfo/ActivationInfo строятся (см лог сообщений) 2. Как я могу осуществить это так, что UserInfo и ActivationInfo может быть введен в моей другие CDI-бобы позже, чтобы у них был пользователь/activInfo, который мне нужен? В настоящее время из-за этой проблемы я устанавливаю activInfo непосредственно на сеанс пользователя в VerificationFilter, но когда я вставляю свой бин CDI, вводится РАЗЛИЧНАЯ UserInfo и DIFFERENT ActivationInfo.

Я использую Tomcat 7 с JEE 6, WELD.

Заранее благодарен!

ответ

0

Если вы используете Tomcat 7, то у вас нет полного контейнера Java EE 6, поэтому JSF и CDI по умолчанию недоступны, и непонятно, как вы их настроили.

На самом деле, я бы ожидать context.getExternalContext() бросить в вашем контексте сеанса фасоли в NullPointerException, так как нет FacesContext, когда методы боба называют фильтром.

Фильтр вызывается перед тем, как FacesServlet имел возможность установить FacesContext.

Итак, ваш вопрос основан на неясных и/или неправильных предположениях.

+0

Фактически, вполне возможно использовать JSF и CDI с tomcat 7 - путем включения необходимых библиотек и настройки web.xml с помощью facesServlet. Это было сделано много раз. Моя проблема в том, что для SAME HttpSession я каждый раз получаю новые экземпляры bean-компонента @SessionScoped CDI. Боб создается и вводится, он просто дает мне совершенно новый каждый раз, хотя мой сеанс все тот же ...! Не уверен, почему это произойдет – Nena

+0

После проверки [this] (http://stackoverflow.com/questions/16796320/cdi-bean-constructor-and-postconstruct-called-multiple-times) сообщения, я поставил диагноз проблемы. Оказывается, мой импорт был неправильным. Мне нужно: 'javax.enterprise.context.SessionScoped' вместо' javax.faces.bean.SessionScoped' – Nena

Смежные вопросы