Используя jersey, как я могу создать json для ошибок и поток октетов для успеха - PullRequest
1 голос
/ 19 июня 2020

Краткая версия вопроса:

Используя Джерси, как я могу определить тип @Produces во время выполнения?

Расширенная версия вопроса:

Я написал вызов REST с использованием jersy следующим образом:

@GET
@Path("/getVideo")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
public Response getAllVideos(@QueryParam("videoID") Long videoID) throws ApiException, SQLException {
    --some code--
    Response r ...;
    return r;
}

Если пользователь предоставляет действительный videoID, тогда он должен вернуть файл mp4, следовательно, @Produces({MediaType.APPLICATION_OCTET_STREAM,. Однако, если выбрано исключение, например неверное предоставление videoID, я хочу вернуть json, описывающее исключение.

В настоящее время он работает так: если указан действительный идентификатор, он возвращает 200 с файлом mp4. Но если генерируется исключение, оно отвечает 500 и сообщением Could not find MessageBodyWriter for response object of type: com.my.package.Errors$CustomError of media type: application/octet-stream.

На основе документации Джерси тип возвращаемого ответа определяется accept тип запроса.

Моя проблема в том, что я не знаю заранее при отправке запроса, какой тип ответа я хочу получить обратно (потому что я надеюсь, что запрос будет успешным). Вместо этого я хочу определить тип ответа во время выполнения в зависимости от того, было ли создано исключение.

Как я могу это сделать?

(я думаю, что мой вопрос похож на этот вопрос , но я не использую Spring).

1 Ответ

1 голос
/ 20 июня 2020

Это, вероятно, сработает, потому что ваше исключение говорит, что не может найти автора сообщения для CustomError

@Provider
@Produces(MediaType.APPLICATION_OCTET_STREAM) //I think you will have to leave this as octet_stream so jax-rs will pick as valid message writer
public class CustomErrorBodyWriter implements MessageBodyWriter<CustomError> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
                               Annotation[] annotations, MediaType mediaType) {
        return type == CustomError.class;
    }

    @Override
    public long getSize(CustomError customError, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        // deprecated by JAX-RS 2.0 and ignored by Jersey runtime
        return 0;
    }

    @Override
    public void writeTo(CustomError customError, Class<?> type, Type genericType, Annotation[] annotations,
                        MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
                        OutputStream out) throws IOException, WebApplicationException {

        //manipulate the httpHeaders  to have content-type application/json

        //transalate customError and write it to OutputStream          

        Writer writer = new PrintWriter(out);
        writer.write("{ \"key\" : \"some random json to see if it works\" }");


        writer.flush();
        writer.close();
    }
}
...