转:http://xinyangwjb.iteye.com/blog/1450586
Json与JavaBean相互转换的工具有很多,比如下面附件中的struts2-json-plugin-2.1.8.1.jar。
具体实现为
- String content = JSONUtil.serialize(javaBean);//将javaBean(包括Domain、List、Map等)转化为String类型的json
- JaveBean jb = (JaveBean)JSONUtil.deserialize(Stirng json);//将String类型的Json转化为JavaBean类型的javaBean
String content = JSONUtil.serialize(javaBean);//将javaBean(包括Domain、List、Map等)转化为String类型的json JaveBean jb = (JaveBean)JSONUtil.deserialize(Stirng json);//将String类型的Json转化为JavaBean类型的javaBean
还有一种就是很常用的json-lib,比如下面附件中的json-lib-2.2.1-jdk15.jar。
具体实现为
- JSON json = JSONSerializer.toJSON( JaveBean );
- JSON json = JSONSerializer.toJSON( JaveBean , jsonConfig);
- JaveBean jb = (JaveBean)JSONSerializer.toJava( json );
- JaveBean jb = (JaveBean)JSONSerializer.toJava(json , jsonConfig);
JSON json = JSONSerializer.toJSON( JaveBean ); JSON json = JSONSerializer.toJSON( JaveBean , jsonConfig); JaveBean jb = (JaveBean)JSONSerializer.toJava( json ); JaveBean jb = (JaveBean)JSONSerializer.toJava(json , jsonConfig);
以上俩个工具都很好,但是有以下问题:
问题 1: 需要有选择的提取 JavaBean 中的属性
转换后的 JSON 数据中包含了 JavaBean 中的全部属性,可是我们常常需要有选择的提取 JavaBean 中的特定属性出来。例如:
需要过滤掉循环引用的属性,这一点 json-lib 提供了 CycleDetectionStrategy 来处理,但是直接过滤掉更简单;
不同的情况下只需要 JavaBean 中的部分属性:比如列表界面只需要显示 Bean 的几个重要属性,而详情界面则需要显示更多的 Bean 的属性;
不同的用户权限限制用户只能获得某些属性数据;
问题 2: 需要自定义某些属性的转换方式
对于普通的 Object 类型(如 Long,String 等),json-lib 有缺省的值转换处理方式,但是对于一些特殊的类型,我们希望用自定义的方式来转换该属性的值。例如:
对于 java.util.Date 类型,我们希望直接转换成时间串:2010-04-10,而不希望得到一个类似 {"year":"2010","month":"4","day":"10"} 这样的结果
对于常用到的代码数据(比如:性别),在定义时它也许是个 Integer(男:1;女:2),我们希望在转换后直接得到:{"性别":"男",...},而不是 {"性别":"1",...}
Json-lib 已经预留出一些接口,让用户修改它的缺省行为。
具体实现我是参考http://www.ibm.com/developerworks/cn/java/j-lo-jsonlib/index.html,以下代码纯属copy,感谢原作者的分享,详细实现请查看原博客:
该博客使用PropertyFilter和JsonConfig来实现过滤,并引入annotation来简化处理代码
代码段一:
- import net.sf.json.JSONSerializer;
- import net.sf.json.JsonConfig;
- import net.sf.json.util.PropertyFilter;
- // 定义属性过滤器
- PropertyFilter filter = new PropertyFilter(
- publicboolean apply(Object source, String name, Object value) {
- if ( name.equals( “pojoId” ) ) {
- returntrue; // 返回 true, 表示这个属性将被过滤掉
- }
- returnfalse;
- }
- );
- // 注册属性过滤器
- JsonConfig config = new JsonConfig();
- config.setJsonPropertyFilter( filter );
- System.out.println( JSONSerializer.toJSON( new MyBean(), config ) );
- // prints {"name":"json"}
import net.sf.json.JSONSerializer; import net.sf.json.JsonConfig; import net.sf.json.util.PropertyFilter; // 定义属性过滤器 PropertyFilter filter = new PropertyFilter( public boolean apply(Object source, String name, Object value) { if ( name.equals( “pojoId” ) ) { return true; // 返回 true, 表示这个属性将被过滤掉 } return false; } ); // 注册属性过滤器 JsonConfig config = new JsonConfig(); config.setJsonPropertyFilter( filter ); System.out.println( JSONSerializer.toJSON( new MyBean(), config ) ); // prints {"name":"json"}
首先先定义annotation和MyBean,并给 MyBean 的 get 方法加上标注,具体实现慢慢来
- import java.lang.annotation.Target;
- import java.lang.annotation.Documented;
- import java.lang.annotation.Retention;
- import java.lang.annotation.ElementType;
- import java.lang.annotation.RetentionPolicy;
- @Documented
- @Target({ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- public@interface Invisible {
- public String[] value();
- }
- // 为myBean中需要过滤的属性get方法(或者is方法)加上Invisible标注
- publicclass MyBean{
- private String name = "json";
- privateint pojoId = 1;
- // getters & setters
- public String getName() { return name; }
- @Invisible(“LIST”) // 在 “LIST” 情况下不要这个属性
- publicint getPojoId() { return pojoId; }
- }
import java.lang.annotation.Target; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.ElementType; import java.lang.annotation.RetentionPolicy; @Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Invisible { public String[] value(); } // 为myBean中需要过滤的属性get方法(或者is方法)加上Invisible标注 public class MyBean{ private String name = "json"; private int pojoId = 1; // getters & setters public String getName() { return name; } @Invisible(“LIST”) // 在 “LIST” 情况下不要这个属性 public int getPojoId() { return pojoId; } }
然后,我们需要一些能处理 annotation 的 PropertyFilter 类
- import java.util.Map;
- import java.lang.reflect.Method;
- import net.sf.json.util.PropertyFilter;
- // 先实现一个abstract类,将读取Bean属性的Method找到并传递给子类处理
- publicabstractclass AbstractMethodFilter implements PropertyFilter {
- // 这个方法留给子类实现,以便适应不同的过滤需求
- publicabstractboolean apply(final Method method);
- publicboolean apply(final Object source, final String name, final Object value) {
- if (source instanceof Map) {
- returnfalse;
- }
- String propName = name.substring(0, 1).toUpperCase() + name.substring(1);
- Class clz = source.getClass();
- String methodName = "get" + propName;
- Method method = null;
- try {
- method = clz.getMethod(methodName, (Class[]) null); // 寻找属性的get方法
- } catch (NoSuchMethodException nsme) {
- String methodName2 = "is" + propName; // 也许是个is方法
- try {
- method = clz.getMethod(methodName2, (Class[]) null);
- } catch (NoSuchMethodException ne) {
- // 没有找到属性的get或者is方法,打印错误,返回true
- System.err.println(“No such methods: ”
- + methodName + “ or “ + methodName2);
- returntrue;
- }
- }
- return apply(method);
- }
- } // END: AbstractMethodFilter
- publicclass InvisibleFilter extends AbstractMethodFilter {
- // 过滤条件,标注中有符合这个条件的property将被过滤掉
- private String _sGUIID;
- public InvisibleFilter(final String guiid) {
- _sGUIID = guiid;
- }
- publicboolean apply(final Method method) {
- if (_sGUIID == null || _sGUIID.equals(“”)) {
- returnfalse; // 表示不做限制
- }
- if (method.isAnnotationPresent(Invisible.class)) {
- Invisible anno = method.getAnnotation(Invisible.class);
- String[] value = anno.value();
- for (int i = 0; i < value.length; i++) {
- if (_sGUIID.equals(value[i])) {
- returntrue;
- }
- }
- }
- returnfalse;
- }
- }
import java.util.Map; import java.lang.reflect.Method; import net.sf.json.util.PropertyFilter; // 先实现一个abstract类,将读取Bean属性的Method找到并传递给子类处理 public abstract class AbstractMethodFilter implements PropertyFilter { // 这个方法留给子类实现,以便适应不同的过滤需求 public abstract boolean apply(final Method method); public boolean apply(final Object source, final String name, final Object value) { if (source instanceof Map) { return false; } String propName = name.substring(0, 1).toUpperCase() + name.substring(1); Class clz = source.getClass(); String methodName = "get" + propName; Method method = null; try { method = clz.getMethod(methodName, (Class[]) null); // 寻找属性的get方法 } catch (NoSuchMethodException nsme) { String methodName2 = "is" + propName; // 也许是个is方法 try { method = clz.getMethod(methodName2, (Class[]) null); } catch (NoSuchMethodException ne) { // 没有找到属性的get或者is方法,打印错误,返回true System.err.println(“No such methods: ” + methodName + “ or “ + methodName2); return true; } } return apply(method); } } // END: AbstractMethodFilter public class InvisibleFilter extends AbstractMethodFilter { // 过滤条件,标注中有符合这个条件的property将被过滤掉 private String _sGUIID; public InvisibleFilter(final String guiid) { _sGUIID = guiid; } public boolean apply(final Method method) { if (_sGUIID == null || _sGUIID.equals(“”)) { return false; // 表示不做限制 } if (method.isAnnotationPresent(Invisible.class)) { Invisible anno = method.getAnnotation(Invisible.class); String[] value = anno.value(); for (int i = 0; i < value.length; i++) { if (_sGUIID.equals(value[i])) { return true; } } } return false; } }
现在只要把这个 filter 注册到 JsonConfig 中,就实现了属性的过滤。
- JsonConfig config = new JsonConfig();
- config.setJsonPropertyFilter( new InvisibleFilter(“LIST”)); //标注了LIST的属性将被过滤掉
- System.out.println( JSONSerializer.toJSON( new MyBean(), config ) );
- // prints {"name":"json"}
JsonConfig config = new JsonConfig(); config.setJsonPropertyFilter( new InvisibleFilter(“LIST”)); //标注了LIST的属性将被过滤掉 System.out.println( JSONSerializer.toJSON( new MyBean(), config ) ); // prints {"name":"json"}
使用 annotation 自定义 Bean 属性的转换方式
Json-lib 通过 JsonConfig 提供了自定义属性转换方式的接口。
- JsonConfig config = new JsonConfig();
- config.registerJsonValueProcessor(java.util.Date.class, new JsDateJsonValueProcessor());
JsonConfig config = new JsonConfig(); config.registerJsonValueProcessor(java.util.Date.class, new JsDateJsonValueProcessor());
注册后 Json-lib 在遇到 java.uitl.Date 类型的属性时,会应用 JsDateJsonValueProcessor 的处理方法。
所以,只要实现自己的 JsonValueProcessor 就可以自定义各种 Object 的转换方式了
根据上一节的讨论,Json-lib 在转换 Bean 属性之前,会将属性数据传递给 PropertyFilter 来判断是否需要过滤掉。因此,我们可以通过一个 Filter 对象获得 Bean 的属性的标注数据,并将它传递给特定的 Processor,Processor 根据得到的标注值知道应该怎么处理这个属性。下面以整型代码为例,说明处理的方法。
一般情况下,一个项目中会涉及许多种不同的代码,我们会为每一种代码定义一个主代码号(代码往往都是整型的),为它的子项定义几个子代码号。例如,我们定义性别的主代码号为 100,并定义男:1,女:2。
首先,需要一个代码标注(IntegerCode)及一个处理这种标注的 PropertyFilter。
- @Documented
- @Target({ElementType.METHOD})
- @Retention(RetentionPolicy.RUNTIME)
- public@interface IntegerCode {
- publicint value();
- }
- publicclass IntegerCodeFilter extends AbstractMethodFilter {
- // 代码处理器
- private IntegerCodeProcessor _processor;
- public IntegerCodeFilter(final IntegerCodeProcessor processor) {
- _processor = processor;
- }
- // 不过滤属性,但当发现IntegerCode标注时,将数据传递给Processor
- publicboolean apply(final Method method) {
- if (_processor == null) {
- returnfalse; // 表示没有特别的处理
- }
- if (method.isAnnotationPresent(IntegerCode.class)) {
- IntegerCode anno = method.getAnnotation(IntegerCode.class);
- int code = anno.value();
- _processor.setMainCode(code); // 将code设置为主代码
- }
- returnfalse;
- }
- }
@Documented @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface IntegerCode { public int value(); } public class IntegerCodeFilter extends AbstractMethodFilter { // 代码处理器 private IntegerCodeProcessor _processor; public IntegerCodeFilter(final IntegerCodeProcessor processor) { _processor = processor; } // 不过滤属性,但当发现IntegerCode标注时,将数据传递给Processor public boolean apply(final Method method) { if (_processor == null) { return false; // 表示没有特别的处理 } if (method.isAnnotationPresent(IntegerCode.class)) { IntegerCode anno = method.getAnnotation(IntegerCode.class); int code = anno.value(); _processor.setMainCode(code); // 将code设置为主代码 } return false; } }
- publicclass IntegerCodeProcessor implements JsonValueProcessor {
- privateint _iMainCode;
- publicvoid setMainCode(finalint mainCode) { _iMainCode = mainCode; }
- public IntegerCodeProcessor() {
- super();
- } // END: IntegerCodeProcessor
- privatevoid reset() {
- _iMainCode = -1;
- }
- public Object processArrayValue(Object value, JsonConfig jsonConfig) {
- return process(value, jsonConfig);
- } // END: processArrayValue
- public Object processObjectValue(
- String key, Object value, JsonConfig jsonConfig ) {
- return process( value, jsonConfig );
- } // END: processObjectValue
- private Object process(Object value, JsonConfig jsonConfig) {
- if (value == null) {
- returnnull;
- }
- String ret = null;
- if (value instanceof Integer && _iMainCode >= 0) {
- int code = value.intValue();
- switch (_iMainCode) {
- case100: // 这里使用简单的case 处理不同的代码
- if (code == 1) { // 好一点的方式是从资源文件中读取对应值
- ret = "man";
- } elseif (code == 2) {
- ret = "woman";
- } else {
- ret = value.toString();
- }
- break;
- default:
- ret = value.toString();
- break;
- }
- } else {
- ret = value.toString();
- }
- reset(); // 处理后重置,以免影响其他 Integer 属性
- return ret;
- } // END: process
- }
public class IntegerCodeProcessor implements JsonValueProcessor { private int _iMainCode; public void setMainCode(final int mainCode) { _iMainCode = mainCode; } public IntegerCodeProcessor() { super(); } // END: IntegerCodeProcessor private void reset() { _iMainCode = -1; } public Object processArrayValue(Object value, JsonConfig jsonConfig) { return process(value, jsonConfig); } // END: processArrayValue public Object processObjectValue( String key, Object value, JsonConfig jsonConfig ) { return process( value, jsonConfig ); } // END: processObjectValue private Object process(Object value, JsonConfig jsonConfig) { if (value == null) { return null; } String ret = null; if (value instanceof Integer && _iMainCode >= 0) { int code = value.intValue(); switch (_iMainCode) { case 100: // 这里使用简单的case 处理不同的代码 if (code == 1) { // 好一点的方式是从资源文件中读取对应值 ret = "man"; } else if (code == 2) { ret = "woman"; } else { ret = value.toString(); } break; default: ret = value.toString(); break; } } else { ret = value.toString(); } reset(); // 处理后重置,以免影响其他 Integer 属性 return ret; } // END: process }
- publicclass Student {
- private String name = "camry";
- privateint gender = 1;
- // getters & setters
- public String getName() { return name; }
- @IntegerCode(100) // 性别主代码为 100
- publicint getGender() { return gender; }}
- }
- ...
- IntegerCodeProcessor processor = new IntegerCodeProcessor();
- IntegerCodeFilter filter = new IntegerCodeFilter(processor);
- JsonConfig config = new JsonConfig();
- config.setJsonPropertyFilter( filter );
- config.registerJsonValueProcessor(Integer.class, processor);
- System.out.println( JSONSerializer.toJSON( new Student(), config ) );
- // prints {“gender”:”man”, "name":"camry"}
相关推荐
json 所需要的jackson-annotations-2.4.0.jar,jackson-core-2.4.2.jar, jackson-databind-2.4.2.jar,jackson-mapper-asl-1.9.11.jar
JSON到Java Bean转换工具,如"json2javabean"和"josnschema2pojo",是开发人员在处理JSON数据与Java对象之间转换时的便利工具。这些工具能够根据JSON格式的数据自动生成对应的Java类,使得数据绑定变得更加简单和...
在Java开发中,有时我们需要将XML转换为JSON,反之亦然,或者将这些格式与JavaBean对象进行互换,以便于数据处理和传输。本篇文章将深入探讨XML、JSON与JavaBean之间的转换方法。 首先,我们来看XML和JSON的特性。...
json对象与javabean相互转化 JSONObject jsonObj=JSONObject.fromObject(s);//将字符串转化为json对象 //写数据库处理 ObjBean bean=(ObjBean)JSONObject.toBean(jsonObj,ObjBean.class); ObjBean bean=new ...
本节将详细讲解如何在Java中进行JavaBean与Json的转换。 首先,我们来看JavaBean。JavaBean遵循一定的规范,通常包含一个无参数的构造器,属性私有化并提供getter和setter方法,以及可能的逻辑业务方法。例如,一个...
本篇将深入探讨JavaBean与JsonString之间的相互转换方法。 1. **什么是JavaBean** JavaBean是一种遵循特定规则的Java类,它主要用于封装数据,便于数据的存储和传递。JavaBean通常具有以下特点: - 是公共类...
最近在研究Webservice的时候遇到一个问题,把java对象转化问json后传过去,接受的是String类型,怎么恢复到原来的java对象呢,后来再一个项目中看到了转换方法,转换顺序为javaBean--jsonObject--jsonString,还原...
**XStream:JavaBean与XML/JSON之间的转换大师** XStream是一个开源库,它为Java对象提供了简单且直观的XML序列化和反序列化的解决方案。它不仅能够将Java对象转换成XML,反之亦然,还能支持JSON格式的转换。这个...
XStream示例代码,JavaBean与XML,JSON之间互相转换(包含完整jar包)jettison-1.3.3.jar、xmlpull-1.1.3.1.jar、xstream-1.4.7.jar
本篇文章将详细讲解如何在Java中使用`json-lib`库进行JSON与Java对象之间的相互转换,并提供相关的jar包列表。 首先,`json-lib`是一个非常流行的Java JSON库,它提供了多种Java数据类型与JSON之间的转换功能,包括...
在Java中,为了实现JSON与Java数据类型的相互转换,通常会使用第三方库,如FastJSON、Jackson、Gson等。这里提到的是FastJSON,它是阿里巴巴提供的一个高性能的JSON库。 1. **JavaBean到JSON的转换** 要将...
总结,GsonFormat插件是Android Studio中的一款神器,它极大地简化了JSON数据到JavaBean类的转换过程,而Gson库则提供了JSON与Java对象之间的相互转换功能。熟练掌握这两项工具,能显著提升你的Android开发效率。
Java与JSON互相转换是开发过程中常见的需求,尤其是在服务器端与前端之间传递数据时。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,因其易读性、易写性和高效性,被广泛应用于Web服务。Java则是...
在Java中,与JSON数据进行交互,通常需要将Java对象(javabean)与JSON字符串相互转换。下面将介绍几种常见的转换方式,并展示示例代码。 一、Java对象与JSON字符串的互转 首先,Java对象与JSON字符串之间的转换...
FastJson支持JSON格式字符串、JSON对象(JSONObject)以及JavaBean之间的相互转换,使得数据处理变得简单。以下将详细解释这些转换操作。 1. JSON格式字符串到JSON对象的转换: 使用`JSON.parseObject()`方法可以...
在Java中,为了实现JSON与Java数据类型的相互转换,通常会使用到一些库,如JSON-P,JSON-B,或者这里提及的net.sf.json.JSONObject,这是一个开源的JSON库。 一、Java对象转换为JSON字符串: 在Java中,如果我们有...
在Java开发中,处理JSON数据时,我们经常需要将JSON字符串与Java对象之间进行相互转换,这正是"json转换插件"所扮演的角色。 这个插件的核心功能是提供了一个桥梁,连接JavaScript提交的JSON字符串和Java世界中的...
通过这样的工具包,开发者可以在项目中方便地进行JSON和BEAN的相互转换,提高代码的可读性和可维护性。此外,还可以考虑添加更多的功能,如JSON数组与BEAN集合的转换,或者支持自定义的转换策略,使得工具包更加灵活...
这个Jar包还支持JavaBean和JSON之间的相互转换。JavaBean是一种符合Java设计模式的类,通常用于封装数据。通过`JSONObject.fromObject()`方法,你可以将JavaBean对象转换为JSON对象;反之,使用`JSONObject.toBean()...
总结来说,JSON-lib是Java开发者处理JSON数据的强大工具,它可以方便地进行Java对象与JSON之间的转换,以及JSON与XML之间的互操作,简化了数据交换和处理的复杂性。在实际项目中,根据需求选择合适的版本和配置,...