Spring Rest POST不支持Json RequestBody内容类型

时间:2013-10-18 08:21:03

标签: java json spring spring-mvc jackson

当我尝试使用post方法发布新对象时。 RequestBody无法识别contentType。 Spring已经配置,POST可以与其他对象一起使用,但不是这个特定的对象。

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

如果我尝试相同的请求只是更改requestbody对象。它有效。

15 个答案:

答案 0 :(得分:62)

我找到了解决方案。 这是因为我有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;
}

当我删除这个二传手时,休息重新开始工作非常好。

Intead抛出解组错误或反映类错误。异常HttpMediaTypeNotSupportedException接缝真的很奇怪。

我希望这个stackoverflow可以帮助其他人。

SIDE NOTE

您可以检查 Spring服务器控制台以获取以下错误消息:

  

无法评估杰克逊反序列化类型[simple type,   class your.package.ClassName]:   com.fasterxml.jackson.databind.JsonMappingException:冲突   属性“propertyname”的setter定义

然后您可以确定您正在处理上述问题。

答案 1 :(得分:6)

还要注意是否已为POST中未发送的参数属性声明了getter和setter(如果未在构造函数中声明,则为event),例如:

@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。

答案 2 :(得分:4)

如果您使用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 :(得分:3)

真!花了4个小时和疯狂的调试后,我在com.fasterxml.jackson.databind.deser.DeserializerCache

找到了这个非常奇怪的代码。
if (deser == null) {
    try {
        deser = _createAndCacheValueDeserializer(ctxt, factory, type);
    } catch (Exception e) {
        return false;
    }
}

雅,问题是双重制定者。

答案 4 :(得分:1)

当我有两个使用Enum和一个String的setter时,我遇到了同样的问题。我不得不使用@JsonSetter注释来告诉Jackson在序列化期间使用什么setter方法。这解决了我的问题。

答案 5 :(得分:1)

我遇到了同样的问题,我通过反序列化自己发布的值解决了这个问题:

@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')

答案 6 :(得分:1)

在我的情况下,我在bean中有两个构造函数,我有同样的错误。我刚刚删除其中一个,现在问题已解决!

答案 7 :(得分:1)

所以我有一个类似的问题,我有一个带有一些重载构造函数的bean。这个bean也有Optional属性。

要解决这个问题,我只是删除了重载的构造函数,但它确实有效。

示例:

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



}

}

答案 8 :(得分:1)

在这样的实体类构造函数中指定@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;
 } 
.......
.......
.......

答案 9 :(得分:1)

对于同一个属性有 2 个 getter 的情况,反序列化器失败参考 Link

答案 10 :(得分:0)

尝试添加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>

答案 11 :(得分:0)

它看起来很旧,但万一有人还在挣扎,我已经解决了,正如Thibaut说的那样,

避免使用两个setter POJO类,我有一个特定属性的两个setter,第一个是在常规setter中,另一个是在构造函数中删除了它在它工作的构造函数中。

答案 12 :(得分:0)

我有同样的问题。根本原因是使用没有默认构造函数的自定义反序列化器。

答案 13 :(得分:0)

将其用作外键时,我遇到了同样的问题。

@JsonBackReference
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.DETACH},fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;

然后我删除了@JsonBackReference注释。之后,上述问题已解决。

答案 14 :(得分:0)

使用Java 9+模块时出现此问题。我必须open模块才能使com.fasterxml.jackson.databind通过反射访问对象。或者,只有拥有模型的人才能打开包装。