I think there may also be a workaround in the interim of fixing this.
Register a ContainerResponseFilter implementation that has
HttpServletResponse injected. Check the status, headers and entity of
the ContainerResponse. If only the status is set and >=400 then call
HttpServletResponse.sendError() with the status.
Paul.
On Jan 14, 2009, at 1:45 PM, Paul Sandoz wrote:
> HI Jorge,
>
> Thanks for doing this investigating it helps me a lot to investigate
> further. Note that i tried asking on the GF users list but got no
> response :-(
>
> So in the bad-resource case the behavior for the Jersey Web app
> should be as follows:
>
> 1) Jersey returns a 404 to the URL path "/rest/bla"
>
> 2) The servlet container redirects the 404 to /rest/error"
>
> And i presume it should be the same for a servlet implemented
> equivalently to that of the Jersey servlet.
>
> So... I modified the servlet test case. The web.xml was modified as
> follows:
>
> <servlet-mapping>
> <servlet-name>ErrorServlet</servlet-name>
> <url-pattern>/servlet/*</url-pattern>
> </servlet-mapping>
> <error-page>
> <error-code>404</error-code>
> <location>/servlet/error</location>
> </error-page>
>
> and the ErrorServlet was modified as follows:
>
> if (req.getPathInfo().equals("/error")) {
> PrintWriter out;
>
> res.setContentType("text/plain");
> out = res.getWriter();
>
> out.printf("The error has been caught by the error
> servlet!\n\n");
> out.printf("Error : %d\n" +
> "Message : %s\n" +
> "Exception Type: %s\n",
>
> req.getAttribute("javax.servlet.error.status_code"),
> req.getAttribute("javax.servlet.error.message"),
>
> req.getAttribute("javax.servlet.error.exception_type"));
> } else {
> res.setStatus(404);
> }
>
> Thus the above models what Jersey does. In such cases the same
> behavior results as the Jersey deployed JAX-RS test case.
>
> I think i now know what it is. If i change:
>
> res.setStatus(404);
>
> to
>
> res.sendError(404);
>
> then it works. And then i read this:
>
> Sets the status code for this response. This method is used to set
> the return status code when there is no error (for example, for the
> status codes SC_OK or SC_MOVED_TEMPORARILY). If there is an error,
> and the caller wishes to invoke an error-page defined in the
> web application, the sendError method should be used instead.
>
> Hmm... i am wondering what to do here. The following rule could apply:
>
> - if the response status is an error >= 400 and there is no
> response entity and no response headers set (the application has not
> set
> anything other than the status code or Jersey has set just the
> status code) then the servlet response mapping calls sendError.
>
> IMHO this is something we need to clarify in the JAX-RS specification.
>
> Paul.
>
> On Jan 14, 2009, at 9:23 AM, Jorge L. Williams wrote:
>
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Hi Paul,
>>
>> Wow, I can't believe it took me a month to get back to you. Sorry,
>> holiday, deadlines, you know how it is.
>>
>> Anyway, I did put together a simple app for you. I noticed while
>> testing it that the behavior is slightly different between
>> application servers. To rule out an application server problem vs a
>> jersey problem I also tested my approach with the RestEasy JAX-RS
>> implementation (no offense guys :-) I'm sending the source for the
>> ear file.
>>
>> There are three web modules:
>>
>> 1. error-servlet : Our old approach of catching errors using a
>> servlet as an error page.
>> 2. error-jaxrs : The Jersey implementation
>> 3. error-resteasy : The Rest-easy implementation
>>
>> I tested with three application servers
>>
>> 1. glassfish : 9.1_02 (build b04-fcs)
>> 2. jboss : 5.0.0.GA
>> 3. weblogic : 10.3
>>
>> Each webapp is setup to forward a 404 to a resource (or servlet). If
>> you visit context root of each of the web apps you'll see a couple of
>> links
>>
>> 1. direct : A direct link to the error resource (just to make sure
>> we're getting to it)
>> 2. bad : A bad link within the context root (this should generate
>> 404 and forward to the error resource)
>> 3. bad-resource : A bad link within the JAX-RS servlet mapping
>> (this should should also forward to the error resource)
>>
>> Here's the results I get for Jersey
>>
>> glassfish (direct : works, bad : works, bad-resource : wrong error
>> page )
>> jboss (direct : works, bad: works, bad-resource: wrong error page)
>> weblogic (direct: works, bad : empty result, bad-resource: empty
>> result)
>>
>> I use weblogic which displays the behavior I described in my initial
>> email. I'm guessing the behavior there may indeed be an application
>> server issue. None the less, Jersey doesn't seem to be behaving
>> correctly with the other app servers. The RestEasy implementation
>> handles all three cases correctly -- in JBoss, I couldn't get it
>> deployed on the other app servers though I didn't spend too much time
>> fighting with it :-)
>>
>> Hope this helps...It would be really nice if I could get this feature
>> to work or if there were at least an alternative to it.
>>
>> Let me know,
>>
>> jOrGe W.
>>
>>> Hi Jorge,
>>>
>>> Would it be possible to create a simple example application. That
>>> would help me understand better your use-case and help debug what is
>>> going on.
>>>
>>> My suspicion is the error resource is deployed at a URL that is
>>> different to what you expect.
>>>
>>> What is the error resource class you are using, specifically the
>>> @Path
>>> value? and what is the URL pattern for the error servlet?
>>>
>>> Paul.
>>>
>>> On Dec 12, 2008, at 12:32 AM, Jorge L Williams wrote:
>>>
>>>>
>>>> Hey guys,
>>>>
>>>> I know we covered this topic earlier, but I have a slightly
>>>> different question, I think.
>>>>
>>>> We want to make sure that regardless of what sort of error
>>>> condition
>>>> occurs (whether it's generated by one of our JAX-RS resources or
>>>> whether it's an internal server error of some kind) that we
>>>> return a
>>>> correct entity. In our case we have a JAXB object called
>>>> WebserviceFault that our clients expect should anything go wrong.
>>>>
>>>> To catch every case we created an ErrorServlet that mapped to say /
>>>> error and setup our web.xml...
>>>>
>>>> <error-page>
>>>> <error-code>400</error-code>
>>>> <location>/error</location>
>>>> </error-page>
>>>> .
>>>> .
>>>> .
>>>> <error-page>
>>>> <error-code>500</error-code>
>>>> <location>/error</location>
>>>> </error-page>
>>>>
>>>> The error servlet itself simply gets details from the request...
>>>>
>>>> Integer code = (Integer) request.getAttribute
>>>> ("javax.servlet.error.status_code");
>>>> Exception e = (Exception) request.getAttribute
>>>> ("javax.servlet.error.exception");
>>>> String msg = (String) request.getAttribute
>>>> ("javax.servlet.error.message");
>>>>
>>>> and wraps it around a WebserviceFault which it serializes to the
>>>> response.
>>>>
>>>> Very tedious and maybe a little goofy (If there's a better way I'll
>>>> take it), but it's been working well for us thus far and this
>>>> method
>>>> allows us to catch absolutely all error conditions including 401s
>>>> etc..that I don't think make it into Jersey.
>>>>
>>>> We've been transitioning our ReST services from using vanilla
>>>> servlets to Jersey over the last couple of months. I decided to
>>>> replace the ErrorServlet that we've been using with an error
>>>> resource since we've become interested in receiving error
>>>> conditions
>>>> not just in XML but also in JSON and I figured converting the Error
>>>> servlet would be the easiest way to accomplish this.
>>>>
>>>> One problem: it doesn't work. When an error condition hits and the
>>>> application server forwards to the error resource, I get nothing
>>>> but
>>>> a blank request no entity at all -- though the Error code is
>>>> correctly transmitted ie:
>>>>
>>>>
>>>> HTTP/1.x 404 Not Found
>>>> Date: Thu, 11 Dec 2008 22:34:21 GMT
>>>> Content-Length: 0
>>>>
>>>> I suspect that this is because the request is being forwarded and
>>>> the URI is not what Jersey is expecting(?).
>>>> For example we get...
>>>>
>>>> GET /bla/bla/bla
>>>>
>>>> but something goes wrong and the application server forwards to
>>>>
>>>> /error
>>>>
>>>> probably via a request dispatcher(?). I believe the request URI in
>>>> this case should be /bla/bla/bla and not /error -- is this what's
>>>> confusing things?
>>>>
>>>> So, should I stick with my error servlet? If so what's the best
>>>> way to utilize Jersey to handle the request -- parse the Accept
>>>> header myself and get a MessageBodyWriter from MessageBodyWorkers?
>>>>
>>>> Thanks,
>>>>
>>>> jOrGe W.
>> -----BEGIN PGP SIGNATURE-----
>> Version: GnuPG v2.0.9 (GNU/Linux)
>>
>> iEYEARECAAYFAkltoQEACgkQ72r0i/n44hPv9wCfdrRjk7MmDJe8TucA4c3oA4rD
>> 3ioAoJjrOsE2mtMqJFzzOpCgUz+Q3Xml
>> =GtV5
>> -----END PGP SIGNATURE-----
>>
>> <error-test.tgz><error-
>> test
>> .tgz
>> .sig
>> >
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>