web-dev-qa-db-ja.com

struts2アプリケーションのセッション

ユーザーセッションが存在する場合はセッションを維持する必要なWebアプリケーションを作成しました。その後、ユーザーがjspを表示できるようになります。

以前にjspサーブレットを使用したことがありますが、struts2は初めてです。

ここに私は私のアクションクラスにユーザー名を設定する

改訂コード

private HttpSession session;

public void setSession(HttpSession session) {
    // TODO Auto-generated method stub0
    this.session = session;
}

public HttpSession getSession() {
    return session;
}

public String getLoginStatus(){     
    session = request.getSession();
    session.setAttribute("userName", loginBean.getUsername());
    return SUCCESS;
}

これで、アクションの後に次のページにリダイレクトされると、セッション値が1回表示されます。その後、すべてのページで、セッションでnull値が見つかりました。

<%
    String userName = (String)session.getAttribute("userName");             
    System.out.println(userName);                        

    if(userName == null || userName.equals("") ){
        response.sendRedirect("login.jsp");
    }

%>

アクションクラスセッションの範囲が1ページに制限されていることをどこかで読みましたが、どうすればこの問題を解決できますか?

どんな例でも私には非常に役立ちます。

11

あなたが現在持っているコードにはいくつかの問題があります。

  • インターセプターを使用して、JSPで強制するのではなく、ユーザーがログインしていることを強制する必要があります。 JSPは、フロー制御ではなく、プレゼンテーション専用にする必要があります。
  • JSPではスクリプトレット(コードのブロック)を避ける必要があります。これは非常に昔に非推奨になり、MVCアプリケーションでは非常に貧弱な方法であると広く考えられています。
  • JSPのセッション値に直接アクセスできます。アクション自体の内部のセッションにアクセスする必要がない限り、アクションにSessionAwareインターフェースを実装する必要はありません。
  • ユーザーをJSPページに直接ではなく、ログインアクションにリダイレクトする必要があります。そうしないと、Struts2フレームワークをバイパスして、フレームワークを使用する利点を失うことになります。

ログイン例

以下は、Struts2フレームワークを使用して基本的なログインシステムを作成するためのサンプルコードです。

ログインが必要です

この部分はオプションですが、一般に、Webアプリケーションのすべてのページでユーザーがログインする必要があるわけではありません。したがって、LoginRequiredというインターフェイスを作成しましょう。ユーザーがまだログインしていない場合、このマーカーインターフェイスを実装するアクションはすべてログインページにリダイレクトされます。

注:必要に応じて、代わりに注釈を使用できますが、この例ではインターフェイスを使用します。

public interface LoginRequired {}

インターセプター

インターセプターは、LoginRequiredインターフェースを実装する要求されたアクションに対してユーザーにログインを強制することを処理します。

public class LoginInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(final ActionInvocation invocation) throws Exception {
        Map<String, Object> session = ActionContext.getContext().getSession();

        // sb: feel free to change this to some other type of an object which
        // represents that the user is logged in. for this example, I am using
        // an integer which would probably represent a primary key that I would
        // look the user up by with Hibernate or some other mechanism.
        Integer userId = (Integer) session.get("userId");

        // sb: if the user is already signed-in, then let the request through.
        if (userId != null) {
            return invocation.invoke();
        }

        Object action = invocation.getAction();

        // sb: if the action doesn't require sign-in, then let it through.
        if (!(action instanceof LoginRequired)) {
            return invocation.invoke();
        }

        // sb: if this request does require login and the current action is
        // not the login action, then redirect the user
        if (!(action instanceof LoginAction)) {
            return "loginRedirect";
        }

        // sb: they either requested the login page or are submitting their
        // login now, let it through
        return invocation.invoke();
    }
}

また、ログインページを表示および処理するLoginActionと、セッションを無効化またはクリアするLogoutActionも必要です。

構成

インターセプターをスタックに追加し、「loginRedirect」のグローバル結果マッピングを作成する必要があります。

<interceptors>
    <interceptor name="login" class="your.package.LoginInterceptor"/>

    <!-- sb: you need to configure all of your interceptors here. i'm only
         listing the one we created for this example. -->
    <interceptor-stack name="yourStack">
        ...
        <interceptor-ref name="login"/>
        ...
    </interceptor-stack>
</interceptors>

<global-results>
    <!-- sb: make this the path to your login action.
         this could also be a redirectAction type. -->
    <result name="loginRedirect" type="redirect">/login</url>
</global-results>
36
Steven Benitez

セッションを維持するには、アクションクラスでSessionAwareインターフェイスを使用し、intpublic void setSession(Map m)属性をマップ内のキーと値のペアとして受け取ります。これは、キーを取得するだけでどこからでもアクセスできます。

たとえばアクションクラス

import org.Apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;

public class LogingEx extends ActionSupport implements SessionAware{
    private static final long serialVersionUID = 1L;

    private String stuname,stuage,country;
    private int stumarks;
    Map m;

    public String getStuname() {
        return stuname;
    }
    public void setStuname(String stuname) {
        this.stuname = stuname;
    }

    public String getStuage() {
        return stuage;
    }
    public void setStuage(String stuage) {
        this.stuage = stuage;
    }

    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }

    public int getStumarks() {
        return stumarks;
    }
    public void setStumarks(int stumarks) {
        this.stumarks = stumarks;
    }

    public void setSession(Map m)
    {
        this.m=m;
    }

    public String execute()
    {
        m.put("a",stuname);
        m.put("b", stuage);
        m.put("c",stumarks);
        m.put("d",country);

        return SUCCESS;
    }

}

出典: http://www.Java4s.com/struts-tutorials/example-on-struts-2-sessionaware-interface/

6
Arvind

この種のMapを使用してユーザーを認証する理由はありません。要件がセッションに対してユーザーを検証することだけである場合は、クラス内の一部のマップよりもFilterを使用することをお勧めします。この種のマップの問題は、セッションが無効になるとセッションオブジェクトを削除することです。 HttpSessionListenerを使用して機能させることができますが、FilterよりもMapを介して検証するのが最善だと思います。

それとは別に、タスクをよりシンプルで堅牢にするために、多くのセキュリティフレームワーク( Apache Shiro など)を見ることができます。

2
Premraj

ActionクラスはすでにSessionAwareインターフェースを実装していますか?

編集:

これを試してください(これはstruts2スタイルのソリューションです):

public class anAction implements SessionAware{
    private Map<String, Object> session;
    public Map<String, Object> getSession() {
         return session;
    }
    public void setSession(Map<String, Object> session) {
         this.session = session;
    }
    public String getLoginStatus(){
         session.put("userName", "test");  //Hard code here for testing.
         return SUCCESS;
    }
}

次に、jspコードを使用して、ページ上のuserNameを取得します。私は自分のマシンでこのアプローチをテストしましたが、機能します。

EDIT2:ところで、このようなログインチェックは、Struts2Frameworkが提供する「Interceptor」を使用して簡単かつエレガントに実行できます。

2
RollingBoy

SessionAwareの実装は必要ありません。

public class LoginAction extends Actionsupport
{
  private Map<String, Object> session;
  //Getter and Setter method
   public String execute() throws Exception {
      session=ActionContext.getContext().getSession();
      session.put("userName", "test");
     return super.execute();
   }
} 
0
hari

次のjournaldevの記事には、上記のSteven応答の同じ行に詳細があります http://www.journaldev.com/2210/struts-2-interceptor-tutorial-with-custom-authentication-interceptor-example

0
rajnish