私はカスタムコンテキストクラスを使ってアプリケーション全体に値を格納する、乱雑なStruts 1アプリケーションを開発しています。基本的には、セッションスコープ変数の格納にのみ使用されます。私はこのカスタムクラスが使用される理由は、httpセッションにアクセスできない他のクラスがセッション変数を取得して設定できるようにするためだと思います。サーブレットフィルタにThreadLocaleの値が混在する
とにかく、ほとんどの場合、これはうまくいきます。カスタムコンテキストは、アクションクラスとサービスクラス全体で問題なく変数を共有するために使用されます。しかし、私はちょうど、うまくいけば、HTTPフィルタ内のこのカスタムコンテキストを使用して動作しないことを発見した!これは、ランダムに別のセッションから値を引き出すように見えます。そして、セッションによって、私は実際にスレッドを意味します。なぜなら、このカスタムコンテキストはThreadLocaleを使ってそれが汚い作業を行うからです。
が、これは、フィルタ以外の他のすべてのクラスの内部だけで結構な動作しているようですが、ここでも見
package com.zero.alpha.common;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Locale;
import java.util.Map;
public final class CustomContext implements Serializable {
private static final long serialVersionUID = 400312938676062620L;
private static ThreadLocal<CustomContext> local = new ThreadLocal() {
protected CustomContext initialValue() {
return new CustomContext("0", "0", Locale.getDefault());
}
};
private String dscId;
private String sessionId;
private Locale locale;
private Map<String, Serializable> generalArea;
public CustomContext(String dscId, String sessionId, Locale locale) {
this.dscId = dscId;
this.sessionId = sessionId;
if (locale != null) {
this.locale = locale;
} else {
this.locale = Locale.getDefault();
}
this.generalArea = new Hashtable();
}
public static CustomContext get() {
return ((CustomContext) local.get());
}
public static void set(CustomContext context) {
local.set(context);
}
public String getDscId() {
return this.dscId;
}
public String getSessionId() {
return this.sessionId;
}
public Locale getLocale() {
return this.locale;
}
public Serializable getGeneralArea(String key) {
return ((Serializable) this.generalArea.get(key));
}
public Serializable putGeneralArea(String key, Serializable value) {
return ((Serializable) this.generalArea.put(key, value));
}
public void clearGeneralArea() {
this.generalArea.clear();
}
public Serializable removeGeneralArea(String key) {
return ((Serializable) this.generalArea.remove(key));
}
}
してください。フィルターが壊れているところを見せてください。
カスタムコンテキストはdoFilterメソッドでユーザをつかむために使用されるpackage com.zero.alpha.myapp.common.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.zero.alpha.common.CustomContext;
import com.zero.alpha.myapp.utility.CommonConstants;
import com.zero.alpha.myapp.utility.CommonHelpers;
import com.zero.alpha.myapp.UserDomain;
public class LoginFilter implements Filter {
public LoginFilter() {
}
public void init(FilterConfig config) throws ServletException {}
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
// Don't use the login filter during a login or logout request
if (req.getServletPath().equals("/login.do")
|| req.getServletPath().equals("/login-submit.do")
|| req.getServletPath().equals("/logout.do")) {
chain.doFilter(request, response);
} else {
doFilter(req, (HttpServletResponse) response, chain);
}
}
protected void doFilter(HttpServletRequest request, HttpServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpSession session = request.getSession(false);
// This is the problem right here. Sometimes this will grab the value of a different user currently logged in
UserDomain user = (UserDomain) CustomContext.get()
.getGeneralArea(CommonConstants.ContextKey.USER_SESSION);
if (session == null || user == null) {
// Unauthorized
response.sendRedirect(loginPage);
} else {
// Authorized
session.setAttribute("userInfo", CommonHelpers.getUserDisplay(user));
chain.doFilter(request, response);
}
}
}
、それがランダムにログインしているユーザーから別のユーザーオブジェクトを取得します。明らかに良い状況ではありません!
これが発生する唯一の時間は、ログインしている別のユーザーのアクティビティの後です。私は終日そこに座って、ユーザーAのセッションをリフレッシュし続けても問題はありません。ただし、ユーザーBとして何らかのアクションを実行した後、ユーザーAのセッションを再度リフレッシュすると、通常はスワップされます。しかし、ユーザーAのセッションをもう一度更新すると、正常に戻ります。
これは、アプリケーションが実際にリモート開発用Tomcatサーバーにデプロイされたときに非常に頻繁に発生することに気付きました。ローカルで実行しても、遠隔地に配置した場合ほど頻繁には発生しません。これは遠隔からほぼ100%発生します。
私はフィルタ内のセッション変数を調べましたが、セッション自体に問題はないようです。私は間違ったユーザーがThreadLocale変数から引き出されても、セッションIDが正しいことを確認しました。
誰でもお手伝いできますか?ありがとう。
ユーザbのアクションがカスタムコンテキストインスタンスにアクセスしていないことを確認してください。 – efekctive
@efekctiveユーザBのアクションは、同じ正確な方法で、ユーザAと同じカスタムコンテキストを使用します。 – zero01alpha