include - Struts2 ActionContext and Response for chaining actions -
i have pretty complex problem struts2 chaining actions, in advance patience reading problem. try best describe clearly.
below struts.xml:
<?xml version="1.0" encoding="utf-8" ?> <!doctype struts public "-//apache software foundation//dtd struts configuration 2.0//en" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.dynamicmethodinvocation" value="false" /> <constant name="struts.enable.slashesinactionnames" value="true" /> <constant name="struts.devmode" value="false" /> <package name="default" extends="struts-default" namespace="/"> <action name="test" class="com.bv.test.testaction1" > <result name="success" type="chain">y</result> </action> <action name="x"> <result name="success">/index.jsp</result> </action> <action name="y" class="com.bv.test.testaction2"> <result name="success">/index.jsp</result> </action> </package> </struts>
my logic this: when accessing /myapp/test, testaction1 handle request; in testaction1, "include" action x (my 2nd action in config) this:
responseimpl myresponse = new responseimpl(response); requestdispatcher rd = request.getrequestdispatcher("/x.action"); rd.include(request, myresponse);
and important thing using customized responseiml when including "x.action".
after including, return "success", result chains action y (3rd action in config);
, @ last, testaction2 continue handle request, go success result, , jsp should rendered, what see blank page.
the jsp file simple: index.jsp
<h1>test!</h1>
my question/puzzle is:
- in testaction1, if response servletactioncontext, getting different ones before , after including; before including default response, after including got instance of customized responseimpl; expect same one: i.e.: default response;
- in testaction2, response servletactioncontext, got instance of customized responseiml. important thing, think should default response instance here, i.e.: org.apache.catalina.connector.response, running on jboss;
- i getting different actioncontext in testaction2 (compared actioncontext in testaction1).
this problem drive me on nuts, have spent days on it.
advice appreciated!
million!!
my code:
testaction1:
public class testaction1 { public string execute() { actioncontext ac = actioncontext.getcontext(); system.out.println("before including: action context : " + ac); httpservletrequest request = servletactioncontext.getrequest(); httpservletresponse response = servletactioncontext.getresponse(); system.out.println("before including: response : " + response); responseimpl myresponse = new responseimpl(response); requestdispatcher rd = request.getrequestdispatcher("/x.action"); try { rd.include(request, myresponse); string s = myresponse.getoutput(); system.out.println("get response: " + s); } catch (exception e) { e.printstacktrace(); } ac = actioncontext.getcontext(); system.out.println("after including : action context : " + ac); response = servletactioncontext.getresponse(); system.out.println("after including : response : " + response); return "success"; } }
responseimpl:
import java.util.locale; import java.io.stringwriter; import java.io.printwriter; import java.io.outputstream; import java.io.bytearrayoutputstream; import java.io.ioexception; import java.io.unsupportedencodingexception; import javax.servlet.servletoutputstream; import javax.servlet.http.httpsession; import javax.servlet.http.httpservletresponse; import javax.servlet.http.httpservletresponsewrapper; import javax.servlet.http.cookie; import javax.servlet.jsp.jspwriter; /** * * */ public class responseimpl extends httpservletresponsewrapper { //========================================================= // private fields. //========================================================= private servletoutputstream outputstream = null; private bytearrayoutputstream bytearrayoutputstream = null; private stringwriter stringwriter = null; private printwriter printwriter = null; private httpservletresponse _response = null; private string contenttype= "text/html"; private string encoding = "utf-8"; /** * */ class servletoutputstream extends javax.servlet.servletoutputstream { private outputstream outputstream = null; /** * */ servletoutputstream(bytearrayoutputstream outputstream) { super(); this.outputstream = outputstream; } /** * */ public void write(int b) throws ioexception { this.outputstream.write(b); } } //========================================================= // public constructors , methods. //========================================================= /** * */ public responseimpl(httpservletresponse response) { super(response); this._response = response; } /** * */ public string getoutput() { if (this.stringwriter != null) { return this.stringwriter.tostring(); } if (this.bytearrayoutputstream != null) { try { return this.bytearrayoutputstream.tostring(this.encoding); } catch (unsupportedencodingexception e) { } return this.bytearrayoutputstream.tostring(); } return null; } //========================================================= // implements httpservletresponse interface. //========================================================= public void addcookie(cookie cookie) { } public void adddateheader(string name, long date) { } public void addheader(string name, string value) { } public void addintheader(string name, int value) { } public boolean containsheader(string name) { return false; } public string encoderedirecturl(string url) { if (null != this._response) { url = this._response.encoderedirecturl(url); } return url; } public string encodeurl(string url) { if (null != this._response) { url = this._response.encodeurl(url); } return url; } public void senderror(int sc) { } public void senderror(int sc, string msg) { } public void sendredirect(string location) { } public void setdateheader(string name, long date) { } public void setheader(string name, string value) { } public void setintheader(string name, int value) { } public void setstatus(int sc) { } public void resetbuffer() { } //========================================================= // implements deprecated httpservletresponse methods. //========================================================= public void setstatus(int sc, string sm) { } //========================================================= // implements deprecated httpservletresponse methods. //========================================================= public string encoderedirecturl(string url) { return encoderedirecturl(url); } public string encodeurl(string url) { return encodeurl(url); } //========================================================= // implements servletresponse interface. //========================================================= public void flushbuffer() { } public int getbuffersize() { return 0; } public string getcharacterencoding() { return this.encoding; } public string getcontenttype() { return this.contenttype; } public locale getlocale() { return null; } public javax.servlet.servletoutputstream getoutputstream() { if (this.outputstream == null) { this.bytearrayoutputstream = new bytearrayoutputstream(); this.outputstream = new servletoutputstream(this.bytearrayoutputstream); } return this.outputstream; } public printwriter getwriter() { if (this.printwriter == null) { this.stringwriter = new stringwriter(); this.printwriter = new printwriter(this.stringwriter); } return this.printwriter; } public boolean iscommitted() { return true; } public void reset() { } public void setbuffersize(int size) { } public void setcharacterencoding(string charset) { } public void setcontentlength(int len) { } public void setcontenttype(string type) { int needle = type.indexof(";"); if (-1 == needle) { this.contenttype = type; } else { this.contenttype = type.substring(0, needle); string pattern = "charset="; int index = type.indexof(pattern, needle); if (-1 != index) { this.encoding = type.substring(index + pattern.length()); } } } public void setlocale(locale locale) { } }
testaction2:
public class testaction2 { public string execute() { actioncontext ac = actioncontext.getcontext(); system.out.println("in testaction 2 : action context : " + ac); httpservletresponse response = servletactioncontext.getresponse(); system.out.println("in testaction 2 : response : " + response); return "success"; } }
web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app id="webapp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>struts2 application</display-name> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> <dispatcher>include</dispatcher> <dispatcher>forward</dispatcher> <dispatcher>request</dispatcher> </filter-mapping> </web-app>
this debug info.
- before including: action context :com.opensymphony.xwork2.actioncontext@c639ce
- before including: response : org.apache.catalina.connector.responsefacade@8b677f
- get response:
<h1>test!</h1>
- after including : action context : com.opensymphony.xwork2.actioncontext@2445d7
- after including : response : com.bv.test.responseimpl@165547d
- in testaction 2 : action context :com.opensymphony.xwork2.actioncontext@19478c7
- in testaction 2 : response : com.bv.test.responseimpl@165547d
so, have different actioncontext instances before , after including!!
when rd.include request fired internally inside web server. struts point of view sees new request , new action context created result. (that's why need include 'include' thing on struts2 filter.. it's seeing included requests well). since thread local variables used track action context , when actioncontext.getcontext() context related new request (related include) gets retrieved.
did try resetting response initial 1 in block below
try { rd.include(request, myresponse); string s = myresponse.getoutput(); system.out.println("get response: " + s); } catch (exception e) { e.printstacktrace(); } { servletactioncontext.setresponse(response); }
if resolves response issue.. store string 's' variable in action context , retrieve inside action2
Comments
Post a Comment