it-swarm.com.ru

Весенний отдых POST Json RequestBody

Когда я пытаюсь опубликовать новый объект с помощью метода post. RequestBody не может распознать contentType. Spring уже настроен и POST может работать с другими объектами, но не с этим конкретным.

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

Если я попробую тот же запрос, просто изменив объект requestbody. Оно работает.

43
Thibaut

Я нашел решение .... Это было потому, что у меня было 2 сеттера с тем же именем, но другого типа.

В моем классе было свойство id int, которое я заменил на Integer, когда Hibernitify моего объекта.

Но, видимо, я забыл удалить сеттеры и у меня было:

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

Когда я убрал этот сеттер, отдыхал хорошо.

Intead бросить unmarshalling error или отразить ошибку класса. Исключение HttpMediaTypeNotSupportedException швы здесь действительно странные.

Я надеюсь, что этот стекопоток может помочь кому-то еще.

ПРИМЕЧАНИЕ

Вы можете проверить ваш сервер Spring console на наличие следующего сообщения об ошибке:

Не удалось оценить десериализацию Джексона для типа [простой тип, class your.package.ClassName]: com.fasterxml.jackson.databind.JsonMappingException: конфликт определения сеттера для свойства "propertyname"

Тогда вы можете быть уверены, что имеете дело с проблемой, упомянутой выше.

60
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.

6
alvgarvilla

В самом деле! потратив 4 часа на безумную отладку, я нашел этот очень странный код на com.fasterxml.jackson.databind.deser.DeserializerCache

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

Я, проблема была двойной сеттер.

3
Reza Shahbazi

Если вы используете 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 ... и у вас будет много часов радости, когда вы будете искать причину ошибки, а в качестве справки получите только крайне бесполезное сообщение об исключении.

3
Mader Levap

Я встретил ту же самую проблему, которую я решил, десериализовав себя объявленной ценностью:

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

с тезисами:

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

Таким образом, у меня была похожая проблема, где у меня был бин с каким-то перегруженным конструктором. Этот боб также имел дополнительные свойства.

Чтобы решить эту проблему, я просто удалил перегруженные конструкторы, и это сработало.

пример:

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

У меня была такая же проблема, когда у меня было два сеттера, один с Enum и один String. Мне пришлось использовать аннотацию @JsonSetter, которая сообщает Джексону, какой метод установки следует использовать во время сериализации. Это решило мою проблему.

1
Kartheek Mannepalli

В моем случае у меня было два Конструктора в бине, и у меня была та же самая ошибка. Я только что удалил один из них, и теперь проблема исправлена!

1
osoitza

укажите @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;
 } 
.......
.......
.......
0
Kiran Kumar A

Я была такая же проблема. Основной причиной было использование пользовательского десериализатора без конструктора по умолчанию.

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

Это выглядит как старая нить, но в случае, если кто-то все еще борется, я решил, как сказал Тибо, 

Избегайте использования двух классов-установщиков класса POJO, у меня было два сеттера для определенного свойства. Первый был в обычном сеттере, а другой - в конструкторе после того, как я удалил тот в конструкторе, который работал.

0
Dan