Any chance you could try the latest 2.2.1-SNAPSHOTS? I think I fixed this
as part of the testing Benson and I did with the Sun Stax parser. The Sun
stream write doesn't cache anything so the fault codes ended up being 200
instead of 500 due to the response already being written. Thus the setStatus
call got properly moved up to the beginning so I THINK this is now fixed.
Dan
On Thu April 16 2009 9:13:04 am Nerijus Areska wrote:
> I believe this should happen on Websphere or any other Servlet spec 2.3+
> compliant web server.
>
> I get an empty response from CXF, when trying to return non-valid response
> ( blank mandatory field or similar, CXF has validating mode switched on ).
> I debugged my application for a while and found out, that CXF gets a fault
> in BareOutInterceptor in marshal phase, then unwinds all other
> interceptors, creates a new chain and invokes that. The message still
> remains the same and keeps some cached resources/data inside ( like
> XMLStreamWriter ).
> In the next chain, producing fault output, MessageSenderEndingInterceptor,
> when handling the message, invokes response.setStatus(500), before flushing
> the outputStream. In normal case( e.g. user exception ), it would not do
> that( Actually we end up with two wrapper streams in this chain, which
> later causes some method calls resulting in setStatus(500) ). Now servlet
> specification says, that setStatus(int) should clear the buffers, which of
> course looses my response.
> Tomcat, Glassfish, and probably several others skip this requirement and do
> not clear the buffers, which then works ok. Websphere follows specification
> strictly at this point, and thus looses the data.
>
> I wrote a simple interceptor, fixing this problem for me, though i am not
> sure about any side effects. I invoke it in Fault chain
>
> public class ClearOutputStreamInterceptor extends AbstractSoapInterceptor
> {
>
> public ClearOutputStreamInterceptor(Bus b) {
> super(Phase.PREPARE_SEND);
> getBefore().add(MessageSenderInterceptor.class.getName());
> }
>
> public void handleMessage(SoapMessage message) {
> message.setContent(XMLStreamWriter.class, null);
> message.put("wrote.envelope.start", null);
> }
>
> }
--
Daniel Kulp
[email protected]
http://www.dankulp.com/blog