Thanks Sergey. I'm interested in this topic. Please keep me posted on
any progress you make on new features. I'll be happy to help out with
testing etc. Cheers,

/Henrik

On Wed, 2009-11-04 at 10:05 +0000, Sergey Beryozkin wrote:
> Hi Henrik
> 
> > Hi Sergey. Thanks again for the response. I stepped through the
> > JAXRSOutInterceptor in the debugger and found out that the content type
> > for the Response I had created was "octet/stream" instead of
> > "application/xml". Once I created the appropriate content type entry in
> > the MultivaluedMap returned by getMetadata() method, everything worked.
> 
> JAXRS spec requires "octet/stream" be set if no content type has been set by 
> the user code (either implicitly by specifying 
> @Produces or returning a custom Response, etc)....Please see more comments 
> below
> 
> >
> > While on that subject, is that the appropriate way of doing it? What I
> > ended up doing was something like the code snippet below. Apologies for
> > the bad formatting, I'm using Evolution to send the email...
> >
> > // "error" is our error placeholder bean sent back as the entity
> > final Response newResponse = builder.entity(error.validate()).build();
> > newResponse.getMetadata().putAll(oldResponse.getMetadata());
> > final MultivaluedMap<String, Object> map = newResponse.getMetadata();
> >
> > if (! map.containsKey(HttpHeaders.CONTENT_TYPE))
> > {
> >  final List<Object> contentTypes = new ArrayList<Object>();
> >  contentTypes.add("application/xml");
> >  map.put(HttpHeaders.CONTENT_TYPE, contentTypes);
> > }
> > else
> > {
> >  final List<Object> contentTypes = map.get(HttpHeaders.CONTENT_TYPE);
> >
> >  if (! contentTypes.contains("application/xml"))
> >  {
> >    contentTypes.add("application/xml");
> >  }
> > }
> >
> > A little clumsy maybe, but I was trying to preserve whatever content
> > types the original response had as well as making sure that the new
> > response declares "application/xml". Any suggestions on how to clean
> > this up and do it properly are appreciated. Anyway, after inserting this
> > code snippet, things work all the way back to the browser, and I see the
> > exception entity in XML form. Thanks,
> 
> This code is fine, and indeed, it is importnat that the headers which 
> might'be been set earlier on are not lost. Though you might 
> want to simplify it a bit, MultivaluedMap supports a putSingle() method, so 
> you can do :
> 
> final MultivaluedMap<String, Object> map = newResponse.getMetadata();
> map.putSingle(HttpHeaders.CONTENT_TYPE, "application/xml");
> 
> given that it is "application/xml" which is required in this case ?
> 
> One thing I'm concerned a bit about is that if the generic exception 
> reporting logic is done in a ResponseHandler and/or 
> RequestHandler filters then even normal non-exceptional requests or responses 
> will go through them, so you probably do some kind of 
> a check to see if it's an exceptional invocation or not...I don't think it 
> affects in any measurable way the overall performance but 
> it's worth mentioning that few more options are available (sorry for not 
> mentioning them in the first place)...
> 
> First, all the exceptions which have not been mapped to responses by 
> registered providers will be propogated (or is it 'propagated' 
> :-) ?)
> to the container wrapped in ServletExceptions. So one other option is to 
> register a simple ServletFilter which will only will only 
> handle ServletExceptions and check the causes and write to the 
> HttpServletResponse as needed.
> 
> Another option is is to register a CXF out fault interceptor with the 
> jaxrs:server. I'll be working on a test which will show how to 
> do it. This fault interceptor will be executed only if the propogation has 
> been disabled through a jaxrs:server property and if no 
> matching ExceptionMappers are available. I'll let you know once the system 
> test is ready.
> 
> That said, I reckon using JAXRS filters should do well - may be I will add 
> the support for the in/out  fault JAXRS filters too...
> 
> thanks, Sergey
> 
> >
> > /Henrik
> >
> > On Tue, 2009-11-03 at 18:25 -0500, Sergey Beryozkin wrote:
> >> Hi Henrik
> >>
> >> I reckon looking at the wire representation would really help in
> >> figuring out what's going on. Also, can it be that say the XStream
> >> writer needs to have some kind of close() method being called ?
> >>
> >> Please send a wget/browser request through a tcp trace utility and let
> >> me know the details
> >>
> >> Thanks, Sergey
> >>
> >> -----Original Message-----
> >> From: Henrik Martin [mailto:[email protected]]
> >> Sent: 03 November 2009 22:03
> >> To: [email protected]
> >> Subject: Re: Would like to send custom XML back whenever a 400 or 500
> >> category error happens
> >>
> >> Sergey, thanks for the response. I should have given you a little more
> >> detail. In my handleResponse() method, I do return a Response, which
> >> contains something similar to your suggested ExceptionInfo. It's just a
> >> Java bean containing some properties and some XStream annotations. When
> >> I run everything in the debugger, I can see that my entity (containing
> >> the exception information) gets handled by our MessageWriter, and proper
> >> XML gets generated (I'm printing it out inside the MessageWriter). This
> >> is what's puzzling me, I never see the XML after that.
> >>
> >> I don't get any exceptions being thrown anywhere, so I don't think it's
> >> a failure of any kind. Our MessageWriter is registered to handle any
> >> type thrown at it. It basically uses XStream to stream out the beans
> >> into XML. It seems to work fine. If I set the HTTP status code to 200
> >> and return the exact same exception data, it gets streamed out properly
> >> all the way back to the client. I'm curious to what the difference is in
> >> execution path when I'm setting the HTTP status to a 400 or 500? I've
> >> tried following along in the debugger, but there are so many levels of
> >> calls that it's a little overwhelming. Is there some sort of error
> >> handler in the CXF framework that takes different paths depending on the
> >> value of the HTTP status code? Thanks,
> >>
> >> /Henrik
> >>
> >> On Mon, 2009-11-02 at 17:11 -0500, Sergey Beryozkin wrote:
> >> > Hi Henrik
> >> >
> >> >
> >> >
> >> > For some reasons I can only see your message in Archives, but not
> >> > Nabble.
> >> >
> >> >
> >> >
> >> > >>The handleResponse() method in
> >> > >>my filter gets called, but I've found that if I return any kind of
> >> > >>error, i.e. a category 400 or 500 type error, the XML that I'm
> >> > returning
> >> > >>as the content doesn't get rendered in the browser
> >> >
> >> > If one returns a custom Response from a filter, then its entity, if
> >> any,
> >> > will be
> >> > serialized by the available writers.
> >> >
> >> > So if you set a String instance as a custom entity and you happen to
> >> > have a custom message body writer which can
> >> > wrap Strings then the browser would show it as a plain text sequence.
> >> >
> >> > Starting from CXF 2.2.4 it is possible to indicate that writers have
> >> to
> >> > be ignored. In meantime, the best way would be to return
> >> > an object like ExceptionInfo which will be serialized by the
> >> appropriate
> >> > XML writer.
> >> >
> >> > Is it what might be happening in your case ?
> >> >
> >> > If you're thinking of doing JAXRS only then filters should do well.
> >> >
> >> > Cheers, Sergey
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> >
> >> > 
> 

Reply via email to