JAX-RS Джерси ExceptionMappers Определенное пользователем исключение

Я новичок в этом, пытаясь добиться чтения некоторых документов, но не работает, пожалуйста, несите меня.

Я создал UserNotFoundMapper с помощью ExceptionMappers следующим образом:

public class UserNotFoundMapper implements ExceptionMapper<UserNotFoundException> {

@Override
public Response toResponse(UserNotFoundException ex) {
    return Response.status(404).entity(ex.getMessage()).type("text/plain").build();
}

}

Это в моей службе:

@GET
@Path("/user")
public Response getUser(@QueryParam("id") String id) throws UserNotFoundException{
    //Some user validation code with DB hit, if not found then
    throw new UserNotFoundException();
}

UserNotFoundException - это User-Defined Исключение.

Я пробовал это:

public class UserNotFoundException extends Exception {
       //SOME block of code 
}

Но когда я вызываю службу, UserDefinedExceptionMapper не вызывается. Кажется, я мог что-то пропустить в UserDefinedException. Как определить это исключение?

Пожалуйста, дайте мне знать, как определить UserNotFoundException.

Ответ 1

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

@Provider
public class UserNotFoundMapper implements
        ExceptionMapper<UserNotFoundException> {
    @Override
    public Response toResponse(UserNotFoundException ex) {
        return Response.status(404).entity(ex.getMessage()).type("text/plain")
                .build();
    }
}

Ответ 2

Одно небольшое замечание, попробуйте использовать Response.Status.NOT_FOUND, а не использовать 404 и т.д. Код будет более читабельным и менее подверженным опечаткам, то же самое касается "text/plain". Ниже приведен код, который будет обрабатывать исключение, как вы упомянули. О, и еще одна вещь не забыть комментировать ваш метод @Produces (MediaType.TEXT_PLAIN) в вашем интерфейсе

    public class UserNotFoundException extends Exception {
        //...
    }

    public class UserServiceImpl implements UserService {

        @Override 
        public Response getUser(@QueryParam("id") String id) {
            final Response response;
            try{
                // call user method
                //if everything is ok
                response = Response.status(Response.Status.OK).entity(whateverYouWant).type(MediaType.TEXT_PLAIN).build();
            } catch(UserNotFoundException ex) {         
                response = new UserNotFoundMapper().toResponse(ex);
            }

            return response;
        }
    }

    In client slide you can check 

    public static boolean isUserExists(final Response serverResp) {
        return serverResp != null && serverResp.getStatus() == Response.Status.NOT_FOUND.getStatusCode();
    }

Ответ 3

То, что я обычно делаю при создании API, создает свое собственное исключение, которое простирается от RuntimeException, поэтому мне не обязательно ловить мое исключение.

Вот пример:

ПРИМЕЧАНИЕ. Я использую JAX-RS с Джерси.

Первый: создайте мое собственное исключение, которое выходит из RuntimeException.

public class ExceptionName extends RuntimeException {

private int code;
private String message;

public int getCode(){
    return code;
}

public String getMessage(){
    return message;
}

public ExceptionName(int code, String message) {
    this.code = code;
    this.message = message;
}

}

Также реализуем ExceptionMapper

@Provider
public class ExceptionName implements ExceptionMapper<ExceptionName>{

    @Override
    public Response toResponse(ExceptionName exception) {
        return Response.status(exception.getCode()).entity(exception.getMessage()).build();
    }

}

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

throw new ExceptionName(500,"there was an error with something here");