0

重複の可能性:
サーブレットはどのように機能しますか?インスタンス化、セッション変数、マルチスレッド

WebServletで奇妙な(しかしおそらく予想される)動作があります。環境は次のとおりです。
-
Apache2.2.x-Glassfish3.1.1+ mod_jk
-JSF Mojarra 2.1.3

特定の@SessionScopedマネージドBeanがあるかどうか、および存在する場合はユーザーがサインインしているかどうかをFacesContext/Sessionでチェックするコードを実装する抽象サーブレットがあります。ユーザーがサインインしている場合は、ファイルの配信に進みます。@WebServletの実装は、実際のファイルのダウンロードのみを提供します。

抽象サーブレット:

public abstract class SecureDownloadServlet extends HttpServlet {
    @EJB
private UserProductBean userProductBean;
private UserInfoView userInfoView = null;

private UserInfoView getUserInfoView(HttpServletRequest req) {
    FacesContext context = FacesContext.getCurrentInstance();
    if (context != null) {
        userInfoView = (UserInfoView) context.getApplication()
                .getELResolver().getValue(FacesContext.
                getCurrentInstance().getELContext(), null, "userInfoView");
    }
    if (userInfoView == null) {
        userInfoView = (UserInfoView) getServletContext().
                getAttribute("userInfoView");
    }
    if (userInfoView == null) {
        userInfoView = (UserInfoView) req.getSession().
                getAttribute("userInfoView");
    }
    return userInfoView;
}

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response)
       throws IOException, ServletException {
    if (getUserInfoView(req) == null || !getUserInfoView(req).getLoggedIn()) {
        response.sendRedirect("message.xhtml?msg=noLogin");
        return;
    }
    doDownload(req, response);
}


public abstract void doDownload(HttpServletRequest req,
        HttpServletResponse response)
throws IOException, ServletException;

}

次に、上記の抽象HttpServletを拡張し、抽象メソッドを実装する@WebServletがあります。

@WebServlet(name = "SecureImageServlet", urlPatterns = {"/print","/m/print"})
public class SecureImageServlet extends SecureDownloadServlet {

  @Override
  public void doDownload(HttpServletRequest req, HttpServletResponse response)
           throws IOException, ServletException {
        // some code
    }
}

ここで問題
が発生します。-コンピューターAからサインインし、SecureImageServletサーブレットを呼び出してファイルを取得します(つまり、http://www.example.com/print? id = 12345 )。セッションBeanはuserInfoView期待どおりに初期化され、ファイルが配信されます。
-コンピューターBから、サインインせずにhttp://www.example.com/print?id=12345に電話します。はuserInfoViewすでにコンピュータAのユーザーのセッションで初期化されています!!! そして、ファイルも配信されます。

WebServletがApplicationScopeなどになっているようです。それを行うのは@EJBインジェクションですか?のインスタンスがuserInfoView同じであることに注意してください(デバッガーのオブジェクトIDは同じ番号を示しています)。これは、コンピューターBがコンピューターAと同じユーザーとして表示されることを意味します。

編集されたフォーマット

4

1 に答える 1

0

わかりました、私の友人(SOのアカウントなし:))が私の間違いを指摘しました:リクエストスコープ内に保持するのではなく、クラスメンバーとして
使用しています。userInfoViewクラスメンバーを削除して修正しました。

于 2012-10-04T10:47:57.550 に答える