2016-12-23 9 views
1

Я использую JEx-RS jersey ExceptionMapper, и мне интересно, есть ли способ узнать внутри метода toResponse(), какой метод (из API) выбрасывает исключение.JAX-RS трикотаж ExceptionMapper: как узнать метод, который выбрал исключение

Пример (фиктивный код)

@javax.ws.rs.Path(“/bookstore/books/{bookID}”) 
public class Book { 
    @javax.ws.rs.GET 
    public String informationMethod(String user) { 
     ... 
      throw new Exception("Error"); 
     ....  
    }  
} 



@Provider 
public class SomeMapper implements ExceptionMapper<Exception> { 
    @Override 
    public Response toResponse(Exception ex) { 

     //a way to get the method name that threw the exception. 
     //In the above example is: informationMethod. 
     String methodName = //informationMethod 

     return Response.status(500).entity(ex.getMessage()).type("text/plain") 
       .build(); 
    } 
} 
+0

Почему вы хотите сделать это? Как правило, вы должны использовать разные типы исключений для генерации различных ответов с помощью разных механизмов отображения исключений. Разве это не хорошее решение для вас? – sisyphus

+0

Вы никогда не должны раскрывать свой backend-компонент в своем ответе (например, java-пакеты или класс или методы или строку кодов), вместо этого используйте код состояния http или настройте тело ответа с соответствующим сообщением. – richersoon

+0

Спасибо за ваш комментарий, это хорошее решение, но я действительно хочу знать, какой метод выбрал исключение. Мне нужно это, например: для регистрации имени метода. –

ответ

0

Вы можете использовать следующий код для входа исключения из которого он был выброшен

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 RuntimeExceptionMapper implements ExceptionMapper<RuntimeException> { 
private static final Logger logger = Logger.getLogger(yourmodule); 
    @Override 
    public Response toResponse(RuntimeException ex) { 
     // TODO Auto-generated method stub 
    logger.log(ex); 
     return Response.status(Status.BAD_REQUEST).entity(ex.getMessage()).build(); 
    } 

} 
+0

Спасибо за ваш ответ, но когда я регистрирую свое исключение, он не показывает, что я хочу. Мне очень нужна информация о методе, который выбрал исключение, по крайней мере, имя метода. Есть способ получить это? –

+0

Почему вы хотите вести журнал до тех пор, пока он не достигнет контроллера. Вы можете зарегистрировать ошибку только на уровне сервиса. –

+0

Спасибо за ваш комментарий, но моя цель - не регистрировать информацию. Мой вопрос: есть ли способ узнать, какой метод выбрал исключение на данный момент (ExceptionMapper).Мне нужна информация, связанная с методом, который выбрал исключение. Мне нужно хотя бы имя метода. –

2

Вы можете предоставить некоторую информацию из контекста к вашим ExcpetionMapper.

package your.rest.pckg; 

import java.lang.reflect.Method; 
import java.net.URI; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.ws.rs.Path; 
import javax.ws.rs.container.ResourceInfo; 
import javax.ws.rs.core.Context; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.MultivaluedMap; 
import javax.ws.rs.core.Response; 
import javax.ws.rs.core.UriBuilder; 
import javax.ws.rs.core.UriInfo; 
import javax.ws.rs.ext.ExceptionMapper; 
import javax.ws.rs.ext.Provider; 

@Provider 
public class SomeMapper 
       implements ExceptionMapper<Exception> 
{ 

    @Context private HttpServletRequest request; 

    @Context private HttpServletResponse response; 

    @Context private ResourceInfo resourceInfo; 

    @Context private UriInfo uriInfo; 

    @Override 
    public Response toResponse(Exception ex) 
    { 
     String method = request.getMethod(); 
     String pathInfo = request.getPathInfo(); 

     Class<?> resourceClass = resourceInfo.getResourceClass(); 
     Method resourceMethod = resourceInfo.getResourceMethod(); 
     URI resourcePath = getResourcePath(resourceClass, resourceMethod); 

     URI requestUri = uriInfo.getRequestUri(); 
     MultivaluedMap<String, String> pathParams = uriInfo.getPathParameters(); 
     MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters(); 

     // define your object to provide data through response 
     Object responseEntity = ex.getMessage(); 

     // do your stuff 

     return Response.status(Response.Status.INTERNAL_SERVER_ERROR) 
         .entity(responseEntity) 
         .type(MediaType.APPLICATION_JSON) 
         .build(); 
    } 

    private static URI getResourcePath(Class<?> clazz, Method method) 
    { 
     if (clazz == null || !clazz.isAnnotationPresent(Path.class)) 
     { 
      return null; 
     } 

     UriBuilder builder = UriBuilder.fromResource(clazz); 
     if (method != null && method.isAnnotationPresent(Path.class)) 
     { 
      builder.path(method); 
     } 

     return builder.build(); 
    } 
} 

См

Вместо Excpetion вы можете также отобразить Throwable.

Чтобы пройти через WebApplicationExcpetion с просто добавить следующее, если положение в НАЧАЛЕ toResponse() тела:

if (ex instanceof WebApplicationException) 
{ 
    return (((WebApplicationException) ex).getResponse()); 
} 

Вы можете также использовать все @Context полей в классе ресурсов Book.

0

Inject в свой ExceptionMapper картографа:

@Context private ResourceInfo resourceInfo; 

, как это было предложено и сделать следующее, чтобы получить имя метода:

resourceInfo.getResourceMethod()