从 Postman 发送的带有 JSON 负载的 PUT 请求,未解析嵌套对象
PUT request with JSON payload sent from Postman, nested object not parsed
我以前没有遇到过这个问题,对于其他 POJO,我不确定这次有什么不同,但我无法正常工作,也找不到确切的解决方案。
我有一个名为 Component 的 POJO(带有一些 Hibernate 注释):
@Entity
@Table(name="component", uniqueConstraints={@UniqueConstraint(
columnNames = {"name", "component_type"})})
public class Component {
@Column(name="id")
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="name")
private String name;
@Column(name="component_type")
private String componentType;
@Column(name="serial_number")
private int serialNumber;
@Column(name="active_since")
private String activeSince;
@Embedded
private ComponentWearoutModel wearout;
public Component() {
}
public Component(String name, String componentType, int serialNumber, String activeSince,
ComponentWearoutModel wearout) {
this.name = name;
this.componentType = componentType;
this.serialNumber = serialNumber;
this.activeSince = activeSince;
this.wearout = wearout;
}
public ComponentWearoutModel getModel() {
return wearout;
}
public void setModel(ComponentWearoutModel wearout) {
this.wearout = wearout;
}
//more getters and setters
}
ComponentWearoutModel:
@Embeddable
public class ComponentWearoutModel {
private String componentType; //dont mind the stupid duplicate attribute
private Integer componentLifeExpectancy;
private Float componentWearOutLevel;
private Float actionThreshold;
public ComponentWearoutModel() {
}
public ComponentWearoutModel(String componentType, int componentLifeExpectancy, float componentWearOutLevel,
float actionThreshold) {
this.componentType = componentType;
this.componentLifeExpectancy = componentLifeExpectancy;
this.componentWearOutLevel = componentWearOutLevel;
this.actionThreshold = actionThreshold;
}
//getters and setters
}
我使用的示例负载:
{
"name": "component name",
"componentType": "airfilter2",
"serialNumber": 573224,
"activeSince": "2016-04-10 17:38:41",
"wearout":
{
"componentType": "airfilter",
"componentLifeExpectancy": 1000,
"componentWearOutLevel": 0.24,
"actionThreshold": 0.2
}
}
最后是资源 class:
@Path("myresource")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
public class MyResource {
DatabaseManager dm = DatabaseManager.getInstance();
@PUT
@Path("Component")
public Response storeComponent(Component component){
System.out.println("reached");
System.out.println(component.getComponentType()); //okay
System.out.println(component.getModel().getComponentType()); //nullpointerexception
ComponentWearoutModel model = new ComponentWearoutModel("type", 1000, 1f, 0.2f);
component.setModel(model); //this way it's saved in the db just fine
dm.save(component);
return Response.status(Status.OK).entity(component).build();
}
}
没有打印,只有不属于 ComponentWearoutModel class 的字段存储在数据库 table 中,其他列为空。因此,当我尝试打印其中一个时,出现异常,我只是不明白为什么。如果我在资源方法中创建一个 ComponentWearoutModel 并将其添加到组件中,数据库中的一切都很好。
更新:
所以我的错误是我在 Component.class 中将 ComponentWearoutModel 属性命名为 "wearout",但是自动生成的 getter 和 setter 被称为 getModel/setModel 而 moxy 不能因此解析我的有效载荷。解决方案:将组件 class 和有效载荷中的属性名称更改为 "model"。
请确保您在 POJO 中使用的属性名称与 json 字符串中发送的属性名称相同。
由于您的 POJO 中没有使用 jackson 等注释来告诉它相应的 json 映射,因此底层代码将直接使用 json 字符串中给出的名称。如果您使用字符串 "model",转换器代码将在您的 POJO 中查找 "setModel" 方法。
在上面的示例中,要么调用所有内容 "model",要么调用 "wearable"。
我以前没有遇到过这个问题,对于其他 POJO,我不确定这次有什么不同,但我无法正常工作,也找不到确切的解决方案。
我有一个名为 Component 的 POJO(带有一些 Hibernate 注释):
@Entity
@Table(name="component", uniqueConstraints={@UniqueConstraint(
columnNames = {"name", "component_type"})})
public class Component {
@Column(name="id")
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@Column(name="name")
private String name;
@Column(name="component_type")
private String componentType;
@Column(name="serial_number")
private int serialNumber;
@Column(name="active_since")
private String activeSince;
@Embedded
private ComponentWearoutModel wearout;
public Component() {
}
public Component(String name, String componentType, int serialNumber, String activeSince,
ComponentWearoutModel wearout) {
this.name = name;
this.componentType = componentType;
this.serialNumber = serialNumber;
this.activeSince = activeSince;
this.wearout = wearout;
}
public ComponentWearoutModel getModel() {
return wearout;
}
public void setModel(ComponentWearoutModel wearout) {
this.wearout = wearout;
}
//more getters and setters
}
ComponentWearoutModel:
@Embeddable
public class ComponentWearoutModel {
private String componentType; //dont mind the stupid duplicate attribute
private Integer componentLifeExpectancy;
private Float componentWearOutLevel;
private Float actionThreshold;
public ComponentWearoutModel() {
}
public ComponentWearoutModel(String componentType, int componentLifeExpectancy, float componentWearOutLevel,
float actionThreshold) {
this.componentType = componentType;
this.componentLifeExpectancy = componentLifeExpectancy;
this.componentWearOutLevel = componentWearOutLevel;
this.actionThreshold = actionThreshold;
}
//getters and setters
}
我使用的示例负载:
{
"name": "component name",
"componentType": "airfilter2",
"serialNumber": 573224,
"activeSince": "2016-04-10 17:38:41",
"wearout":
{
"componentType": "airfilter",
"componentLifeExpectancy": 1000,
"componentWearOutLevel": 0.24,
"actionThreshold": 0.2
}
}
最后是资源 class:
@Path("myresource")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8")
public class MyResource {
DatabaseManager dm = DatabaseManager.getInstance();
@PUT
@Path("Component")
public Response storeComponent(Component component){
System.out.println("reached");
System.out.println(component.getComponentType()); //okay
System.out.println(component.getModel().getComponentType()); //nullpointerexception
ComponentWearoutModel model = new ComponentWearoutModel("type", 1000, 1f, 0.2f);
component.setModel(model); //this way it's saved in the db just fine
dm.save(component);
return Response.status(Status.OK).entity(component).build();
}
}
没有打印,只有不属于 ComponentWearoutModel class 的字段存储在数据库 table 中,其他列为空。因此,当我尝试打印其中一个时,出现异常,我只是不明白为什么。如果我在资源方法中创建一个 ComponentWearoutModel 并将其添加到组件中,数据库中的一切都很好。
更新:
所以我的错误是我在 Component.class 中将 ComponentWearoutModel 属性命名为 "wearout",但是自动生成的 getter 和 setter 被称为 getModel/setModel 而 moxy 不能因此解析我的有效载荷。解决方案:将组件 class 和有效载荷中的属性名称更改为 "model"。
请确保您在 POJO 中使用的属性名称与 json 字符串中发送的属性名称相同。
由于您的 POJO 中没有使用 jackson 等注释来告诉它相应的 json 映射,因此底层代码将直接使用 json 字符串中给出的名称。如果您使用字符串 "model",转换器代码将在您的 POJO 中查找 "setModel" 方法。
在上面的示例中,要么调用所有内容 "model",要么调用 "wearable"。