I am trying to invoke this exception mapper to return a 404 not found response but it keeps returning 500 internal error. Jersey version is 2.22.1. Code snippet below. Appreciate all help.
Thanks.
Exception mapper class.
package org.learn.rest.messengerdemo.exception;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class DataNotFoundExceptionMapper implements ExceptionMapper<DataNotFoundException>{
@Override
public Response toResponse(DataNotFoundException ex) {
return Response.status(Response.Status.FORBIDDEN).build();
}
}
Exception Class.
package org.learn.rest.messengerdemo.exception;
public class DataNotFoundException extends RuntimeException{
private static final long serialVersionUID = 2176642539344388961L;
public DataNotFoundException(String message)
{
super(message);
}
}
Service class's method that throws.
public Message getMessage(long messageId) {
Message message = messages.get(messageId);
if(message == null)
{
throw new DataNotFoundException("Message with id " + messageId + " not found");
}
return message;
}
And the resource class.
@GET
@Path("/{messageId}")
public Message getMessage(@PathParam("messageId") long messageId) {
return messageService.getMessage(messageId);
}
Looking at the web.xml
from your previous question, you have this
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.learn.rest.messengerdemo.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
What this init-parm jersey.config.server.provider.packages
says is that Jersey should scan the named package for @Path
annotated resource class and @Provider
annotated provider classes and register them.
You only have the resources package org.learn.rest.messengerdemo.resources
listed, but you ExceptionMapper
is in a different package. The default behavior is to scan recursively, meaning sub-packages also. So if you listed org.learn.rest.messengerdemo
instead, you would hit both the resources package and the exceptions package. Or you could list both packages, separated by comma or semi-colon. Either way would work
<param-value>org.learn.rest.messengerdemo</param-value>
<!-- OR -->
<param-value>
org.learn.rest.messengerdemo.resources,
org.learn.rest.messengerdemo.exception
</param-value>
Please note that this is not problem of annotation. i have seen people given comments that due to @Provider annotation its not registered, if you have imported correct provider it will work. Please find my solution below
I have encountered the same issue while develop sample REST API. While creating REST API i have given base package name like org.manish.rest.message
, I supposed to create every other packages under the base package like this
- model -
org.manish.rest.message.model
- database -
org.manish.rest.message.database
- resource -
org.manish.rest.message.resource
in web.xml init param was given like this
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.manish.rest.message</param-value>
</init-param>
It means, i have registered my base package in web.xml, what ever package i will create under this; will be consider by JAX-RS based on my call and requirement. But when i created my exception package by mistake i put package name org.manish.rest.exception. Since this was not registered in web.xml so my complete exception class was not considered to handle exception by JAX-RS. As a correction, i have just modified my exception package name from org.manish.rest.exception
to org.manish.rest.message.exception
After that i executed once in post man and i got expected result.
Hope this can solve your query.
Thanks Manish
I'd like to propose another option ...
change the mapper package to match the resource package where the exception could normally be caught.
Assuming the resource classes package is:
package org.learn.rest.messengerdemo.resources;
change the mapper class package from:
package org.learn.rest.messengerdemo.exception;
to:
package org.learn.rest.messengerdemo.resources;
That way you won't be fiddling with framework generated files or uncommon syntax.
I still don't grasp why a try/catch isn't used but I'm rebuilding my Java knowledge so I won't inject an opinion or request any. If its current practice then I'll learn that soon enough. And mappers are an interesting opportunity at that.