users@jersey.java.net

Re: [Jersey] How to handle exceptions when we need to display error msg in the same page that was served by GET

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 21 Oct 2009 13:26:16 +0200

HI Dinesh,

Q. 1:
It is OK to pass the resource instance if you like.

The general design question i have is should the model be an instance
of the resource class or an instance if the exception?

Not that the following is equivalent:

   throw new WebApplicationException(Response.serverError().entity(new
Viewable(JSP_PAGE, this)).build());

It does not seem that using MyBrocadeExceptionMapper and
MyBrocadeException is giving much.

Perhaps the following would be more uself:

   throw new ViewableException(new Viewable(JSP_PAGE, this));

and have a ViewableExceptionMapper which does the following:

@Provider
public class ViewableExceptionMapper implements
javax.ws.rs.ext.ExceptionMapper<ViewableException>{
     public Response toResponse(ViewableException ex) {
       return Response.serverError().entity(ex.getViewable()).build();
     }
}

Alternatively it may be more appropriate to have specific exceptions
bound to a particular JSP page. For example:

   throw new InvalidAccessCode();

public class InvalidAccessCode extends ViewableException {
   public InvalidAccessCode(...) {
     super("/jsp/myAccount/siteAccessPartial.jsp");
   }
}

@Provider
public class ViewableExceptionMapper implements
javax.ws.rs.ext.ExceptionMapper<ViewableException>{
     public Response toResponse(ViewableException ex) {
       return Response.serverError().entity(ex.getViewable()).build();
     }
}

My gut feeling is it is probably best in such cases for the model to
be the exception instance with a well defined interface for accessing
the error information (even if the exception defers to state of a
resource instance). As this would allow for better reuse.



Q. 2:
I have not done any performance testing in this regard. Each sub-
resource stage requires the use of regexes, reflective method
invocation etc. I suspect the cost is not that huge in the context of
the complete app. But the only way for you to tell is to measure
yourself :-) and see if the performance is acceptable for your
requirements.


Paul.

On Oct 21, 2009, at 11:04 AM, Dinesh Narayanan wrote:

> Hello Paul,
>
> Question 1:
> I was trying to implement exception handling for my project based
> on the following email thread http://markmail.org/message/vicjp4eyqqwx7brd#query
> :ExceptionMapper%20and%20Viewable+page:1+mid:zxuftddvp7ugltnw+state:results
>
> And I was wondering if there is a better way to do this. I have a
> jsp (siteAccessPartial.jsp) which displays some entity info and also
> has some form fields. Now the user enters some form fields (say some
> textbox fields in this case) and clicked on submit. I do a POST to
> the appropriate resource, and one of my service threw an application
> exception (due to some business validation failure in this case), I
> need to return back a 500 (with an appropriate error message) and I
> need to show this error message in the same
> jsp(siteAccessPartial.jsp).
>
> The Question is that is it OK to pass my resource instance to the
> Exception class or is there a better way to do it?
>
> Here is the sample code snippet:
>
> public class SiteAccessResource {
> private static final Logger logger =
> Logger.getLogger(SiteAccessResource.class
> private static final String JSP_PAGE = "/jsp/myAccount/
> siteAccessPartial.jsp";
> // this entity info be displayed in the jsp
> private List<UserAccess> userAccessList = new
> ArrayList<UserAccess>();
> private final UserAccessDAO userAccessDAO;
>
> @Inject
> public SiteAccessResource(UserAccessDAO userAccessDAO){
> this.userAccessDAO = userAccessDAO;
> }
>
> @GET
> @Produces("text/html")
> public Viewable get(@QueryParam("userName) String userName) {
> userAccessList = userAccessDAO.getUserAccess(userName);
> return new Viewable(JSP_PAGE, this);
> }
>
> @POST
> @Produces("text/html")
> public Viewable post(@FormParam("key1") String siteAccessCode ){
> // this will throw MyBrocadeException if siteAccessCode does not
> exist in DB
> if( userAccessDAO.checkIfCodeisValid(siteAccessCode)) {
> //TODO - Paul Is this correct?
> throw new MyBrocadeException("error.siteAccessCode",
> "Invalid site access code", JSP_PAGE, this);
> } else {
> // store the entry in db
> userAccessDAO.createUserAcces(siteAccessCode);
> }
> return new Viewable(JSP_PAGE, this);
> }
> }
>
> MyBrocadeException class:
>
> public class MyBrocadeException extends RuntimeException{
> private final String errorMessage;
> private final String errorCode;
> private final String jspName;
> private final Object o;
>
> public MyBrocadeException(String errorCode, String errorMessage,
> String jspName, Object obj) {
> this.errorCode = errorCode;
> this.errorMessage = errorMessage;
> this.jspName = jspName;
> this.o = obj;
> }
>
> public String getErrorMessage() {
> return errorMessage;
> }
>
> public String getErrorCode() {
> return errorCode;
> }
>
> public String getJspName() {
> return jspName;
> }
>
> public Object getO() {
> return o;
> }
> }
>
> MyProvider class:
> @Provider
> public class MyBrocadeExceptionMapper implements
> javax.ws.rs.ext.ExceptionMapper<MyBrocadeException>{
> public Response toResponse(MyBrocadeException exception) {
> return Response.serverError().entity(new
> Viewable(exception.getJspName(),exception.getO())).build();
> }
> }
>
>
> Question no 2: Are there any performance overhead if we use
> excessive subResource locators or is this negligible.
>
> Thanks
> Dinesh