zoukankan      html  css  js  c++  java
  • Json Serialize 忽略特定属性

    Json Serialize 忽略特定属性

    Json Serialize SerializeFilter 忽略特定属性

    key words:Json Serialize jackson fastjson springmvc responsebody lodash

    问题描述

    SpringMVC中直接可以返回经过序列化的对象,只需要在Controller上加上 @ResponseBody
    例如:

    model 代码:

    public class A{
    	private long id;
    	private String name;
    	private String avatar;
    	private int score;
    	private B b;
    
    	//......setter and getter
    }
    

    controller代码:

    @RequestMapping("/A")
    @ResponseBody
    public A getModel(){
    	A a = new A();
    	a.setName("one");
    	a.setAvatar("avatar.jpg");
    	return a;
    }
    

    那么在前端请求/A时就会得到:

    {id:0,name:"one",avatar:"avatar.jpg",score:0,b:null}
    

    这不是我希望的结果,我希望前端只能拿到它所需要的name 和 avatar。

    1. 我不希望暴露后端bean的所有Properties
    2. 基本类型都被赋予了默认值0,这也许会给前端造成误解。例如score在数据库里本来是100,但序列化时附带了score=0
    3. 返回了大量无意义的、潜藏危险的数据

    有缺陷的解决方案

    能想到的解决方案有如下:

    1.用mybatis时,每次查询结果数据,用Map来承载,而不是bean,在Controller中也是如此(甚至可以剔除model层)。但这样就要求对数据库表非常了解,而牺牲了很多便利操作(如 增、改操作)

    2.返回时,新建ViewModel,用ViewModel来过滤。比较麻烦

    3.jackson,@JsonIgnore。不满足要求,需要序列化的Property,并非固定的。这次我要id,name,下次我可能要name,score

    4.使用fastjson的SerializeFilter ,具体见这里。还是有点缺陷,遇到多层次引用就不知道怎么办了:List< A > ,A包含B,过滤了A,却暴露了B。(可能是没深入研究。。。。)

    @RequestMapping("/A")
    @ResponseBody
    public String getModel(){
    	//A a
    	SimplePropertyPreFilter filter = new SimplePropertyPreFilter(); // 构造方法里,也可以直接传需要序列化的属性名字
    	filter.getExcludes().add("id");
    	filter.getExcludes().add("score");
    	return JSON.toJSONString(a, filter);
    }
    

    不知道java里面有没有类似于lodash.js 中的pick函数的方法,可能javascript里面是弱对象,所以实现和效率都不成问题吧。

    贴一段代码求java解决方案:

    //载入lodash.js
    var _   = require('lodash');
    
    ep.all('topics', function (topics) {
        topics.forEach(function (topic) {
          UserModel.findById(topic.author_id, ep.done(function (author) {
            if (mdrender) {
              topic.content = renderHelper.markdown(at.linkUsers(topic.content));
            }
            topic.author = _.pick(author, ['loginname', 'avatar_url']);
            ep.emit('author');
          }));
        });
    
        ep.after('author', topics.length, function () {
          topics = topics.map(function (topic) {
            return _.pick(topic, ['id', 'author_id', 'tab', 'content', 'title', 'last_reply_at',
              'good', 'top', 'reply_count', 'visit_count', 'create_at', 'author']);
          });
    
          res.send({data: topics});
        });
    });
  • 相关阅读:
    十大开源CRM
    编码转换与网址解码
    1、ADO.NET相关对象一句话介绍
    接口与抽象类对比
    C#中的文件下载问题
    在WinForm下获取粘贴板中HTML格式的数据
    Exchange学习
    用Log Explorer恢复数据的基本操作
    iframe的问题
    再发一个C#版的日历
  • 原文地址:https://www.cnblogs.com/sloong/p/5047583.html
Copyright © 2011-2022 走看看