在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:beetl-json开源软件地址:https://gitee.com/xiandafu/beetl-json开源软件介绍:##介绍: - 作者:闲.大赋(同时也开发了Beetl模版语言)- 功能:Beetl-JsonTool 作为beetl模板引擎的一个附属工具,提供了对象序列化成json技术。其原理是基于(Location:action)*,功能强大,扩展性强,比fastjson,jackson,gosn基于annotatoin的强大,也远远超过了jodd json,flexjson序列化能力 而体积小,仅仅不到80K。它能允许通过序列化策略来个性化的序列化对象到JSON而无需编程或者包装原有对象,而它的性能也是相当优秀。 ##例子:
序列化规则可以有多个,每个包含一个location和action对,用冒号分开,每个序列化规则用逗号分开,这个类似json的格式,如name:i,user.id:i,~L/#ju.Collection*/:->null如上表示三个序列化规则,*第一个是忽略属性name*第二个是忽略user属性的id属性*第三个要复杂一些,意思当序列到Collecton类及其子类时候,直接赋值为null(#jl是java.util的别名)。 location和action有可能出现//,这类似程序语言的(),里面是参数,如~L/#ju.Collection*/ ##Action定义了一个匹配动作的输出,有忽略属性,包含属性,排序,改名,条件判断,直接赋值,调用回调等
##循环处理 注意,当序列化出现循环引用的,beetl-json不会再列化已经序列化过的对象,取而代之是用$ref:path来指向上次序列化的对象,path从根目录开始,如 user:{ "$ref":"$.list[0].user"} 如果同时还使用了ci,cu,可以选择性额外的输出一些属性,而不是枯燥的 "$ref":path,如:序列化规则是~/User/:cu/name/ 意思当User对象出现在循环引用里,除了输出$ref外,还输出name属性。生成结果类似如下: user:{ "$ref":"$.list[0].user",name:'xiandafu'} 这样使得输json更容易阅读,有些JS前端框架也可以利用额外的这些属性 ##Location定义了一个序列化的位置,如属性名,或者属性表达式,列表(数组)元素,类等
locaton 可以是属性表达式
注意,目前不支持在~L/Class/后面继续用属性表达式 ##API例子: //全局设定,对于所有对象都适用 JsonTool tool = new JsonTool(); tool.addLocationAction("~d","f/yyyy.MM.dd/"); tool.addLocationAction("~L/java.util.Calendar*/","$.getTime->f/yyyy-MM-dd/"); //类json格式的策略,用逗号分开多个locationAction tool.addPolicy("~f:n/#.##/,~c:?null->[]"); // 默认是紧凑输出,使用true,将换行和缩进 tool.pretty = true; tool.addAlias("loc", "org.beetl.json.test.location"); //序列化User String json = tool.serialize(User); //or 指定一个序列化策略,age,name先输出,适合有特殊需求的对象或者无法注解(第三方)对象 String json2 = tool.serialize(User,"~*:o/age,name/")); // 同上策略,但name属性输出改为code String json2 = tool.serialize(User,"~*:o/age,name/,name:nn/code/")); // 同上策略,像api传递俩个策略 String json2 = tool.serialize(User,"~*:o/age,name/","name:nn/code/")); //序列化dept,Department跟SysUser是一对多关系,如果俩个类都重复引用,则忽略导致重复引用的dept字段和users字段 String json1 = tool.serialize(dept, "~L/#loc.SysUser/:ci/dept/,~L/#loc.Department/:ci/users/"); 注解默认情况下,也可以用注解来作为序列化策略。 @Json( policys={ @JsonPolicy(location="name", action="nn/newUserName/"), @JsonPolicy(location="deleteList", action="?empty->[]") })public class User{ String name="joel"; int age =12; double salary=12.32266; Customer customer = new Customer(); List<Customer> list = new ArrayList<Customer>(); List<Customer> deleteList = null; //getter and setter 方法必须有,在此忽略}@Json( policys={ @JsonPolicy(location="name", action="nn/userName/") })class Customer{ String name="lijz"; int age=11; Date bir = new Date(); //getter and setter 方法必须有,在此忽略} ##Action扩展 允许自定义Action来处理序列化特殊需求,Action可以实现IValueAction,用来处理渲染对象,也可以实现IKeyAction,IInstanceAction等。如下代码实现一个IValueAction,当检测到对象并未真正hibernate加载的时候,不序列化,从而避免hibernate懒加载问题 JsonTool tool = new JsonTool(); tool.addAction("hibernate", new IValueAction() { @Override public int getIndex() { // TODO Auto-generated method stub return 0; } @Override public ActionReturn doit(OutputNodeKey field, Object value, OutputNode thisNode, JsonWriter w) { if (value instanceof HibernateProxy) {// hibernate代理对象 LazyInitializer initializer = ((HibernateProxy) value).getHibernateLazyInitializer(); if (initializer.isUninitialized()) { return new ActionReturn(null,ActionReturn.RETURN); } } else if (value instanceof PersistentCollection) {// 实体关联集合 PersistentCollection collection = (PersistentCollection) value; if (!collection.wasInitialized()) { return new ActionReturn(null,ActionReturn.RETURN); } else if (collection.getValue() == null) { return new ActionReturn(null,ActionReturn.RETURN); } } return new ActionReturn(value,ActionReturn.CONTINUE); } }); String joins = "location,customer" List cars = service.findAll(joins); String json = tool.serialize(cars,"*:!hibernate"); ##格式化扩展可以自定义一个格式化函数,如下代码 JsonTool.addFormat("simple", new MyDateFomrat()); public class MyDateFomrat implements Format{ public Object format(Object o) { // TODO Auto-generated method stub return "2015"; } } //序列化item,其属性bir按照simple来格式化,f是acton前缀,simple是注册的格式化函数 String json1 = JsonTool.serialize(item, "bir:fsimple"); 主要api:
SpringMVC集成:配置如下: <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="org.beetl.json.ext.BeetlJsonHttpMessageConverter"> <property name="supportedMediaTypes" value="text/html;charset=UTF-8"/> <property name="policys"> <map> <entry key="~d" value="f/yyyy-MM-dd/"/> </map> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> 代码例子 @RequestMapping(value = "/json.html", method = RequestMethod.GET) @ResponseBody public List index1(HttpServletRequest req) { List list = new ArrayList(); list.add(1); list.add(2); list.add(new Date()); return list; } 如果想自定义序列化策略,而不是用Annotaion,可以采用SerObject对象 @RequestMapping(value = "/json2.html", method = RequestMethod.GET) @ResponseBody public SerObject index2(HttpServletRequest req) { List list = new ArrayList(); list.add(1); list.add(2); list.add(new Date()); SerObject s = new SerObject(list,"[1]:i"); //忽略第2个元素 return s; } 更多例子参考单元测试代码 https://git.oschina.net/xiandafu/beetl-json/tree/master/test maven 地址<dependency> <groupId>com.ibeetl</groupId> <artifactId>btjson</artifactId> <version>0.94</version></dependency> 下一步:
|
请发表评论