问题描述
Comment
开发通用评论功能时,建立评论实体。
/**
* @author zhangxishuo on 2018/8/19
* 评论实体
*/
@Entity
@ApiModel(value = "Comment (评论)", description = "评论实体")
public class Comment extends YunZhiAbstractEntity {
private static final Map<String, Class<?>> serviceMap = new HashMap<>();
static {
serviceMap.put("NonMandatoryInstrumentCheckApplyService", NonMandatoryInstrumentCheckApplyService.class);
}
@Column(length = 3000)
private String content;
@Transient // 该字段不映射到数据库
@JsonIgnore // 序列化时忽略属性
private String serviceName;
@Transient // 该字段不映射到数据库
@JsonIgnore // 序列化时忽略属性
private Long relationId;
}
这里因为考虑到需要将信息传递给相关联该评论的实体,所以建了两个额外的属性serviceName
和relationId
,但是这个仅在Service
中使用,并不映射到数据库,同时也不希望这个字段映射到前台是也显示。
测试代码
@Test
public void saveTest() throws Exception {
logger.debug("测试数据");
NonMandatoryInstrumentCheckApply nonMandatoryInstrumentCheckApply = nonMandatoryInstrumentCheckApplyService.getOneSavedObject();
Long relationId = nonMandatoryInstrumentCheckApply.getId();
String content = "测试评论";
String serviceName = "NonMandatoryInstrumentCheckApplyService";
logger.debug("生成评论");
Comment comment = new Comment();
comment.setRelationId(relationId);
comment.setContent(content);
comment.setServiceName(serviceName);
String json = JSONObject.toJSONString(comment);
this.mockMvc
.perform(MockMvcRequestBuilders.post("/Comment")
.content(json)
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andDo(document("Comment_save", preprocessResponse(prettyPrint())))
.andExpect(MockMvcResultMatchers.status().isOk());
}
看着好像没什么问题,但是执行时发生了错误,Required type must not be null
。
logger.debug("获取服务Bean");
String serviceName = comment.getServiceName();
Class<?> className = Comment.getServiceMap().get(serviceName);
Object service = ContextConfig.getContext().getBean(className);
在调用getBean(Class<T> requiredType)
动态获取Bean
的时候,抛出了异常,requiredType
不能为空,也就是我们调用getBean
传的参数className
是空。
调试
Debug
开启找Bug
模式,我们看我们测试请求的字符串json
是没问题,属性齐全。
走到控制器时,这两个属性就没了。结论:Json
反序列化时出错。
JsonIgnore
原因就在@JsonIgnore
上,我只考虑了后台的对象序列化到前台时需要忽略该属性,从而添加了这个注解。
但是这个注解是在序列化与反序列化时都生效的,也就是说:序列化时,忽略该属性;反序列化时,也忽略该属性。所以造成了绑定时@JsonIgnore
标注的属性为null
的结果。
解决
去掉@JsonIgnore
注解,一切正常。
总结
记得第一次见到@JsonIgnore
注解时去网上查这个注解时干什么的。
谷歌第一条。然后,没有认真看,一直以为是JsonIgnore
只在对象序列化为json
是才起作用。导致了误用。
JsonIgnore
在序列化与反序列化时都生效!
一知半解,害己误人。