Anderson  Feng
Anderson Feng

Reputation: 141

org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/json;charset=UTF-8' not supported

The error show up when My code like this:

@Test
public void getTemplateByIdTest() throws Exception {
    client.get().uri("/template/getTemplate/7")
            .exchange()
            .expectStatus().isOk()
            .expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
            .expectBody(VtTemplateVO.class)
            .returnResult();
}

When I change my code like this,it's ok!

@Test
public void getTemplateByIdTest() throws Exception {
    client.get().uri("/template/getTemplate/7")
            .exchange()
            .expectStatus().isOk()
            .expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8)
            .expectBody(String.class)
            .returnResult();
}

Why when I use .expectBody(VtTemplateVO.class) it will say org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/json;charset=UTF-8' not supported

Somebody knows? please help,thanks

Upvotes: 13

Views: 19065

Answers (8)

stenix
stenix

Reputation: 3106

This error can occur when the web client is for any reason not able to build and assign your entity class (in your case VtTemplateVO) with java refection. There can be several reason for that such as:

  • The entity class lacks default constructor.
  • Setter or getter methods do not have public access.
  • Java module system permits reflection. The module that your entity class belongs to needs to be open.

Example of open module-info.java for entity classes:

open module com.my.domain.model { ...

Upvotes: 0

Victor Z
Victor Z

Reputation: 76

I don't know why, but I caught now, that such error occurs when something wrong during deserialization. Check your mapping class.

Upvotes: 0

Askar
Askar

Reputation: 574

Missing the following dependency can cause the same exception

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
</dependency>

Upvotes: 0

Mecs
Mecs

Reputation: 1

For me, the issue was caused by duplicated @Jsonproperty values, as Jefferson Lima pointed in his answer. I can't see your VtTemplateVO POJO class in your question but it might cause the problem.

In my case, I tried to unpack several nested values from "game" JSON node in my POJO class to get the desired mapping schema when this exception occurred.

"game": {
  "home_team_id": 2
  "visitor_team_id": 5
}

The following approach didn't work.

public class MyPojo {

  @JsonProperty("game")
  public void unpackHomeTeamId(Map<String, String> game) {
      homeTeamId = game.get("home_team_id");
  }

  @JsonProperty("game")
  public void unpackAwayTeamId(Map<String, String> game) {
      awayTeamId = game.get("visitor_team_id");
  }
}

The solution was setting all fields in one method thus avoiding confusing Jackson mapper. It also led me to a more concise design.

@JsonProperty("game")
public void unpackNestedGameProperties(Map<String, String> game) {
    homeTeamId = game.get("home_team_id");
    awayTeamId = game.get("visitor_team_id");
}

Upvotes: 0

Jefferson Lima
Jefferson Lima

Reputation: 5436

Apparently, any problem in creating and populating the object might result in this error.

In my case, I had duplicated @JsonProperty, example:

public class MyObject {
  @JsonProperty("foo")
  private String foo;

  @JsonProperty("foo")
  private String bar;
}

So I fixed to:

public class MyObject {
  @JsonProperty("foo")
  private String foo;

  @JsonProperty("bar")
  private String bar;
}

And it worked.

But I've seen other people commenting that other mistakes might result in this error, like:

  • Not having setter methods
  • Having overloaded setters
  • Not having a default constructor

Upvotes: 4

user432843
user432843

Reputation: 93

Use

.accept(MediaType.APPLICATION_JSON)

as

webClientBuilder.build()
                .post()
                .uri(ccpApiUrl)
                //.accept(MediaType.APPLICATION_JSON)
                .bodyValue(customerRequest)
                .exchange()
                .doOnSuccess(
                            clientResponse -> logger.info("clientResponse.headers() = " + clientResponse.headers())
                            )
                .doOnSuccess(
                        clientResponse -> {
                    logger.info("clientResponse.statusCode() = " + clientResponse.statusCode());
                    getStatus(clientResponse.statusCode());

                            })
                //.timeout(Duration.ofSeconds(5))
                .flatMap(clientResponse -> clientResponse.bodyToMono(CcpResponse.class))
                // .retryWhen(fixedRetry)
                .block();

Upvotes: -1

Leonard Br&#252;nings
Leonard Br&#252;nings

Reputation: 13272

Instead of annotating every parameter with @JsonProperty, you can also compile your code with the -parameters flag (since Java 8). This will retain the parameter names in the bytecode thus allowing Jackson to use them. See the Maven docs

<compilerArgs>
  <arg>-parameters</arg>
</compilerArgs>

You should also consider this https://stackoverflow.com/a/44075684/2145769 that now parameter names become part of your API.

Upvotes: 2

Aparajita
Aparajita

Reputation: 93

I was also facing this issue caused by Jackson.There needs to be a default constructor for the VtTemplateVO.class with annotated properties. Ex. what I did-

@JsonCreator
public Comment(@JsonProperty("id")String id, @JsonProperty("text")String text, @JsonProperty("createdTime") LocalDate createdTime) {
        this.id = id;
        this.text = text;
        this.createdTime = createdTime;
}

Hope it works for you as well. :)

Upvotes: 8

Related Questions