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

Java 不支持Spring Rest POST Json RequestBody内容类型,java,json,spring,spring-mvc,jackson,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对象。它很有效。我找到了解决办法。

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

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported
如果我尝试相同的请求,只需更改requestbody对象。它很有效。

我找到了解决办法。 这是因为我有两个同名但类型不同的setter

我的类具有id属性int,在对对象进行反序列化时,我将其替换为整数

但很明显,我忘了移除二传手,我有:

/**
 * @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;
}
当我移除这个setter时,rest-resquest工作得非常好

Intead引发解组错误或反射类错误。异常HttpMediaTypeNotSupportedException在这里非常奇怪

我希望这能帮助别人

旁注 您可以检查您的Spring server控制台,查看以下错误消息:

无法计算类型[简单类型]的Jackson反序列化, 将您的.package.ClassName]分类: com.fasterxml.jackson.databind.JsonMappingException:冲突 属性“propertyname”的setter定义


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

真的!在花了4个小时和疯狂的调试之后,我在com.fasterxml.jackson.databind.deser.DeserializerCache上发现了这段非常奇怪的代码

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

是的,问题是双重setter。

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

@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;
        }
    }
}
@Value
@Builder(toBuilder = true)
@JsonDeserialize(builder = SomeClass.SomeOtherClassBuilder.class)
public class SomeClass {
    ...
    public static class SomeOtherClassBuilder {
        ...
    }
}

下一个结构为:{“id”:“1”}的post请求将不起作用,您必须删除name get和set。

当我有两个setter时,我遇到了相同的问题,一个是Enum,一个是String。我必须使用@JsonSetter注释,它告诉Jackson在序列化期间要使用什么setter方法。这解决了我的问题。

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

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

在我的例子中,bean中有两个构造函数,并且我有相同的错误。我刚刚删除了其中一个,现在问题已经解决了

所以我遇到了一个类似的问题,我有一个带有重载构造函数的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();
}



}

}
公共类Bean{
可选字符串;
可选对象;
公共Bean(可选str、可选obj){
string=str;
对象=obj;
}
///这个问题没有解决
公共Bean(可选str){
string=str;
object=Optional.empty();
}
}
}

如果您使用lombok,如果将@JsonDeserialize的命名搞砸了,可能会出现该错误,例如:

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

当您重构类名而忘记了生成器时,很容易做到这一点。。。然后,当您搜索错误原因时,您会有很多小时的快乐,而作为帮助,只有极为无用的异常消息。

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

com.fasterxml.jackson.core
杰克逊核心
2.9.3
com.fasterxml.jackson.core
杰克逊注释
2.9.3
com.fasterxml.jackson.core
杰克逊数据绑定
2.9.3
杰克逊注释
com.fasterxml.jackson.core

这看起来是一条旧线索,但万一有人还在挣扎,我已经解决了,正如蒂鲍特所说


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

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

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

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

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

然后我删除了
@JsonBackReference
注释。此后,上述问题得到解决

我在使用java 9+模块时遇到了这个问题。我必须
打开
模块,以便
com.fasterxml.jackson.databind
访问具有反射的对象。或者,如果您有模型,则只能打开模型所在的包。

对于同一属性有两个getter的情况,反序列化程序失败。请参阅

我花了大约5个小时处理同一问题。我在一个名为“getSerial(…)”的实体上有两个setter。一个是“字符串”,另一个是“大整数”…这里一样。。。一个用于枚举,另一个用于字符串。。谢谢你,谢谢你。我无法跟踪是什么导致了我的错误,并且错误消息在我的日志中的位置比我检查的位置要高得多。搜索反序列化错误直接导致了这个问题。显然,异常是不准确的。我们可以找出实际的错误,通过简单地接受作为字符串的负载,然后尝试将负载序列化到相应的映射对象。在我的例子中,我遇到这个问题是因为我在一个字段上使用了
@JsonSerialize
,但是缺少
@JsonDeserialize
注释。如果没有设置
内容,也会出现一个稍微不同的错误type=application/json
Jackson反序列化程序可能存在问题。请参阅,由于字段有多个getter,可能会出现问题。是否应该从com.fasterxml.jackson.annotation.*导入JsonProperty?