The VelocityECSLayout has been deprecated in Turbine 2.3.
Writing Directly To ServletOutputStream
On March 19, 2003, Peter Courcoux wrote to turbine-dev:
_Hi all,
I have recently changed from using turbine 2.2-b3 to 2.2.1 and from using VelocityECSLayout to VelocityOnly'*_Layout.
One of my actions which extends VelocitySecure_'Action handles a file download by obtaining the HttpServlet'Response setting the headers and then obtaining and writing directly to the ServletOutput*'Stream.
Before the changes outlined above this caused no problem. Having made the changes the following Exception occurs after the completion of the download and closing the ServletOutput'*_Stream:
java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.catalina.connector.ResponseBase.getWriter(ResponseBase.java:750) at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:165) at org.apache.turbine.services.rundata.DefaultTurbineRunData.getOut(DefaultTurbineRunData.java:1013) at org.apache.turbine.modules.layouts.VelocityOnlyLayout.doBuild(VelocityOnlyLayout.java:120) at org.apache.turbine.modules.Layout.build(Layout.java:91) at org.apache.turbine.modules.LayoutLoader.exec(LayoutLoader.java:123) at org.apache.turbine.modules.pages.DefaultPage.doBuild(DefaultPage.java:169) at org.apache.turbine.modules.Page.build(Page.java:90) at org.apache.turbine.modules.PageLoader.exec(PageLoader.java:123) at org.apache.turbine.Turbine.doGet(Turbine.java:563) at org.apache.turbine.Turbine.doPost(Turbine.java:658)
_
*
He later contributed a solution:*_
"I have solved this by creating a DirectResponse'*_Layout class which does nothing except check that declareDirectResponse() has been called on RunData. I then call
data.setLayout("DirectResponseLayout");
in my Action class.
Source of DirectResponse_*'Layout:
package com.whatever.modules.layouts; // Turbine Classes import org.apache.turbine.modules.Layout; import org.apache.turbine.util.RunData; /** * This layout allows an action to manipulate the * ServletOutputStream directly. It requires that * data.declareDirectResponse() has been called to * indicate that the OutputStream is being * handled else an Exception is thrown * * @author <a href="mailto:peter@courcoux.biz">Peter Courcoux</a> */ public class DirectResponseLayout extends Layout { /** * Method called by LayoutLoader. * * @param RunData */ public void doBuild( RunData data ) throws Exception { if (!data.isOutSet()) { throw new Exception( "data.declareDirectResponse() has not been called"); } } }
One drawback is that it calls data.isOutSet() which is deprecated.
Questions:
- Is there a better way?
- If not, would it be worth including the DirectResponse'*_Layout class in the turbine distribution.
- Is there a case for removing the deprecation of RunData.isOutSet()?
- Is this worth documenting. At least one other user appears to be doing something similar."
_
I have committed DirectResponse**Layout to cvs - it will come with future releases of Turbine (2.3.1 and 2.4) whenever those are released.
– ScottEade 2003-10-17