【问题标题】:No suitable HttpMessageConverter for content type application/json;charset=UTF-8没有适合内容类型 application/json;charset=UTF-8 的 HttpMessageConverter
【发布时间】:2019-10-09 11:39:21
【问题描述】:

即使添加了在其他解决方案中在线找到的所有代码(我添加了 HttpMessageConverters 以及 APPLICATION_JSON 接受标头),我仍然在标题中遇到异常。

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;
}

我的对象:

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>

【问题讨论】:

  • 嗨,Tiberiu,您是否使用spring-boot?如果您使用的是 spring boot,则不需要添加这些消息转换器。请在pom.xmlbuild.gradle 中提供一些有关依赖项的信息。
  • pom.xml中添加了相关依赖

标签: spring-boot jackson resttemplate


【解决方案1】:

请注意,要使 HttpMessageConverter 符合映射条件,它的 canRead 方法必须返回 true。

对于 AbstractJackson2HttpMessageConverter(MappingJackson2HttpMessageConverter 的父级),它不仅检查 MediaType,还检查 Jackson 是否可以反序列化对象。

@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 进行注释,以指示要绑定到的属性名称

另见Why when a constructor is annotated with @JsonCreator, its arguments must be annotated with @JsonProperty?

【讨论】:

  • 我的pom.xml 中有jackson-corejackson-databind (2.9.8)
【解决方案2】:

默认情况下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 转换器,spring 必须检测到 jackson 存在于类路径中,因此通过向您的应用程序添加 jackson 依赖项,应自动配置转换器,除非您是使用@EnableWebMVC 注解显式阻止自动配置。

另外,请确保如果您使用的是 rest 端点,则该方法已正确注释,即为该类使用 @RestController,否则您必须提供 @ResponseBody 注释以指示 spring 它是一个休息端点。

来自文档:

指示方法参数的注释应绑定到 Web 请求的正文。请求的主体通过 HttpMessageConverter 解析方法参数取决于 请求的内容类型。可选地,自动验证可以是 通过使用 @Valid 注释参数来应用。支持 Servlet 环境中带注释的处理程序方法。

【讨论】:

    猜你喜欢
    • 2019-09-19
    • 2020-03-20
    • 2013-05-09
    • 1970-01-01
    • 2018-07-24
    • 2015-11-01
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    相关资源
    最近更新 更多