web-dev-qa-db-ja.com

Spring Rest POST Json RequestBodyコンテンツタイプはサポートされていません

Postメソッドで新しいオブジェクトを投稿しようとすると。 RequestBodyはcontentTypeを認識できませんでした。 Springは既に設定されており、POSTは他のオブジェクトで動作しますが、この特定のオブジェクトでは動作しません。

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

同じリクエストを試してみると、requestbodyオブジェクトを変更するだけです。できます。

49
Thibaut

私は解決策を見つけました。それは、同じ名前で異なるタイプのセッターを2つ持っていたからです。

クラスにidプロパティintがあり、オブジェクトをHibernitifyするときにIntegerに置き換えました。

しかし、どうやら、セッターを削除するのを忘れて、私は持っていました:

/**
 * @param id
 *            the id to set
 */
public void setId(int id) {
    this.id = id;
}

/**
 * @param id
 *            the id to set
 */
public void setId(Integer id) {
    this.id = id;
}

このセッターを削除すると、残りのクエストは非常にうまく機能します。

アンマーシャリングエラーをスローするか、クラスエラーを反映するようになりました。例外HttpMediaTypeNotSupportedExceptionは、ここでは本当に奇妙な継ぎ目です。

このstackoverflowが他の誰かを助けることを願っています。

サイドノート

Spring server consoleで次のエラーメッセージを確認できます。

タイプ[単純型、クラスyour.package.ClassName]のジャクソンの逆シリアル化の評価に失敗しました:com.fasterxml.jackson.databind.JsonMappingException:プロパティ "propertyname"のセッター定義が競合しています

その後、上記の問題に対処していることを確認できます。

65
Thibaut

また、POST(コンストラクターで宣言されていない場合のイベント)で送信されないパラメーターの属性のゲッターとセッターを宣言した場合にも注意してください。

@RestController
public class TestController {

    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public String test(@RequestBody BeanTest beanTest) {
        return "Hello " + beanTest.getName();
    }


    public static class BeanTest {

        private Long id;
        private String name;

        public BeanTest() {
        }

        public BeanTest(Long id) {
            this.id = id;
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

次の構造の投稿リクエスト:{"id": "1"}は機能しません。名前getおよびsetを削除する必要があります。

7
alvgarvilla

Lombokを使用している場合、@ JsonDeserializeの命名を台無しにすると、そのエラーが発生する可能性があります。例えば:

@Value
@Builder(toBuilder = true)
@JsonDeserialize(builder = SomeClass.SomeOtherClassBuilder.class)
public class SomeClass {
    ...
    public static class SomeOtherClassBuilder {
        ...
    }
}

そのはず:

@Value
@Builder(toBuilder = true)
@JsonDeserialize(builder = SomeClass.SomeClassBuilder.class)
public class SomeClass {
    ...
    public static class SomeClassBuilder {
        ...
    }
}

クラス名のリファクタリングを行い、Builderを忘れた場合、それを行うのは非常に簡単です...そして、エラーの理由を検索する間、非常に役に立たない例外メッセージのみを持ちながら、何時間も喜びます。

4
Mader Levap

本当に! 4時間をかけて非常識なデバッグを行った後、com.fasterxml.jackson.databind.deser.DeserializerCacheでこの非常に奇妙なコードを見つけました。

if (deser == null) {
    try {
        deser = _createAndCacheValueDeserializer(ctxt, factory, type);
    } catch (Exception e) {
        return false;
    }
}

はい、問題はダブルセッターでした。

3
Reza Shahbazi

私は投稿された値をデシリアライズすることで解決した同じ問題に遭遇しました:

@RequestMapping(value = "/arduinos/commands/{idArduino}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String sendCommandesJson(@PathVariable("idArduino") String idArduino, HttpServletRequest request) throws IOException {
    // getting the posted value
    String body = CharStreams.toString(request.getReader());
    List<ArduinoCommand> commandes = new ObjectMapper().readValue(body, new TypeReference<List<ArduinoCommand>>() {
    });

これらのgradle依存関係:

  compile('org.springframework.boot:spring-boot-starter-web')
  compile('com.google.guava:guava:16.0.1')
1
Serge Tahé

このようなエンティティクラスコンストラクターで@JsonPropertyを指定します。

......
......
......

 @JsonCreator
 public Location(@JsonProperty("sl_no") Long sl_no, 
          @JsonProperty("location")String location,
          @JsonProperty("location_type") String 
          location_type,@JsonProperty("store_sl_no")Long store_sl_no) {
  this.sl_no = sl_no;
  this.location = location;
  this.location_type = location_type;
  this.store_sl_no = store_sl_no;
 } 
.......
.......
.......
1
Kiran Kumar A

そのため、オーバーロードされたコンストラクターを持つBeanがあるという同様の問題がありました。このBeanにはオプションのプロパティもありました。

それを解決するために、オーバーロードされたコンストラクターを削除しただけで機能しました。

例:

public class Bean{

Optional<String> string;
Optional<AnotherClass> object;

public Bean(Optional<String> str, Optional<AnotherClass> obj){
string = str;
object = obj;
}

///The problem was below constructor

public Bean(Optional<String> str){
string = str;
object = Optional.empty();
}



}

}
1
user_CC

1つの列挙型と1つの文字列を持つ2つのセッターがあったときに、同じ問題が発生しました。シリアル化中に使用するセッターメソッドをJacksonに伝える@JsonSetterアノテーションを使用する必要がありました。これで問題が解決しました。

1

私の場合、Beanに2つのコンストラクターがあり、同じエラーがありました。そのうちの1つを削除したところ、問題は修正されました。

1
osoitza

同じ問題がありました。根本的な原因は、デフォルトのコンストラクタなしでカスタムデシリアライザを使用していたことです。

0
gstackoverflow

ジャクソン依存関係を追加しよう

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

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.9.3</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.3</version>
        <exclusions>
            <exclusion>
                <artifactId>jackson-annotations</artifactId>
                <groupId>com.fasterxml.jackson.core</groupId>
            </exclusion>
        </exclusions>
    </dependency>
0
Aborn Jiang

古いスレッドに見えますが、誰かがまだ苦労している場合は、Thibautが言ったように解決しました、

セッターPOJOクラスを2つ持つことは避けてください。特定のプロパティのセッターが2つありました。最初のセッターは通常のセッターにあり、もう1つはコンストラクターの下にありました。

0
Dan