Spring - "Content type 'application/json;charset=UTF-8' not supported" Spring框架 - “不支持内容类型'application/json;charset=UTF-8'”

4
我遇到了这个错误:
{
  "timestamp": 1507132684098,
  "status": 415,
  "error": "Unsupported Media Type",
  "exception": "org.springframework.web.HttpMediaTypeNotSupportedException",
  "message": "Content type 'application/json;charset=UTF-8' not supported",
  "path": "/api/v1/user/0045b213-e764-4ca5-b2e4-71058ef8b2bc"
}

以下是需要翻译的请求:

curl -X PUT --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \ 
   "agreedToTerms": true, \ 
   "alias": "string", \ 
   "authToken": { \ 
     "created": "2017-10-04T15:57:16.485Z", \ 
     "key": "string", \ 
     "user": {} \ 
   }, \ 
   "authenticationTemporaryTokens": {}, \ 
   "createdDate": "2017-10-04T15:57:16.485Z", \ 
   "customerId": "string", \ 
   "dateJoined": "2017-10-04T15:57:16.485Z", \ 
   "email": "string", \ 
   "firstName": "string", \ 
   "lastLogin": "2017-10-04T15:57:16.485Z", \ 
   "lastName": "string", \ 
   "lastSyncFromMdm": "2017-10-04T15:57:16.485Z", \ 
   "lastZconsoleLogin": "2017-10-04T15:57:16.485Z", \ 
   "middleName": "string", \ 
   "modifiedDate": "2017-10-04T15:57:16.485Z", \ 
   "notificationRules": {}, \ 
   "objectId": "string", \ 
   "password": "string", \ 
   "passwordExpirationDate": "2017-10-04T15:57:16.485Z", \ 
   "phoneNumber": "string", \ 
   "phoneNumberVerified": true, \ 
   "pwdRecoveryRequest": true, \ 
   "resetPasswordToken": "string", \ 
   "resetPasswordTokenLifetime": { \ 
     "nano": 0, \ 
     "negative": true, \ 
     "seconds": 0, \ 
     "units": [ \ 
       { \ 
         "dateBased": true, \ 
         "duration": {}, \ 
         "durationEstimated": true, \ 
         "timeBased": true \ 
       } \ 
     ], \ 
     "zero": true \ 
   }, \ 
   "role": 0, \ 
   "roles": {}, \ 
   "signupSteps": 0, \ 
   "staff": true, \ 
   "status": 0, \ 
   "superuser": true, \ 
   "syncedFromMdm": true, \ 
   "termsVersion": 0, \ 
   "ugroup_id": "string" \ 
 }' 'http://localhost:8080/api/v1/user/0045b213-e764-4ca5-b2e4-71058ef8b2bc'

这是控制器(方法本身在底部):

package com.zimperium.server.user.controller;

import com.querydsl.core.types.Predicate;
import com.zimperium.server.user.dto.CreateUserRequest;
import com.zimperium.server.user.entity.legacy.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.Extension;
import io.swagger.annotations.ExtensionProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

@Slf4j
@RestController
@RequestMapping(value = "/api/v1/user", produces = {MediaType.APPLICATION_JSON_VALUE})
@Api(value = "user",
        description = "Manage users")
public class BackwardsCompatibleController {

    @Autowired UserController delegate;

    @ApiOperation(value = "Search for a user",
                  extensions =
                  @Extension(name = "api-info", properties =
                  @ExtensionProperty(name = "availability", value = "service")
                  )
    )
    @RequestMapping(method = RequestMethod.GET)
    public Page<User> find(@QuerydslPredicate(root = User.class)
                                   Predicate predicate,
                           Pageable pageable) {
        return delegate.find(predicate, pageable);
    }

    @RequestMapping(method = RequestMethod.GET, value = "all")
    public Iterable<User> find(@QuerydslPredicate(root = User.class) Predicate predicate) {

        //noinspection unchecked
        return delegate.find(predicate);
    }

    @ApiOperation(value = "Look up information about a user",
                  extensions =
                  @Extension(name = "api-info", properties =
                  @ExtensionProperty(name = "availability", value = "service")
                  )
    )
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public User get(@PathVariable(value = "id") String id) {
        return delegate.get(id);
    }

    @ApiOperation(value = "Create a user",
                  extensions =
                  @Extension(name = "api-info", properties =
                  @ExtensionProperty(name = "availability", value = "public")
                  )
    )
    @RequestMapping(method = RequestMethod.POST)
    public User save(@RequestBody CreateUserRequest req) throws IOException {
        return delegate.save(req);
    }

    @ApiOperation(value = "Update a user",
                  extensions =
                  @Extension(name = "api-info", properties =
                  @ExtensionProperty(name = "availability", value = "service")
                  )
    )
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public void save(@PathVariable(value = "id") String id, @RequestBody User user) {
        delegate.save(id, user);
    }
}

这是User类:

package com.zimperium.server.user.entity.legacy;

import java.io.Serializable;
import java.time.Duration;
import java.util.Collection;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.eclipse.persistence.annotations.UuidGenerator;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Table(name = "users_user")
@Entity
@UuidGenerator(name = User.ID_GENERATOR)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(exclude = {"password"})
@EqualsAndHashCode(of = {"email", "status"})
@Cacheable(false)
public class User implements Serializable
{
    public static final Integer ACTIVE = 1;
    public static final Integer INACTIVE = 2;
    public static final Integer BLOCKED = 3;
    public static final Integer VERIFICATION_MAIL_SENT = 4;
    public static final Integer EXPIRED = 5;
    public static final Integer NEEDS_RE_LOGIN = 6;
    public static final Integer DELETED = 7;

    public static final String ID_GENERATOR = "user_id_gen";
    private static final long serialVersionUID = 1L;


    @Id
    @Size(min = 1, max = 64)
    @Column(name = "object_id", nullable = false, length = 64)
    @GeneratedValue(generator = ID_GENERATOR)
    private String objectId;

    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 128)
    @Column(name = "password", nullable = false, length = 128)
    private String password;

    @Basic(optional = false)
    @NotNull
    @Column(name = "last_login", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastLogin;

    @Basic(optional = false)
    @NotNull
    @Column(name = "is_superuser", nullable = false)
    private boolean isSuperuser;

    // @Pattern(regexp="[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?", message="Invalid email")//if the field contains email address consider using this annotation to enforce field validation
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "email", nullable = false, length = 255)
    private String email;

    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 120)
    @Column(name = "alias", nullable = false, length = 120)
    private String alias;

    @Size(max = 255)
    @Column(name = "first_name", length = 255)
    private String firstName;

    @Size(max = 255)
    @Column(name = "middle_name", length = 255)
    private String middleName;

    @Size(max = 255)
    @Column(name = "last_name", length = 255)
    private String lastName;

    @Size(max = 255)
    @Column(name = "ugroup_id", length = 255)
    private String ugroup_id;

    @Basic(optional = false)
    @NotNull
    @Column(name = "is_staff", nullable = false)
    private boolean isStaff;

    @Basic(optional = false)
    @NotNull
    @Column(name = "status", nullable = false)
    private int status;

    @Basic(optional = false)
    @NotNull
    @Column(name = "date_joined", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dateJoined;

    @Basic(optional = false)
    @NotNull
    @Column(name = "agreed_to_terms", nullable = false)
    private boolean agreedToTerms;

    @Basic(optional = false)
    @NotNull
    @Column(name = "pwd_recovery_request", nullable = false)
    private boolean pwdRecoveryRequest;

    @Basic(optional = false)
    @NotNull
    @Column(name = "role", nullable = false)
    private int role;

    @Basic(optional = false)
    @NotNull
    @Column(name = "signup_steps", nullable = false)
    private int signupSteps;

    @Column(name = "terms_version")
    private Integer termsVersion;

    @Basic(optional = false)
    @NotNull
    @Column(name = "created_date", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDate;

    @Basic(optional = false)
    @NotNull
    @Column(name = "modified_date", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date modifiedDate;

    @Size(max = 128)
    @Column(name = "phone_number", length = 128)
    private String phoneNumber;

    @Basic(optional = false)
    @NotNull
    @Column(name = "is_synced_from_mdm", nullable = false)
    private boolean isSyncedFromMdm;

    @Basic(optional = false)
    @NotNull
    @Column(name = "is_phone_number_verified", nullable = false)
    private boolean isPhoneNumberVerified;

    @Column(name = "last_sync_from_mdm")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastSyncFromMdm;

    @Column(name = "last_zconsole_login")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastZconsoleLogin;

    @Column(name = "password_expiration_date")
    @Temporal(TemporalType.TIMESTAMP)
    private Date passwordExpirationDate;

    @Column(name = "system_id")
    private String customerId;

    @JsonManagedReference
    @OneToMany(mappedBy="user", cascade = CascadeType.ALL)
    private Collection<UserRole> roles;

    @JsonIgnore
    @OneToMany(mappedBy="user", cascade = CascadeType.ALL)
    private Collection<UsersUserUserPermissions> usersUserUserPermissionses;

    @JsonIgnore
    @OneToMany(mappedBy="user", cascade = CascadeType.ALL)
    private Collection<UsersUseruserobjectpermission> usersUseruserobjectpermissions;

    @OneToOne(mappedBy="user", cascade = CascadeType.ALL)
    private AuthToken authToken;

    @JsonManagedReference
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Collection<AuthenticationTemporaryToken> authenticationTemporaryTokens;

    @JsonManagedReference
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private Collection<NotificationRule> notificationRules;



    /**
     * Include the temporary token and expiration duration. These allow the user to reset his password without
     * knowing the previous password.
     */
    @Transient
    private String resetPasswordToken;

    @Transient
    private Duration resetPasswordTokenLifetime;
}

我在函数的第一行设置了断点,但在到达第一行之前就遇到了错误。此外,如果我从参数列表中删除@RequestBody User user,则不会出现这个错误。据我所知,这意味着它在尝试将JSON转换为User对象时失败。


看起来有些属性与请求不匹配。尝试在类顶部添加@JsonIgnoreProperties(ignoreUnknown=true) - Barath
@Barath 没有帮助 :/ - W2a
你能否尝试将PUT方法的映射更改为其他内容。GET方法也有类似的映射。只需尝试指向另一个映射,以确保它与路径映射无关。 - Barath
更改为/a/different/requestmapping/{id} - 相同.. @Barath - W2a
用户缺少默认构造函数(无参数)。似乎与https://dev59.com/PmQn5IYBdhLWcg3wzZ76相同。 - derkoe
@koe 类的顶部有 @NoArgsConstructor - W2a
2个回答

0

0

这个类与许多其他对象相关联。

请检查设置方法的冲突。

//try to @JsonIgnore in set method 
public void setSystemConfig(Config config)   {
  
}

public void setSystemConfig(Config config,String version)   {
  
}

尝试使用@JsonIgnore注解来忽略某些类。

这也可能是一个Jar冲突,您可以在pom.xml中添加它。

 <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
    <!--    your version:        <version>2.9.9</version>-->
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
    <!--     your version:            <version>2.9.9</version>-->
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
    <!--      your version:           <version>2.9.9</version>-->
            </dependency>

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