3

これが私のセッション Bean です。任意のサーブレットまたはフィルターからいつでも currentUser を取得できます。それは問題ではありません 問題は fileList と currentFile です。単純な int と String でテストしたところ、同じ効果が得られました。ビュー スコープ Bean から値を設定すると、別のクラスからデータを取得できます。

@ManagedBean(name = "userSessionBean")
@SessionScoped
public class UserSessionBean implements Serializable, HttpSessionBindingListener {

    final Logger logger = LoggerFactory.getLogger(UserSessionBean.class);

    @Inject
    private User currentUser;

    @EJB
    UserService userService;

    private List<File> fileList;   

    private File currentFile;

    public UserSessionBean() {

        fileList = new ArrayList<File>();
        currentFile = new File("");
    }

    @PostConstruct
    public void onLoad() {

        Principal principal = FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();
        String email = principal.getName();

        if (email != null) {
            currentUser = userService.findUserbyEmail(email);
        } else {

            logger.error("Couldn't find user information from login!");
        }
    }

ここに例があります。

私のビュースコープのBean。こんな風に飾られています。

 @ManagedBean
 @ViewScoped
 public class ViewLines implements Serializable {

    @Inject
    private UserSessionBean userSessionBean; 

今コード。

    userSessionBean.setCurrentFile(file);
    System.out.println("UserSessionBean : " + userSessionBean.getCurrentFile().getName());

現在のファイル名がバッチリ見えます。これは、実際には jsf アクション メソッドから出力されています。したがって、明らかに currentFile が設定されています。

今、私がこれを行う場合。

@WebFilter(value = "/Download")
public class FileFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {        
        HttpSession session = ((HttpServletRequest) request).getSession(false);
        UserSessionBean userSessionBean = (UserSessionBean) session.getAttribute("userSessionBean");       

        System.out.println(userSessionBean.getCurrentUser().getUserId()); //works

        System.out.println("File filter" + userSessionBean.getCurrentFile().getName()); //doesn't work


        chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}

currentUser は正常に表示されますが、ファイルが表示されません。それはちょうど空白です。String や int などでも同じことが起こります。

これについてあなたが提供できる助けをありがとう。

INFO: UserSessionBean : Line 3B--8531268875812004316.csv (ビュー スコープ Bean から出力された値)

情報: ファイル フィルター tester.csv (フィルターの実行時に出力される値)

**編集**

これはうまくいきました。

 FacesContext context = FacesContext.getCurrentInstance();
    userSessionBean = (UserSessionBean) context.getApplication().evaluateExpressionGet(context, "#{userSessionBean}", UserSessionBean.class);

これをViewScopedのコンストラクターに入れましたが、すべて問題ありませんでした。では、なぜインジェクトが私が思っていたように機能しないのですか? 最初は、新しい CDI Bean の代わりに JSF マネージド Bean を使用していたのではないかと考えました。しかし、Bean を新しいスタイル (名前付き) に変更しましたが、それは同じ効果でした。

インジェクトは Bean へのアクセスのみを許可し、それらの属性を変更することはできませんか?

4

2 に答える 2

5

JSFとCDIを混合しています。あなたUserSessionBeanはJSF@ManagedBeanですが、CDI@Injectを使用して別のBeanに注入しています。CDIは、JSFが管理するものを再利用せず、代わりに新しいものを作成します。両方ではなく、どちらか一方を使用してください。JSF管理対象Beanを注入するための正しいアノテーションは@ManagedPropertyです。

交換

@Inject
private UserSessionBean userSessionBean; 

@ManagedProperty(value="#{userSessionBean}")
private UserSessionBean userSessionBean; 

import javax.enterprise.contextまた、コード(CDIアノテーションのパッケージ)のどこにも存在しないことを確認してください。

または、すべてのJSFBean管理アノテーションをCDIBean管理アノテーションに移行します。

import javax.inject.Named;
import javax.enterprise.context.SessionScoped;

@Named
@SessionScoped
public class UserSessionBean implements Serializable {}

import javax.inject.Named;
import javax.faces.view.ViewScoped;

@Named
@ViewScoped
public class ViewLines implements Serializable {}

追加の利点は、@Injectリクエスト/セッション/アプリケーション属性として手動で取得する必要なしに、通常のサーブレットまたはフィルター内でそれを実行できることです。

さらに、JSF Bean管理アノテーションは、JSF2.3以降非推奨になりました。バッキングBean(@ManagedBean)またはCDI Bean(@Named)?も参照してください。

于 2011-03-15T13:12:08.740 に答える
0

なぜこれが起こっているのかについての私の最善の推測は、変数ファイルがビュースコープに設定されており、参照によってセッションスコープの Bean に渡されているためです。これは、ビュー スコープ Bean が破棄されたときに、その変数への参照がまだ残っているが、保持する必要があるセッション スコープ内に他の参照があるかどうかを気にしないために発生している可能性があります。したがって、破棄されると、この場合はビューとセッションの両方のスコープから削除されます。

「new」でインスタンス化されたオブジェクトで setCurrentFile を呼び出してみてください。それは私のこの仮説を証明または反証するかもしれません.

それ以外の場合は、デバッガーをクラックして開き、getCurrentFile が変更されている場所を正確に確認することをお勧めします。

于 2011-03-14T19:32:55.100 に答える