我收到此错误:
{
"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
对象时失败。