ユーザーセッションが存在する場合はセッションを維持する必要な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ページに制限されていることをどこかで読みましたが、どうすればこの問題を解決できますか?
どんな例でも私には非常に役立ちます。
あなたが現在持っているコードにはいくつかの問題があります。
SessionAware
インターフェースを実装する必要はありません。以下は、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>
セッションを維持するには、アクションクラスで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/
この種のMap
を使用してユーザーを認証する理由はありません。要件がセッションに対してユーザーを検証することだけである場合は、クラス内の一部のマップよりもFilter
を使用することをお勧めします。この種のマップの問題は、セッションが無効になるとセッションオブジェクトを削除することです。 HttpSessionListener
を使用して機能させることができますが、Filter
よりもMap
を介して検証するのが最善だと思います。
それとは別に、タスクをよりシンプルで堅牢にするために、多くのセキュリティフレームワーク( Apache Shiro など)を見ることができます。
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」を使用して簡単かつエレガントに実行できます。
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();
}
}
次のjournaldevの記事には、上記のSteven応答の同じ行に詳細があります http://www.journaldev.com/2210/struts-2-interceptor-tutorial-with-custom-authentication-interceptor-example