Hi there :)
I made i little hack (following your example for the 500 :) ) to solve the 404 error:
public class HackDumpFilter implements ContainerResponseFilter{
private final static Logger logger = LoggerFactory.getLogger(HackDumpFilter.class);
public ContainerResponse filter(ContainerRequest request,ContainerResponse response){
if(response.getStatus() == 500){
response.setEntity(null);
response.getHttpHeaders().put("Content-Type",null);
}else if(response.getStatus() == 404){
response.setEntity(new Viewable("/jsp/notFound.jsp",null));
}
return response;
}
}
Hope it helps somebody else :)
Jordi
From: noseya_at_hotmail.com
To: users_at_jersey.dev.java.net
Date: Fri, 16 Oct 2009 11:02:05 +0200
Subject: RE: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable
Great test Paul!
But, did you try to turn your resource into an EJB ? :)
Results change:
1) Now Fails with a complete dump, escaping the servlet container
2) Same like not ejb
3) Same like not ejb
My resource's are Stateless beans :(
Sorry for the delay, i got a bit crazy with maven and failures deploying the app with an EJB (your web.xml was 2.4 version and I didnt noticed :)) )
Thanks,
Jordi
Date: Thu, 15 Oct 2009 12:50:44 +0200
From: Paul.Sandoz_at_Sun.COM
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable
H Jordi,
I have attached a very simple project that exercises many of the possible ways of mapping exceptions.
Hopefully it should be fairly intuitive to understand. The main index.jsp provides links to click on that results in various forms of error pages.
Results of investigation:
1) Jersey will propagate runtime exceptions to the servlet layer if those exceptions are not mapped by an ExceptionMapper. Those exceptions can then be mapped using an error page. See the error page SecurityExceptionErrorPage.jsp and the link:
http://localhost:8080/exceptions/webresources/myresource/runtime?ex=java.lang.SecurityException
supported by the following resource method:
@Path("runtime") @GET @Produces("text/plain") public String runtimeException(@QueryParam("ex") String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class c = Class.forName(className, true, this.getClass().getClassLoader()); RuntimeException re = (RuntimeException)c.newInstance(); if (true) throw re; return "Hi there!"; }
2) Jersey will propagate checked exceptions wrapped in a MappableContainerException to the servlet layer. That exception can then be mapped using an error page and the cause can be extracted. See the error page MappableContainerException.jsp and the links:
http://localhost:8080/exceptions/webresources/myresource/checked/ioexception http://localhost:8080/exceptions/webresources/myresource/checked/myexception
supported by the following resource methods: @Path("checked/ioexception") @GET @Produces("text/plain") public String checkedIOException() throws IOException { if (true) throw new IOException(); return "Hi there!"; }
public static class MyException extends Exception { }
@Path("checked/myexception") @GET @Produces("text/plain") public String checkedMyException() throws MyException { if (true) throw new MyException(); return "Hi there!"; }
3) If Jersey sets the status code in the servlet response it is not possible for error pages to be mapped to the status code. See the links:
http://localhost:8080/exceptions/404 http://localhost:8080/exceptions/webresources/404
The first link is mapped to the 404 bound error page, NotFound.jsp. The the second link returns the default GF 404 error page. The first works because the Jersey servlet is not invoked.
I verified i get the same behavior with a simple servlet if one only sets the status code to 404. However, i could get this to work if instead of calling HttpServletResponse.setStatus i call HttpServletResponse.sendError.
Conclusions:
Result 1 is working correctly.
Result 2 could be improved by unwrapping the cause in the MappableContainerException and re-throwing the cause wrapped in ServletException.
Result 3 might be a bug in the servlet container. I am not quite sure how to work around it. For example if using sendError then any headers that have been added are ignored. It seems to me the correct behavior would be to map status codes if no entity is present (nor no bytes have been written to the response output stream).
Paul.
En tu material escolar no puede faltar el nuevo Pack de Emoticonos Vuelta al Cole ¡Descárgatelo gratis! Es muy divertido
_________________________________________________________________
Vive toda la experiencia de Messenger con Orange desde tu Blackberry ¡Descúbrelo!
http://serviciosmoviles.es.msn.com/messenger/blackberry.aspx
--_f65c81ad-f1ed-4d07-bdd2-8630cec68f96_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
Hi there :)<br><br>I made i little hack (following your example for the 500 :) ) to solve the 404 error:<br><br>public class HackDumpFilter implements ContainerResponseFilter{<br><br> private final static Logger logger = LoggerFactory.getLogger(HackDumpFilter.class);<br> <br> public ContainerResponse filter(ContainerRequest request,ContainerResponse response){<br> <br> if(response.getStatus() == 500){<br> response.setEntity(null);<br> response.getHttpHeaders().put("Content-Type",null);<br> }else if(response.getStatus() == 404){<br> response.setEntity(new Viewable("/jsp/notFound.jsp",null));<br> }<br> return response;<br> }<br>}<br><br>Hope it helps somebody else :)<br><br>Jordi<br><br><hr id="stopSpelling">From: noseya_at_hotmail.com<br>To: users_at_jersey.dev.java.net<br>Date: Fri, 16 Oct 2009 11:02:05 +0200<br>Subject: RE: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable<br><br>
<style>
.ExternalClass .ecxhmmessage P
{padding:0px;}
.ExternalClass body.ecxhmmessage
{font-size:10pt;font-family:Verdana;}
</style>
Great test Paul!<br><br>But, did you try to turn your resource into an EJB ? :)<br><br>Results change:<br><br>1) Now Fails with a complete dump, escaping the servlet container<br>2) Same like not ejb<br>3) Same like not ejb<br><br>My resource's are Stateless beans :(<br><br>Sorry for the delay, i got a bit crazy with maven and failures deploying the app with an EJB (your web.xml was 2.4 version and I didnt noticed :)) )<br><br>Thanks,<br><br>Jordi<br><br><hr id="ecxstopSpelling">Date: Thu, 15 Oct 2009 12:50:44 +0200<br>From: Paul.Sandoz@Sun.COM<br>To: users@jersey.dev.java.net<br>Subject: Re: [Jersey] Doh! Re: [Jersey] ExceptionMapper and Viewable<br><br><div>H Jordi,</div><div><br></div><div>I have attached a very simple project that exercises many of the possible ways of mapping exceptions.</div><div><br></div><div>Hopefully it should be fairly intuitive to understand. The main index.jsp provides links to click on that results in various forms of error pages.</div><div><br></div><div>Results of investigation:</div><div><br></div><div>1) Jersey will propagate runtime exceptions to the servlet layer if those exceptions are not mapped by</div><div> an ExceptionMapper. Those exceptions can then be mapped using an error page. </div><div> See the error page SecurityExceptionErrorPage.jsp and the link:</div><div> </div><div> <a href="
http://localhost:8080/exceptions/webresources/myresource/runtime?ex=java.lang.SecurityException">
http://localhost:8080/exceptions/webresources/myresource/runtime?ex=java.lang.SecurityException</a></div><div><br></div><div> supported by the following resource method:</div><div><br></div><div> @Path("runtime")</div><div> @GET</div><div> @Produces("text/plain")</div><div> public String runtimeException(@QueryParam("ex") String className) </div><div> throws ClassNotFoundException, InstantiationException, IllegalAccessException {</div><div> Class c = Class.forName(className, true, this.getClass().getClassLoader());</div><div> RuntimeException re = (RuntimeException)c.newInstance();</div><div> if (true) throw re;</div><div> return "Hi there!";</div><div> }</div><div> </div><div><br></div><div><div>2) Jersey will propagate checked exceptions wrapped in a MappableContainerException to the servlet layer.</div><div> That exception can then be mapped using an error page and the cause can be extracted.</div><div> See the error page MappableContainerException.jsp and the links:</div><div><br></div><div> <a href="
http://localhost:8080/exceptions/webresources/myresource/checked/ioexception">
http://localhost:8080/exceptions/webresources/myresource/checked/ioexception</a></div><div> <a href="
http://localhost:8080/exceptions/webresources/myresource/checked/myexception">
http://localhost:8080/exceptions/webresources/myresource/checked/myexception</a> </div><div><br></div><div> supported by the following resource methods:</div></div><div> </div><div><div> @Path("checked/ioexception")</div><div> @GET</div><div> @Produces("text/plain")</div><div> public String checkedIOException() throws IOException {</div><div> if (true) throw new IOException();</div><div> return "Hi there!";</div><div> }</div><div><br></div><div> public static class MyException extends Exception {</div><div> }</div><div><br></div><div> @Path("checked/myexception")</div><div> @GET</div><div> @Produces("text/plain")</div><div> public String checkedMyException() throws MyException {</div><div> if (true) throw new MyException();</div><div> return "Hi there!";</div><div> }</div><div><br></div><div><br></div><div>3) If Jersey sets the status code in the servlet response it is not possible for error pages to be mapped to the </div><div> status code.</div><div> See the links:</div><div><br></div><div> <a href="
http://localhost:8080/exceptions/404">
http://localhost:8080/exceptions/404</a></div><div> <a href="
http://localhost:8080/exceptions/webresources/404">
http://localhost:8080/exceptions/webresources/404</a></div><div><br></div><div> The first link is mapped to the 404 bound error page, NotFound.jsp. The the second link returns the default </div><div> GF 404 error page. The first works because the Jersey servlet is not invoked.</div><div><br></div><div> I verified i get the same behavior with a simple servlet if one only sets the status code to 404.</div><div> However, i could get this to work if instead of calling HttpServletResponse.setStatus i call </div><div> HttpServletResponse.sendError.</div><div><br></div><div> </div><div>Conclusions:</div><div><br></div><div>Result 1 is working correctly.</div><div><br></div><div>Result 2 could be improved by unwrapping the cause in the MappableContainerException and re-throwing the cause wrapped in ServletException.</div><div><br></div><div>Result 3 might be a bug in the servlet container. I am not quite sure how to work around it. For example if using sendError then any headers that have been added are ignored. It seems to me the correct behavior would be to map status codes if no entity is present (nor no bytes have been written to the response output stream).</div><div><br></div><div>Paul.</div><div><br></div><div><br></div></div><div><br></div> <br><hr>En tu material escolar no puede faltar el nuevo Pack de Emoticonos Vuelta al Cole <a href="
http://www.vivelive.com/emoticonosvueltaalcole%20%20">¡Descárgatelo gratis! Es muy divertido</a> <br /><hr />En tu material escolar no puede faltar el nuevo Pack de Emoticonos Vuelta al Cole <a href='
http://www.vivelive.com/emoticonosvueltaalcole ' target='_new'>¡Descárgatelo gratis! Es muy divertido</a></body>
</html>
--_f65c81ad-f1ed-4d07-bdd2-8630cec68f96_--