有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从struts2运行线程

我正在开发一个sturts2 Web应用程序,我有一个带有用户名和密码字段的登录页面。一旦用户提交了带有值的表单,我将验证登录,如果用户提供了有效的用户名和密码,它将重定向到主页。在重定向主页时,我必须调用一个线程,在该线程中我在会话中设置了一些数据以备将来使用。如何做到这一点

我所做的是

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

共 (3) 个答案

  1. # 1 楼答案

    我只是想知道为什么需要启动一个新线程来将一些数据放入session

    (你说你想做的事情,但实际上你没有在发布的代码中做,而是把东西放在request

    您只需通过您的操作implement SessionAware Interface

    Actions that want access to the user's HTTP session attributes should implement this interface.

    This will give them access to a Map where they can put objects that can be made available to subsequent requests.

    Typical uses may be cached user data such as name, or a shopping cart.

    它不是强制性的,但是it is a best practice用于从操作中访问会话,而不是请求操作上下文:

    You can obtain the session attributes by asking the ActionContext or implementing SessionAware. Implementing SessionAware is preferred.

    如果需要,这里有一个小的用法示例:http://www.splinter.com.au/how-to-use-sessions-with-struts-2/

  2. # 2 楼答案

    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;
    
    }
    
  3. # 3 楼答案

    来自Struts2Javadoc

    The ActionContext is thread local which means that values stored in the ActionContext are unique per thread

    您只需创建一个新线程,这样您的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;
    }
    

    最好的方法是将上下文传递给线程构造函数。但我不确定上下文是否是线程安全的