Spring MVC - 对使用@RequestBody 接收的对象的限制
Spring MVC - restriction on objects received using @RequestBody
当我在@RequestBody 中使用带继承的 class 时,我收到“400 Bad Request”。我有另一个控制器,我在其中使用没有继承的 class 并且它可以工作。
我想知道我是否可以在@RequestBody 中使用常规 EJB,或者对可以使用的 classes 有什么限制吗?
下面是控制器:
@RequestMapping(value = "auth/ping", method = RequestMethod.POST, consumes="application/json")
@ResponseStatus(HttpStatus.OK)
public @ResponseBody String pingPost(@RequestBody User model) {
final String signature = CLASSNAME + "#pingPost(User model)";
Helper.logEntrance(getLogger(), signature, new String[]{"model"}, new Object[]{model});
return "unprotected ping post with data";
}
下面是 classes
public abstract class User extends AuditableEntity {
@Indexed
private String name;
private String password;
public User() {
super();
}
public String getName() {
return this.name;
}
public void setName(String value) {
this.name = value;
}
public String getPassword() {
return this.password;
}
public void setPassword(String value) {
this.password = value;
}
}
public abstract class AuditableEntity {
private User createdBy;
private Date createdDate;
public AuditableEntity() {
super();
}
public User getCreatedBy() {
return this.createdBy;
}
public void setCreatedBy(User value) {
this.createdBy = value;
}
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date value) {
this.createdDate = value;
}
}
我在 maven 中包含了以下库
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.2</version>
</dependency>
继承工作得很好,你的问题是因为你的 User class 是一个抽象 class。
当 Spring MVC 发现用 @RequestBody 注释的参数时,它的参数解析机制就会启动,并且在这个过程中它会尝试创建一个 class,在你的情况下 User class。如果 class 在被标记为抽象时无法实例化,则该过程失败。
我个人会创建和使用数据传输对象,但您也可以使用 EJB class,只需确保删除抽象,或使用具体的 subclass 作为你的方法的参数
另请注意,可以使用抽象 class 作为方法参数,但您需要提供更多信息以帮助框架解决它。这在很大程度上取决于处理转换的消息转换器,因为您似乎正在使用 JSON 和 Jackson,您可以通过提供自定义反序列化器来处理它,所以这样的事情就可以了。
public ConcreteUser extends User {
}
然后用
注释您的用户 class
@JsonDeserialize(as=ConcreteUser.class)
public abstract class User extends AuditableEntity
当我在@RequestBody 中使用带继承的 class 时,我收到“400 Bad Request”。我有另一个控制器,我在其中使用没有继承的 class 并且它可以工作。
我想知道我是否可以在@RequestBody 中使用常规 EJB,或者对可以使用的 classes 有什么限制吗?
下面是控制器:
@RequestMapping(value = "auth/ping", method = RequestMethod.POST, consumes="application/json")
@ResponseStatus(HttpStatus.OK)
public @ResponseBody String pingPost(@RequestBody User model) {
final String signature = CLASSNAME + "#pingPost(User model)";
Helper.logEntrance(getLogger(), signature, new String[]{"model"}, new Object[]{model});
return "unprotected ping post with data";
}
下面是 classes
public abstract class User extends AuditableEntity {
@Indexed
private String name;
private String password;
public User() {
super();
}
public String getName() {
return this.name;
}
public void setName(String value) {
this.name = value;
}
public String getPassword() {
return this.password;
}
public void setPassword(String value) {
this.password = value;
}
}
public abstract class AuditableEntity {
private User createdBy;
private Date createdDate;
public AuditableEntity() {
super();
}
public User getCreatedBy() {
return this.createdBy;
}
public void setCreatedBy(User value) {
this.createdBy = value;
}
public Date getCreatedDate() {
return this.createdDate;
}
public void setCreatedDate(Date value) {
this.createdDate = value;
}
}
我在 maven 中包含了以下库
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.2</version>
</dependency>
继承工作得很好,你的问题是因为你的 User class 是一个抽象 class。
当 Spring MVC 发现用 @RequestBody 注释的参数时,它的参数解析机制就会启动,并且在这个过程中它会尝试创建一个 class,在你的情况下 User class。如果 class 在被标记为抽象时无法实例化,则该过程失败。
我个人会创建和使用数据传输对象,但您也可以使用 EJB class,只需确保删除抽象,或使用具体的 subclass 作为你的方法的参数
另请注意,可以使用抽象 class 作为方法参数,但您需要提供更多信息以帮助框架解决它。这在很大程度上取决于处理转换的消息转换器,因为您似乎正在使用 JSON 和 Jackson,您可以通过提供自定义反序列化器来处理它,所以这样的事情就可以了。
public ConcreteUser extends User {
}
然后用
注释您的用户 class@JsonDeserialize(as=ConcreteUser.class)
public abstract class User extends AuditableEntity