Нет подходящего HttpMessageConverter для типа контента application / json; charset = UTF-8 - PullRequest
0 голосов
/ 23 мая 2019

Я получаю исключение в заголовке, даже после добавления всего кода, найденного в сети в других решениях (я добавил HttpMessageConverters, а также заголовок APPLICATION_JSON accept.)

public MyObject myMethod(String arg) {
    String uri = BASE_URI + "/var?arg=" + arg;

    restTemplate.setMessageConverters(getMessageConverters());

    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    HttpEntity<String> entity = new HttpEntity<>(headers);

    ResponseEntity<MyObject> response = restTemplate.exchange(uri, HttpMethod.GET, entity, MyObject.class);
    MyObject resource = response.getBody();

    return resource;

}

private List<HttpMessageConverter<?>> getMessageConverters() {
    List<HttpMessageConverter<?>> converters =
            new ArrayList<>();
    converters.add(new MappingJackson2HttpMessageConverter());
    converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
    return converters;
}

MyObject:

public class MyObject {

    private String test;
    //more fields

    @JsonCreator
    public MyObject(String test) { //more args
        this.test = test;
        //more assignments
    }

У кого-нибудь есть идеи?

РЕДАКТИРОВАТЬ: соответствующие зависимости в pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.8</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.8</version>
</dependency>

Ответы [ 2 ]

0 голосов
/ 23 мая 2019

По умолчанию spring или springboot настраивают следующие конвертеры сообщений при запуске:

ByteArrayHttpMessageConverter – converts byte arrays
StringHttpMessageConverter – converts Strings
ResourceHttpMessageConverter – converts org.springframework.core.io.Resource for any type of octet stream
SourceHttpMessageConverter – converts javax.xml.transform.Source
FormHttpMessageConverter – converts form data to/from a MultiValueMap<String, String>.
Jaxb2RootElementHttpMessageConverter – converts Java objects to/from XML
MappingJackson2HttpMessageConverter – converts JSON
MappingJacksonHttpMessageConverter – converts JSON
AtomFeedHttpMessageConverter – converts Atom feeds 
RssChannelHttpMessageConverter – converts RSS feeds

Но для добавления конвертеров Джексона пружина должна обнаружить, что jackson присутствует в classpath, поэтому, добавив в приложение зависимость Джексона, конвертер должен быть настроен автоматически, если вы явно не запретите автоматическую настройку с помощью аннотации @EnableWebMVC.

Также убедитесь, чтоесли вы используете конечную точку покоя, метод аннотируется правильно, то есть либо для класса используется @RestController, либо вам нужно будет предоставить аннотацию @ResponseBody, чтобы указать пружине, что это конечная точка покоя.

Из документации:

Аннотация, указывающая, что параметр метода должен быть привязан к телу веб-запроса.Тело запроса передается через HttpMessageConverter для разрешения аргумента метода в зависимости от типа содержимого запроса.По желанию, автоматическая проверка может быть применена путем аннотирования аргумента @Valid.Поддерживается для аннотированных методов-обработчиков в средах сервлетов.

0 голосов
/ 23 мая 2019

Обратите внимание, что для того, чтобы HttpMessageConverter имел право на сопоставление, его метод canRead должен возвращать true.

В случае AbstractJackson2HttpMessageConverter (родительского элемента MappingJackson2HttpMessageConverter), он проверяет не только MediaType, но и может ли Джексон десериализовать объект.

@Override
public boolean canRead(Type type, @Nullable Class<?> contextClass, @Nullable MediaType mediaType) {
    if (!canRead(mediaType)) {
        return false;
    }
    JavaType javaType = getJavaType(type, contextClass);
    AtomicReference<Throwable> causeRef = new AtomicReference<>();
    if (this.objectMapper.canDeserialize(javaType, causeRef)) {
        return true;
    }
    logWarningIfNecessary(javaType, causeRef.get());
    return false;
}

Теперь я считаю, что ваш JsonCreator неверен.

ПРИМЕЧАНИЕ: при аннотировании методов-создателей (конструкторов, фабричных методов), метод должен быть либо:

  • Метод конструктора / фабрики с одним аргументом без аннотации JsonProperty для аргумента: если это так, то это так называемый «создатель делегата», и в этом случае Джексон сначала связывает JSON с типом аргумента, а затем вызывает создателя. Это часто используется вместе с JsonValue (используется для сериализации).
  • Метод конструктора / фабрики, где каждый аргумент аннотируется с помощью JsonProperty или JacksonInject, чтобы указать имя свойства для привязки к

См. Также Почему, когда конструктор аннотируется @JsonCreator, его аргументы должны аннотироваться @JsonProperty?

...