users@jersey.java.net

[Jersey] Re: Tomcat not seeing exception message

From: Casper Bang <casper.bang_at_gmail.com>
Date: Wed, 16 Mar 2011 14:17:24 +0100

Thanks for testing Ryan. I am 99% my problem has to do with using
EhCache's SimpleCachingHeadersPageCachingFilter, I've logged issues with
Terracotta for this before (the filter not forwarding 3xx and 4xx response
codes). I don't know why I didn't think of checking that at first, sorry to
have wasted your time!

/Casper


On Wed, Mar 9, 2011 at 11:46 PM, Ryan Stewart <zzantozz_at_gmail.com> wrote:

> I tried out the servlet/filter thing in Tomcat, and I don't get any
> unexpected results. I added a context to Tomcat (just created a directory in
> <tomcat home>/webapps) and put in a basic web.xml and a servlet/filter class
> that always returns a 400 response of type text/plain just like you're
> describing. When invoking it as either a filter or a servlet, I get a plain
> text page with the error message on it, as expected. I tried it in Tomcat
> 6.0.32 and 7.0.10. If you can run the same kind of test on your Tomcat
> server, it might give you some insight. Here are the files I used:
>
> <web-app xmlns="http://java.sun.com/xml/ns/javaee"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
> http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
> version="3.0"
> metadata-complete="true">
>
> <filter>
> <filter-name>foo</filter-name>
> <filter-class>com.MyServletAndFilter</filter-class>
> </filter>
>
> <filter-mapping>
> <filter-name>foo</filter-name>
> <url-pattern>/filter/*</url-pattern>
> </filter-mapping>
>
> <servlet>
> <servlet-name>bar</servlet-name>
> <servlet-class>com.MyServletAndFilter</servlet-class>
> </servlet>
>
> <servlet-mapping>
> <servlet-name>bar</servlet-name>
> <url-pattern>/servlet/*</url-pattern>
> </servlet-mapping>
>
> </web-app>
>
> public class MyServletAndFilter extends HttpServlet implements Filter {
> @Override
> public void init(FilterConfig filterConfig) {}
>
> @Override
> public void doFilter(ServletRequest request, ServletResponse response,
> FilterChain chain) throws IOException, ServletException {
> doYourStuff((HttpServletRequest) request, (HttpServletResponse)
> response);
> }
>
> @Override
> protected void doGet(HttpServletRequest req, HttpServletResponse resp)
> throws ServletException, IOException {
> doYourStuff(req, resp);
> }
>
> private void doYourStuff(HttpServletRequest req, HttpServletResponse
> response) throws IOException {
> response.setContentType("text/plain");
> response.setStatus(400);
> response.getWriter().println("TEEEEEST");
>
> }
> }
>
> On Wed, Mar 9, 2011 at 4:36 PM, Ryan Stewart <rds6235_at_gmail.com> wrote:
>
>> It could be related to the filter, though I can't say how. I'm using the
>> Jersey SpringServlet (Spring-enabled subclass of ServletContainer) as a
>> servlet instead of as a filter. I also don't do any Jersey configuration in
>> the web.xml (other than creating the servlet). Everything is in the Spring
>> config. Is there a particular reason you're running it as a filter? It seems
>> that by its nature of serving up content, it belongs more properly as a
>> servlet than as a filter. Also, why do you have ServletContainer configured
>> as both a servlet and a filter below? I can't think of anything else that
>> might help right now.
>>
>>
>> On Wed, Mar 9, 2011 at 2:59 AM, Casper Bang <casper.bang_at_gmail.com>wrote:
>>
>>> Thanks for the suggestion Ryan, but I could observe no change in
>>> behavior. I wonder if it has something to do with the fact, or the way, that
>>> I am using Jersey as a filter.
>>>
>>> <servlet>
>>> <servlet-name>ServletAdaptor</servlet-name>
>>>
>>> <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
>>> <load-on-startup>1</load-on-startup>
>>> </servlet>
>>>
>>> <servlet-mapping>
>>> <servlet-name>ServletAdaptor</servlet-name>
>>> <url-pattern>/resources/*</url-pattern>
>>> </servlet-mapping>
>>>
>>> <filter>
>>> <filter-name>LoggingCachingFilter</filter-name>
>>>
>>> <filter-class>com.brunata.webmon.ws.LoggingCachingFilter</filter-class>
>>> <init-param>
>>> <param-name>cacheName</param-name>
>>> <param-value>LoggingCachingFilter</param-value>
>>> </init-param>
>>> </filter>
>>>
>>> <filter-mapping>
>>> <filter-name>LoggingCachingFilter</filter-name>
>>> <url-pattern>/*</url-pattern>
>>> </filter-mapping>
>>>
>>> <filter>
>>> <filter-name>ws-webmon</filter-name>
>>>
>>> <filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
>>> <init-param>
>>>
>>> <param-name>com.sun.jersey.config.property.packages</param-name>
>>> <param-value>com.brunata.webmon.ws.resources;</param-value>
>>> </init-param>
>>> <init-param>
>>>
>>> <param-name>com.sun.jersey.config.property.JSPTemplatesBasePath</param-name>
>>> <param-value>/WEB-INF/jsp</param-value>
>>> </init-param>
>>> <init-param>
>>>
>>> <param-name>com.sun.jersey.config.property.WebPageContentRegex</param-name>
>>>
>>> <param-value>/(static|img|js|css|(WEB-INF/jsp))/.*</param-value>
>>> </init-param>
>>> <init-param>
>>>
>>> <param-name>com.sun.jersey.config.feature.ImplicitViewables</param-name>
>>> <param-value>false</param-value>
>>> </init-param>
>>> <init-param>
>>>
>>> <param-name>com.sun.jersey.config.feature.Redirect</param-name>
>>> <param-value>true</param-value>
>>> </init-param>
>>> </filter>
>>>
>>> <filter-mapping>
>>> <filter-name>ws-webmon</filter-name>
>>> <url-pattern>/*</url-pattern>
>>> </filter-mapping>
>>>
>>> /Casper
>>>
>>> On Tue, Mar 8, 2011 at 11:51 PM, Ryan Stewart <rds6235_at_gmail.com> wrote:
>>>
>>>> Have you tried with other content types than text/plain? Maybe try
>>>> application/xml. I use Tomcat as a servlet container, and I've never seen
>>>> the behavior you're describing on a 400 response. The only thing that jumps
>>>> out at me is that I don't use text/plain for the response.
>>>>
>>>>
>>>> On Tue, Mar 8, 2011 at 11:11 AM, Casper Bang <casper.bang_at_gmail.com>wrote:
>>>>
>>>>> The closest related issue in the list history seems to be the
>>>>> following:
>>>>> http://java.net/projects/jersey/lists/users/archive/2008-01/message/88
>>>>>
>>>>> As expected, providing a custom error-page did not work - it's never
>>>>> consulted.
>>>>>
>>>>> On Tue, Mar 8, 2011 at 4:30 PM, Casper Bang <casper.bang_at_gmail.com>wrote:
>>>>>
>>>>>> I am mapping a custom ParserException to HTTP error 400 "Bad Request"
>>>>>> with a message/reason like the following:
>>>>>>
>>>>>> @Provider
>>>>>> public class ParserExceptionMapper implements
>>>>>> ExceptionMapper<ParserException> {
>>>>>> @Override
>>>>>> public Response toResponse(ParserException ex) {
>>>>>> return Response.status(400)
>>>>>> .entity("TEEEEEST")
>>>>>> .type("text/plain")
>>>>>> .build();
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> But for some reason my deployment server (a Tomcat 6.0.29) omits the
>>>>>> message, even if the default error page clearly has support for it:
>>>>>>
>>>>>> HTTP Status 400 -
>>>>>> ------------------------------
>>>>>>
>>>>>> *type* Status report
>>>>>>
>>>>>> *message* **
>>>>>>
>>>>>> *description* *The request sent by the client was syntactically
>>>>>> incorrect ().*
>>>>>>
>>>>>>
>>>>>> A unit-test using Grizzly shows that Jersey is indeed sending
>>>>>> the appropriate response back:
>>>>>>
>>>>>> assertEquals( 400,
>>>>>> response.getClientResponseStatus().getStatusCode() );
>>>>>>
>>>>>> assertEquals("Bad Request",
>>>>>> response.getClientResponseStatus().getReasonPhrase());
>>>>>>
>>>>>> assertEquals("TEEEEEST", response.getEntity(String.class));
>>>>>>
>>>>>>
>>>>>> Which makes me wonder whether anyone on this list is familiar with
>>>>>> container rewrites of error responses, perhaps even Tomcat specifically. The
>>>>>> only thing I can think of trying, is providing my very own error page via
>>>>>> error-page declarations in web.xml but my gut feeling is that it won't help
>>>>>> since - again - the default error page already has support for showing
>>>>>> message/reason entity/payload.
>>>>>>
>>>>>> Any pointers and suggestions welcomed.
>>>>>>
>>>>>> /Casper
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>