Вызов API с Java + STS, возвращающий «Тип содержимого« application / octet-stream »не поддерживается» - PullRequest
0 голосов
/ 02 июня 2018

Я работаю над частью API, которая требует вызова другого внешнего API для извлечения данных для одной из его функций.Вызов возвращал ошибку HTTP 500 с описанием «Тип содержимого« application / octet-stream »не поддерживается».Ожидается, что вызов возвратит тип 'application / json.'

Я обнаружил, что это потому, что полученный ответ не указывает явно тип содержимого в своем заголовке, даже если его содержимое отформатировано как JSON, поэтому мой API по умолчанию предположил, что это поток октетов.

Проблема в том, что я не уверен, как это исправить. Как бы мне заставить мой API обрабатывать данные, которые он получает от другого APIкак приложение / JSON, даже если другой API не указывает тип содержимого? Изменение другого API для включения атрибута contenttype в его ответ невозможно.

Код:
Класс API:

@RestController
@RequestMapping(path={Constants.API_DISPATCH_PROFILE_CONTEXT_PATH},produces = {MediaType.APPLICATION_JSON_VALUE})
public class GetProfileApi {

    @Autowired
    private GetProfile GetProfile;

    @GetMapping(path = {"/{id}"})
    public Mono<GetProfileResponse> getProfile(@Valid @PathVariable String id){
        return GetProfile.getDispatchProfile(id);

    }

Служба, вызывающая внешний API:

@Autowired
private RestClient restClient;

@Value("${dispatch.api.get_profile}")
private String getDispatchProfileUrl;

@Override
public  Mono<GetProfileResponse> getDispatchProfile(String id) {

    return Mono.just(id)
                .flatMap(aLong -> {
    MultiValueMap<String, String> headers = new HttpHeaders();
    headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
    return restClient.get(getDispatchProfileUrl, headers);
                }).flatMap(clientResponse -> {
                    HttpStatus status = clientResponse.statusCode();
                    log.info("HTTP Status : {}", status.value());
                    return clientResponse.bodyToMono(GetProfileClientResponse.class);
                    // the code does not get past the above line before returning the error
                }).map(GetProfileClientResponse -> {
                    log.debug("Response : {}",GetProfileClientResponse);
                    String id = GetProfileClientResponse.getId();

                    log.info("SubscriberResponse Code : {}",id);
                    return GetProfileResponse.builder()
                            // builder call to be completed later
                            .build();
        }); 
}

Метод GET для RestClient:

public <T> Mono<ClientResponse> get(String baseURL, MultiValueMap<String,String> headers){
    log.info("Executing REST GET method for URL : {}",baseURL);

    WebClient client = WebClient.builder()
            .baseUrl(baseURL)
            .defaultHeaders(httpHeaders -> httpHeaders.addAll(headers))
            .build();
    return client.get()
            .exchange();

}

Одно из попыток, которое я попытался, было установить produces= {MediaType.APPLICATION_JSON_VALUE} в@RequestMapping API для produces= {MediaType.APPLICATION_OCTET_STREAM_VALUE}, но это вызвало другую ошибку, HTTP 406. Недопустимо. Я обнаружил, что сервер не может предоставить клиенту данные в запрошенном представлении, bно я не мог понять, как это исправить.

Как бы я мог успешно обработать ответ как JSON, даже если он не имеет типа содержимого?

Надеюсь, я сформулировал свой вопрос достаточно хорошо, меня как бы засунули в это, и я все еще пытаюсь понять, что происходит.

1 Ответ

0 голосов
/ 02 июня 2018

Используете ли вы библиотеку Джексона или библиотеку jaxb для маршалинга / демаршаллинга?

Попробуйте аннотировать класс сущности Mono с помощью @XmlRootElement и посмотрите, что произойдет.

...