web-dev-qa-db-fra.com

Repos de printemps POST Json RequestBody Type de contenu non pris en charge

Quand j'essaye de poster un nouvel objet avec la méthode post. RequestBody n'a pas pu reconnaître contentType. Spring est déjà configuré et POST pourrait fonctionner avec d'autres objets, mais pas avec cet objet spécifique.

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

Si j'essaie la même demande, il suffit de changer d'objet requestbody. Ça marche.

43
Thibaut

J'ai trouvé la solution… .. C'est parce que j'avais 2 passeurs avec le même nom mais de type différent.

Ma classe avait la propriété id int que j'ai remplacée par Integer lorsque à Hibernitify mon objet.

Mais apparemment, j'ai oublié de retirer les setters et j'avais:

/**
 * @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;
}

Quand j'ai enlevé ce setter, reste demande très bien.

Intead pour jeter une erreur incontrôlable ou refléter une erreur de classe Une exception HttpMediaTypeNotSupportedException semble vraiment étrange ici.

J'espère que ce stackoverflow pourrait aider quelqu'un d'autre.

NOTE DE CÔTÉ

Vous pouvez vérifier votre serveur de printemps console pour le message d'erreur suivant:

Échec de l'évaluation de la désérialisation de Jackson pour le type [type simple, class your.package.ClassName]: com.fasterxml.jackson.databind.JsonMappingException: Conflicting définitions de setter pour la propriété "propertyname"

Ensuite, vous pouvez être sûr de traiter le problème mentionné ci-dessus.

60
Thibaut

Sachez également si vous avez déclaré des getters et des setters pour des attributs du paramètre qui ne sont pas envoyés dans le POST (événement s'ils ne sont pas déclarés dans le constructeur), par exemple:

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

Une demande de publication avec la structure suivante: {"id": "1"} ne fonctionnerait pas, vous devez supprimer le nom get et set.

6
alvgarvilla

Vraiment! Après avoir passé 4 heures et débogué insensé, j'ai trouvé ce code très étrange sur com.fasterxml.jackson.databind.deser.DeserializerCache.

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

Oui, le problème était double poseur.

3
Reza Shahbazi

Si vous utilisez lombok, vous pouvez obtenir cette erreur si vous vous trompez en nommant @JsonDeserialize, par exemple:

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

CA devrait etre:

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

Il est très facile de le faire lorsque vous refactorisez le nom de la classe et oubliez Builder ... et vous disposez alors de nombreuses heures de joie lorsque vous recherchez une raison d'erreur, tout en n'ayant comme aide que des messages d'exception extrêmement inutiles.

3
Mader Levap

J'ai rencontré le même problème que j'ai résolu en me désérialisant la valeur affichée:

@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>>() {
    });

avec ces dépendances:

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

Donc, j'ai eu un problème similaire où j'avais un bean avec un constructeur surchargé. Ce haricot avait également des propriétés facultatives.

Pour résoudre cela, je viens de supprimer les constructeurs surchargés et cela a fonctionné.

exemple:

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

J'ai eu le même problème quand j'avais deux setters, l'un avec Enum et un String. J'ai dû utiliser l'annotation @JsonSetter qui indique à Jackson la méthode de définition à utiliser lors de la sérialisation. Cela a résolu mon problème.

1

Dans mon cas, j'avais deux constructeurs dans la fève et j'ai eu la même erreur. Je viens de supprimer l'un d'entre eux et maintenant le problème est résolu!

1
osoitza

spécifiez @JsonProperty dans le constructeur de la classe d'entité comme ceci.

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

 @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;
 } 
.......
.......
.......
0
Kiran Kumar A

J'ai eu le même problème. La cause première était l'utilisation d'un désérialiseur personnalisé sans constructeur par défaut.

0
gstackoverflow

essayez d'ajouter une dépendance jackson

    <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

Ça a l'air d'être un vieux fil, mais au cas où quelqu'un aurait encore du mal, j'ai résolu ce que disait Thibaut, 

Évitez d'avoir deux classes POJO de setter, j'avais deux setters pour une propriété spécifique. Le premier était dans le setter régulier et un autre dans le sous-constructeur après que j'ai supprimé celui du constructeur dans lequel il travaillait.

0
Dan