问题
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);
}
回答1:
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>
回答2:
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
回答3:
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.
来源:https://stackoverflow.com/questions/33386225/jersey-exceptionmapper-not-being-invoked