资讯专栏INFORMATION COLUMN

JsonIgnore误用引发的对象绑定问题

王岩威 / 949人阅读

摘要:问题描述开发通用评论功能时,建立评论实体。调试开启找模式,我们看我们测试请求的字符串是没问题,属性齐全。所以造成了绑定时标注的属性为的结果。在序列化与反序列化时都生效一知半解,害己误人。

问题描述 Comment

开发通用评论功能时,建立评论实体。

/**
 * @author zhangxishuo on 2018/8/19
 * 评论实体
 */
@Entity
@ApiModel(value = "Comment (评论)", description = "评论实体")
public class Comment extends YunZhiAbstractEntity {

    private static final Map> 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;
}

这里因为考虑到需要将信息传递给相关联该评论的实体,所以建了两个额外的属性serviceNamerelationId,但是这个仅在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 requiredType)动态获取Bean的时候,抛出了异常,requiredType不能为空,也就是我们调用getBean传的参数className是空。

调试 Debug

开启找Bug模式,我们看我们测试请求的字符串json是没问题,属性齐全。

走到控制器时,这两个属性就没了。结论:Json反序列化时出错。

JsonIgnore

原因就在@JsonIgnore上,我只考虑了后台的对象序列化到前台时需要忽略该属性,从而添加了这个注解。

但是这个注解是在序列化与反序列化时都生效的,也就是说:序列化时,忽略该属性;反序列化时,也忽略该属性。所以造成了绑定时@JsonIgnore标注的属性为null的结果。

解决

去掉@JsonIgnore注解,一切正常。

总结

记得第一次见到@JsonIgnore注解时去网上查这个注解时干什么的。

谷歌第一条。然后,没有认真看,一直以为是JsonIgnore只在对象序列化为json是才起作用。导致了误用。

JsonIgnore在序列化与反序列化时都生效!

一知半解,害己误人。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76785.html

相关文章

  • JQuery坑,说说哪些大家都踩过

    摘要:回调在请求成功或失败都会触发。为避免多次执行,请先做事件解绑再重新绑定。避免响应多次执行错误使用指示符坑人指数指示符存在于一定的上下文中的,当上下文变化时指向不同的对象。 1 乱用选择器 坑人指数:200 JQuery选择器调用代价很大,反复调用效率更低。应采用缓存对象的方法或采用链式调用的方式。 //错误的写法 $(#button).click(function(){ $(#...

    habren 评论0 收藏0
  • 字符串拼接引发BUG

    摘要:你的线上代码真的没有吗欢迎免费使用我们可以帮助您第一时间发现字符串拼接加法仔细查看生成的代码,你会发现出现在标记的后面,然而标签不见了。在中,根据左右两边变量的类型的不同,符号可以用于数字相加或则字符串拼接。然后又转换为字符串拼接起来。 译者按: bug虽小,却是个磨人的小妖精! 原文: Fixing a bug: when concatenated strings turn int...

    zengdongbao 评论0 收藏0
  • Spring Boot QuickStart (5) - Spring Data JPA

    摘要:关联关系的关联关系定义上,感觉并不是很灵活,姿势也比较难找。如,定义在关联关系上的参数可以设置级联的相关东西。因为序列化会涉及到实体类关联对象的获取,会触发所有的关联关系。 接(4) - Database 系列. Java Persistence API,可以理解就是 Java 一个持久化标准或规范,Spring Data JPA 是对它的实现。并且提供多个 JPA 厂商适配,如 Hi...

    sutaking 评论0 收藏0
  • Spring Boot 返回 JSON 数据,一分钟搞定!

    摘要:在项目中返回数据是常见的交互形式,在中这一切都变得十分简单。返回数据格式定义定义返回方式在类上面用定义或者在方法上面用定义,表明是在区域输出数据。返回数据栈长正在拼命写作中,过两天我的公众号会第一时间分享。 在 WEB 项目中返回 JSON 数据是常见的交互形式,在 Spring Boot 中这一切都变得十分简单。So easy!!! 你所需具备的基础 什么是 Spring Boot...

    Backache 评论0 收藏0
  • (讨论)缓存同步、如何保证缓存一致性、缓存误用

    摘要:总结允许的缓存写场景大部分情况,修改成本会高于增加一次,因此应该淘汰缓存如果还在纠结,总是淘汰缓存,问题也不大先操作数据库,还是先操作缓存这里分了两种观点,的观点沈老师的观点。这里我觉得沈老师可能忽略了并发的问题,比如说以下情况一个写请求 缓存误用 缓存,是互联网分层架构中,非常重要的一个部分,通常用它来降低数据库压力,提升系统整体性能,缩短访问时间。 有架构师说缓存是万金油,哪里有问...

    msup 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<