﻿{"id":259,"date":"2015-06-04T15:17:19","date_gmt":"2015-06-04T07:17:19","guid":{"rendered":"http:\/\/blog.sway.com.cn\/?p=259"},"modified":"2015-06-04T15:17:19","modified_gmt":"2015-06-04T07:17:19","slug":"struts2%e4%b8%ad%e4%bd%bf%e7%94%a8execandwait%e5%90%8e%ef%bc%8c%e5%9c%a8-action%e4%b8%ad%e8%b0%83%e7%94%a8getxxx%e6%96%b9%e6%b3%95%e6%8a%a5%e5%91%8ajava-lang-nullpointerexception%e5%bc%82%e5%b8%b8","status":"publish","type":"post","link":"http:\/\/blog.sway.com.cn\/?p=259","title":{"rendered":"Struts2\u4e2d\u4f7f\u7528execAndWait\u540e\uff0c\u5728 Action\u4e2d\u8c03\u7528getXXX()\u65b9\u6cd5\u62a5\u544ajava.lang.NullPointerException\u5f02\u5e38\u7684\u539f\u56e0\u548c\u89e3\u51b3\u65b9\u6cd5"},"content":{"rendered":"<p>\u4f7f\u7528\u00a0Struts2 \u7f16\u5199\u9875\u9762\uff0c\u9047\u5230\u4e00\u4e2a\u8981\u957f\u65f6\u95f4\u8fd0\u884c\u7684\u63a5\u53e3\uff0c\u56e0\u6b64\u589e\u52a0\u4e86\u4e00\u4e2aexecAndWait \uff0c\u7ed3\u679c\u5728 Action \u4e2d\u8c03\u7528 getContext()\u7684\u65f6\u5019\u62a5\u544a\u5f02\u5e38<\/p>\n<pre class=\"lang:default decode:true \">1 ActionContext context = ActionContext.getContext();\r\n2 ServletContext servletContext = (ServletContext) context.get(ServletActionContext.SERVLET_CONTEXT);  \/\/\u629b\u7a7a\u6307\u9488\u5f02\u5e38\r\n3 String rootPath = servletContext.getRealPath(\"\/\");<\/pre>\n<p>\u67e5\u8be2\u4e86\u5f88\u591a\u8bc4\u8bba\uff0c\u6700\u7ec8\u627e\u5230\u539f\u56e0\u8ddf\u89e3\u51b3\u65b9\u6848\uff0c\u5177\u4f53\u89e3\u91ca\u5728\u00a0<a href=\"http:\/\/stackoverflow.com\/questions\/16692658\/execandwait-interceptor-not-redirecting-to-success-page-after-waiting\">http:\/\/stackoverflow.com\/questions\/16692658\/execandwait-interceptor-not-redirecting-to-success-page-after-waiting<\/a>\u3002\u5927\u81f4\u610f\u601d\u4e3a\uff1aexecAndWait \u4f1a\u5bfc\u81f4\u6267\u884c\u7684Action \u5728\u53e6\u5916\u4e00\u4e2a\u7ebf\u7a0b\u4e2d\u88ab\u6267\u884c\uff0c\u800cgetText \u4f9d\u8d56\u00a0ActionContext \uff0c\u4ed6\u4ece\u00a0ActionContext \u4e2d\u83b7\u5f97\u5f53\u524d\u7684Locale \u4ece\u800c\u6839\u636e\u8bed\u8a00\u7684\u4e0d\u540c\u52a0\u8f7d\u4e0d\u540c\u7684\u6587\u5b57\uff0c\u53ef\u662f\uff0c\u7531\u4e8eActionContext \u662fThreadLocal \u7684\uff0c\u800cexecAndWait \u65b0\u5f00\u7ebf\u7a0b\u7684\u65f6\u5019\u5e76\u6ca1\u6709\u628a\u7236\u7ebf\u7a0b\u7684ActionContext \u4f20\u9012\u7ed9\u5b50\u7ebf\u7a0b\u00a0\u7ed3\u679c\u5bfc\u81f4\u5728\u65b0\u5f00\u7684\u5b50\u7ebf\u7a0b\u4e2d\u7684ActionContext\u4e2d\u7684\u6570\u636e\u90fd\u662fnull ,\u56e0\u6b64\u51fa\u73b0\u5f02\u5e38\u4fe1\u606f\u5c31\u4e0d\u8db3\u4e3a\u602a\u4e86\u3002<\/p>\n<p>\u89e3\u51b3\u65b9\u6cd5\u5982\u4e0b\uff1a\u9700\u8981\u91cd\u8f7d\u4e24\u4e2a\u7c7b\uff0c\u6765\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898<\/p>\n<p>ActionInvocationEx.java<\/p>\n<pre class=\"lang:java decode:true \">package byrs.rms.interceptors;\r\n\r\nimport com.opensymphony.xwork2.ActionContext;\r\nimport com.opensymphony.xwork2.ActionEventListener;\r\nimport com.opensymphony.xwork2.ActionInvocation;\r\nimport com.opensymphony.xwork2.ActionProxy;\r\nimport com.opensymphony.xwork2.Result;\r\nimport com.opensymphony.xwork2.interceptor.PreResultListener;\r\nimport com.opensymphony.xwork2.util.ValueStack;\r\n\r\npublic class ActionInvocationEx implements ActionInvocation {\r\n\r\n    \/**\r\n     * \r\n     *\/\r\n    private static final long serialVersionUID = 2434502343414625665L;\r\n\r\n    private final ActionInvocation mActionInvocation;\r\n\r\n    private final ActionContext context;\r\n\r\n    public ActionInvocationEx(ActionInvocation aActionInvocation,ActionContext aContext)\r\n    {\r\n        mActionInvocation = aActionInvocation;\r\n        context = aContext;\r\n    }\r\n\r\n    public Object getAction() {\r\n        return mActionInvocation.getAction();\r\n    }\r\n\r\n    public boolean isExecuted() {\r\n        return mActionInvocation.isExecuted();\r\n    }\r\n\r\n    public ActionContext getInvocationContext() {\r\n        return mActionInvocation.getInvocationContext();\r\n    }\r\n\r\n    public ActionProxy getProxy() {\r\n        return mActionInvocation.getProxy();\r\n    }\r\n\r\n    public Result getResult() throws Exception {\r\n        return mActionInvocation.getResult();\r\n    }\r\n\r\n    public String getResultCode() {\r\n        return mActionInvocation.getResultCode();\r\n    }\r\n\r\n    public void setResultCode(String resultCode) {\r\n        mActionInvocation.setResultCode(resultCode);\r\n    }\r\n\r\n    public ValueStack getStack() {\r\n        return mActionInvocation.getStack();\r\n    }\r\n\r\n    public void addPreResultListener(PreResultListener listener) {\r\n        mActionInvocation.addPreResultListener(listener);\r\n    }\r\n\r\n    public String invoke() throws Exception {\r\n        return mActionInvocation.invoke();\r\n    }\r\n\r\n    public String invokeActionOnly() throws Exception {\r\n        return mActionInvocation.invokeActionOnly();\r\n    }\r\n\r\n    public void setActionEventListener(ActionEventListener listener) {\r\n        mActionInvocation.setActionEventListener(listener);\r\n    }\r\n\r\n    public void init(ActionProxy proxy) {\r\n        mActionInvocation.init(proxy);\r\n    }\r\n\r\n    public ActionInvocation serialize() {\r\n        return mActionInvocation.serialize();\r\n    }\r\n\r\n    public ActionInvocation deserialize(ActionContext actionContext) {\r\n        return mActionInvocation.deserialize(actionContext);\r\n    }\r\n\r\n    \/**\r\n     * @return the context\r\n     *\/\r\n    public ActionContext getContext() {\r\n        return context;\r\n    }\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>ExecAndWaitInterceptorEx.java<\/p>\n<pre class=\"lang:java decode:true \">package byrs.rms.interceptors;\r\n\r\nimport org.apache.struts2.interceptor.BackgroundProcess;\r\nimport org.apache.struts2.interceptor.ExecuteAndWaitInterceptor;\r\n\r\nimport com.opensymphony.xwork2.ActionContext;\r\nimport com.opensymphony.xwork2.ActionInvocation;\r\n\r\npublic class ExecAndWaitInterceptorEx extends ExecuteAndWaitInterceptor {\r\n\r\n    \/**\r\n     * \r\n     *\/\r\n    private static final long serialVersionUID = 8829373762598564300L;\r\n    \r\n    \/**\r\n     * {@inheritDoc}\r\n     *\/\r\n    @Override\r\n    protected BackgroundProcess getNewBackgroundProcess(String arg0, ActionInvocation arg1, int arg2) {\r\n        ActionInvocationEx aActionInvocationEx = new ActionInvocationEx(arg1,ActionContext.getContext());\r\n        return new BackgroundProcessEx(arg0, aActionInvocationEx, arg2);\r\n    }\r\n\r\n    private class BackgroundProcessEx extends BackgroundProcess {\r\n        public BackgroundProcessEx(String threadName,\r\n                ActionInvocation invocation, int threadPriority) {\r\n            super(threadName, invocation, threadPriority);\r\n        }\r\n\r\n        private static final long serialVersionUID = -9069896828432838638L;\r\n        \/**\r\n         * {@inheritDoc}\r\n         * @throws InterruptedException \r\n         *\/\r\n        @Override\r\n        protected void beforeInvocation() throws InterruptedException {\r\n            ActionInvocationEx aActionInvocationEx = (ActionInvocationEx)this.invocation;\r\n            ActionContext context = aActionInvocationEx.getContext();\r\n            ActionContext.setContext(context);\r\n        }\r\n\r\n        \/**\r\n         * {@inheritDoc}\r\n         *\/\r\n       @Override\r\n        protected void afterInvocation() {\r\n            ActionContext.setContext(null);\r\n        }\r\n\r\n    }\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>\u7136\u540e\u5728struts.xml\u4e2d\u8986\u76d6\u9ed8\u8ba4\u62e6\u622a\u5668\u5373\u53ef<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;interceptors &gt; \r\n\t&lt;interceptor name=\"execAndWait\" class=\"byrs.rms.interceptors.ExecAndWaitInterceptorEx\"\/&gt; \r\n&lt;\/interceptors &gt;<\/pre>\n<p>\u53c2\u8003\u81ea\uff1ahttp:\/\/www.mobibrw.com\/?p=1046<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4f7f\u7528\u00a0Struts2 \u7f16\u5199\u9875\u9762\uff0c\u9047\u5230\u4e00\u4e2a\u8981\u957f\u65f6\u95f4\u8fd0\u884c\u7684\u63a5\u53e3\uff0c\u56e0\u6b64\u589e\u52a0\u4e86\u4e00\u4e2aexecAndWait \uff0c\u7ed3\u679c\u5728 A [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[114,18],"class_list":["post-259","post","type-post","status-publish","format-standard","hentry","category-struts2","tag-execandwait","tag-struts2-2"],"_links":{"self":[{"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/259","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=259"}],"version-history":[{"count":1,"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/259\/revisions"}],"predecessor-version":[{"id":260,"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=\/wp\/v2\/posts\/259\/revisions\/260"}],"wp:attachment":[{"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=259"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=259"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.sway.com.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=259"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}