Spring Rest 应用程序中不支持内容类型为 'application/json;charset=UTF-8'。

34
当我在localhost:8080/api/users上进行POST请求以创建新用户时,我会收到以下错误消息:
{
    "timestamp": "2018-05-28T09:44:55.704+0000",
    "status": 415,
    "error": "Unsupported Media Type",
    "message": "Content type 'application/json;charset=UTF-8' not supported",
    "path": "/api/users/"
}

enter image description here

这是请求的主体,选择 JSON(application/json)格式。

即使我删除了 Roles 并将其保持为 null,它仍会给出相同的错误。

enter image description here

的内容类型也是application/json。

enter image description here

这是我的控制器:

@PostMapping("/api/users" )
public User createUser(@Valid @RequestBody User user) {
    securityService.autologin(user.getUsername(), user.getPassword());
    return userService.createUser(user);
}

在UserService中创建createUser函数:
public User createUser(@Valid @RequestBody User user) {
    user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
    user.setRoles(new HashSet<>(roleRepository.findAll()));
    return userRepository.save(user);
}

编辑

这是我的用户类:

@Entity
@Table(name = "user")
@EntityListeners(AuditingEntityListener.class)
@JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, 
                      allowGetters = true)
public class User implements Serializable{

    private static final long serialVersionUID = 1L;
    
    
    public User() {
        super();
        // TODO Auto-generated constructor stub
    }

    @Id
    @Column(name = "user_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "user_name")
    private String name;

    @Column(name = "user_email")
    private String email;
    
    @Column(name = "user_password")
    @NotBlank
    private String password;
    
    @Column(name = "user_status")
    private String status;
    
    @Column(name = "user_tel")
    private String tel;
    
    @Column(name = "user_confirmation")
    private String confirmation;

    @Column(name = "user_birth_date")
    @Temporal(TemporalType.DATE)
    private Date birth_date;
    
    @Column(nullable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @CreatedDate
    private Date createdAt;

    @Column(nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    @LastModifiedDate
    private Date updatedAt;

    @JsonManagedReference
    @ManyToMany
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;
    
    @Column(name = "username")
    @NotBlank
    private String username;
    
    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;
    }

    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getConfirmation() {
        return confirmation;
    }

    public void setConfirmation(String confirmation) {
        this.confirmation = confirmation;
    }

    public Date getBirth_date() {
        return birth_date;
    }

    public void setBirth_date(Date birth_date) {
        this.birth_date = birth_date;
    }

    public Date getCreatedAt() {
        return createdAt;
    }
    
    public Date getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }
    
    public Set<Role> getRoles() {
        return roles;
    }
    
    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }
}

1
你是在使用 RestController 还是简单的 Controller? - JEY
1
@Ouissal: 参考:https://dev59.com/GF0a5IYBdhLWcg3wW3nN#30424031 并添加 Content-Type: application/json 和 Accept: application/json。 - Gaurav
1
@Ouissal 请确保您在实体类(即User类)中放置了JAXB注释。 - piy26
1
为什么需要在JSON转换中使用JAXB注释? - Edwin Dalorzo
1
你是否为你的应用程序配置了任何Jackson或Gson转换器? - Edwin Dalorzo
显示剩余7条评论
14个回答

27

我通过移除 @JsonManagedReference 解决了这个问题。


2
这个解决方案在我的情况下有效。 - Anis KCHAOU
1
有点奇怪,但它确实有帮助——从实体中删除@JsonManagedReference,在这个特定的地方/请求/端点中没有涉及。更奇怪的是——注释的实体在其他地方并没有引起任何问题... - Taraskin

21

在我的情况下,Jackson遇到了一个失败并记录为警告:

无法为类型[[简单类型,类***]]评估Jackson反序列化:com.fasterxml.jackson.databind.JsonMappingException: 属性的设置器定义冲突[...]

由于我意外地重载了一个设置器,因此Jackson无法解析它,Spring抛出了415状态码错误。


这帮助我解决了我的问题。我曾尝试使用 @JsonProperty("fooPerson") 将键反序列化为与变量名不同的内容。但它并不喜欢这样。 - Brian Akumah

3
在我的情况下, 我的 DTO 类中有两次相同的 jsonProperty 标识符。 当我发出请求后返回: “内容类型为 'application/json;charset=UTF-8'”。 不确定为什么会返回该错误,但一旦我更改了标识符就可以正常工作。

enter image description here


2

您指定了内容类型为application/json。我认为您还需要检查“接受”头属性(application/json)。

postman screenshot


2
你可以尝试类似这样的做法: @PostMapping(value="/rest/account/json", consumes={"application/json"})

我遇到了这个错误: "类型不匹配:无法将MediaType转换为String[]"。 - Ouissal
@Ouissal:尝试一下这个,用MediaType.APPLICATION_JSON_VALUE代替MediaType.APPLICATION_JSON。 - Gaurav
1
显然,OP现在遇到了不同的错误。因此,你的答案可能是正确的。现在似乎缺少消息转换器。 - Edwin Dalorzo

2

我在使用Jackson反序列化时也遇到了这个警告错误。我的情况更接近Klaudia的回复,我在POJO上有一个成员字段表示服务,我用@JsonIgnore标记了它,但是为了简洁起见,我将getter和setter重命名为getService()和setService(),而不是与较长命名的服务接口相匹配的变量名。在不同命名的getter和setter上添加@JsonIgnore解决了错误。


1
有时候会出现这样的情况,某人错误地为同一属性保留了两个getter,导致Jackson反序列化无法评估。
它会抛出异常。
Failed to evaluate Jackson deserialization for type [[simple type,
class com.org..*..*]]:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
Conflicting getter definitions for property \"field_name\":
com.org..*..*#getterBName() vs com.org..*..*#gettername()"

在这种情况下,只需删除该字段的额外getter。

0

提示“不支援的媒體類型”,這意味著由於某些問題,操作調用無法完成。請檢查您的服務操作正在請求什麼以及您是否正確地發送了所有字段。 大多數情況下是映射問題。檢查控制台中的錯誤。


0

我在使用 PATCH 请求时,也遇到了以下问题:

public Order markOrderAsPayed(@RequestBody final MultiValueMap<String, String> values) {
...
}

MultiValueMap来自org.springframework.util。将Map更改为Map<String,String>解决了我的问题。

抱歉,我无法解释原因。


0
可能对这篇文章来说已经有点晚了。
如果您可以在控制器类中添加此媒体类型consumes={MediaType.APPLICATION_JSON_UTF8_VALUE},您就可以顺利通过。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接