我正在开发一个sturts2 webapplication,我有一个包含用户名和密码字段的登录页面。一旦用户提交了带有值的表单,我就会确认登录,如果用户提供有效的用户名和密码,则会将其重定向到主页。重定向主页时,我必须调用一个线程,我在会话中设置一些数据供将来使用。怎么做?
我做的是
import com.opensymphony.xwork2.ActionContext;
if( loginSuccess(userInfo) ) {
initializeDatas(); // calling thread after userInfo bean validated
// redirecting to home page
return HOME_PAGE;
}
我添加了一个实现runnable的新类。
class intilalizer implements Runnable {
@Override
public void run() {
try {
System.out.println("Started to set values ");
List<String> iphoneSdks = new ArrayList<String>();
List<String> iphoneOSSdks = IosSdkUtil.getMacSdks(MacSdkType.iphoneos);
List<String> simSdks = IosSdkUtil.getMacSdks(MacSdkType.iphonesimulator);
List<String> macSdks = IosSdkUtil.getMacSdks(MacSdkType.macosx);
iphoneSdks.addAll(iphoneOSSdks);
iphoneSdks.addAll(simSdks);
iphoneSdks.addAll(macSdks);
ActionContext context = ActionContext.getContext();
System.out.println("context ===> " + context); // here i am getting null value
String httpRequest = ServletActionContext.HTTP_REQUEST;
System.out.println("httpRequest =====> " + httpRequest);
Object object = context.get(httpRequest);
System.out.println(object);
HttpServletRequest req = (HttpServletRequest) object;
req.setAttribute(REQ_IPHONE_SDKS, iphoneSdks);
req.setAttribute(REQ_IPHONE_SIMULATOR_SDKS, simSdks);
System.out.println("Value initialized@@@@");
} catch (Exception e) {
e.printStackTrace();
}
}
}
我正在
java.lang.NullPointerException
at com.photon.phresco.framework.actions.intilalizer.run(Login.java:286)
at java.lang.Thread.run(Thread.java:680)
我在网上收到此错误。
ActionContext context = ActionContext.getContext();
System.out.println("context ===> " + context); // here i am getting null value
答案 0 :(得分:2)
来自Struts 2 JavaDoc
ActionContext是线程本地的,这意味着存储在ActionContext中的值对于每个线程是唯一的
您只需创建一个新线程,这样您的ThreadLocal变量就不可用了。你应该这样做:
import com.opensymphony.xwork2.ActionContext;
if( loginSuccess(userInfo) ) {
ActionContext context = ActionContext.getContext();
initializeDatas(context); // calling thread after userInfo bean validated
// redirecting to home page
return HOME_PAGE;
}
最好的方法是将上下文传递给Thread构造函数。但我不确定COntext是否是ThreadSafe。
答案 1 :(得分:1)
我只是想知道为什么你需要开始一个新的线程来将一些数据放入session
(你说你想做的事情,但实际上你没有在发布的代码中做,你把东西放在request
中)。
您可以从行动中 implement SessionAware Interface 。
要访问用户的HTTP会话属性的操作应该 实现这个界面。
这将使他们可以访问Map,在那里他们可以放置对象 可以提供给后续请求。
典型用途可以是缓存的用户数据,例如名称或购物车。
这不是强制性的,但 it is a best practice 用于从Actions中访问会话,而不是要求ActionContext:
您可以通过询问ActionContext或获取会话属性 实现SessionAware。 首选实施SessionAware 。
如果需要,这里有一个小例子:http://www.splinter.com.au/how-to-use-sessions-with-struts-2/
答案 2 :(得分:0)
if( loginSuccess(userInfo) ) {
// redirecting to home page
return HOME_PAGE;
initializeDatas(); // calling thread after userInfo bean validated
}
那不行。该方法将在返回调用后结束。尝试先调用创建新线程的方法。
if( loginSuccess(userInfo) ) {
// redirecting to home page
initializeDatas(); // calling thread after userInfo bean validated
return HOME_PAGE;
}