高效的JSON转换工具

 

 

       在网上搜索了一番发现用json-lib进行json格式转换的还真不少,但是经过测试性能不太令人满意,同类工具中还有个后起

之秀那就是jackson,单从性能上说要比json-lib好很多,于是在项目中就决定用jackson了。
     但是关于jackson的资料在网上相比不是很多,于是到了官方网站看了看,把源码下载下来。帮助文档做的不太好,也没有

个现成的例子供参考。不过还好,最后在官方网(http://jackson.codehaus.org/)站的某个角落里找到了一些例子, 我在原来例子的基础上稍加改动封装了一个工具,供网友们参考,有不当之处还望拍砖指正。

      为性能考虑尽量少的向客户端发送数据,所以在Bean到JSON转换的时候把不需要的字段过滤掉,要完成这个功能我们必须自定义一个实现StdSerializerProvider接口的序列化器BzStdSerializerProvider,然后把这个序列化器赋给ObjectMapper即可,下面就把整个具体实现贴出来:

view plaincopy to clipboardprint?

  1. package com.bzlccn.oa.common.json.jackson;  
  2. import java.io.IOException;  
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Vector;  
  6. import org.codehaus.jackson.JsonGenerator;  
  7. import org.codehaus.jackson.JsonParseException;  
  8. import org.codehaus.jackson.map.JsonMappingException;  
  9. import org.codehaus.jackson.map.ObjectMapper;  
  10. import org.codehaus.jackson.map.SerializationConfig;  
  11. import org.codehaus.jackson.map.SerializerFactory;  
  12. import org.codehaus.jackson.map.SerializerProvider;  
  13. import org.codehaus.jackson.map.introspect.BasicBeanDescription;  
  14. import org.codehaus.jackson.map.ser.BeanPropertyWriter;  
  15. import org.codehaus.jackson.map.ser.BeanSerializer;  
  16. import org.codehaus.jackson.map.ser.CustomSerializerFactory;  
  17. import org.codehaus.jackson.map.ser.StdSerializerProvider;  
  18. /** 
  19.  * json处理工具集 
  20.  *  
  21.  * @author rain 
  22.  *  
  23.  */  
  24. public class CustomSerialization {  
  25.     private static final ObjectMapper mapper = new ObjectMapper();  
  26.     static class FilteredWriter extends BeanPropertyWriter {  
  27.         public FilteredWriter(BeanPropertyWriter w) {  
  28.             super(w);  
  29.         }  
  30.         public void serializeAsField(Object bean, JsonGenerator jgen,  
  31.                 SerializerProvider prov) throws Exception {  
  32.             BzStdSerializerProvider myprov = (BzStdSerializerProvider) prov;  
  33.             HashMap<?, ?> filter = myprov.getCurrentFilter();  
  34.             if (filter == null) {  
  35.                 super.serializeAsField(bean, jgen, prov);  
  36.             } else if (filter.containsKey(this._name)) {  
  37.                 Object subfilter = filter.get(this._name);  
  38.                 myprov.pushFilter(HashMap.class.isAssignableFrom(subfilter  
  39.                         .getClass()) ? (HashMap<?, ?>) subfilter : null);  
  40.                 super.serializeAsField(bean, jgen, prov);  
  41.                 myprov.popFilter();  
  42.             }  
  43.         }  
  44.     }  
  45.     static class CustomBeanFactory extends CustomSerializerFactory  
  46.     {  
  47.         @Override  
  48.         protected BeanSerializer processViews(SerializationConfig config,  
  49.                 BasicBeanDescription beanDesc, BeanSerializer ser,  
  50.                 List<BeanPropertyWriter> props) {  
  51.             ser = super.processViews(config, beanDesc, ser, props);  
  52.             BeanPropertyWriter[] writers = props  
  53.                     .toArray(new BeanPropertyWriter[props.size()]);  
  54.             for (int i = 0; i < writers.length; ++i) {  
  55.                 writers[i] = new FilteredWriter(writers[i]);  
  56.             }  
  57.             ser = ser.withFiltered(writers);  
  58.             return ser;  
  59.         }  
  60.     }  
  61.     static class BzStdSerializerProvider extends StdSerializerProvider {  
  62.         private HashMap<?, ?> _filter;  
  63.         private Vector<HashMap<?, ?>> _stack = new Vector<HashMap<?, ?>>();  
  64.         public BzStdSerializerProvider() {  
  65.             super();  
  66.         }  
  67.         public BzStdSerializerProvider(HashMap<?, ?> filter) {  
  68.             super();  
  69.             _filter = filter;  
  70.         }  
  71.         protected BzStdSerializerProvider(SerializationConfig config,  
  72.                 StdSerializerProvider src, SerializerFactory f) {  
  73.             super(config, src, f);  
  74.         }  
  75.         protected BzStdSerializerProvider(SerializationConfig config,  
  76.                 StdSerializerProvider src, SerializerFactory f,  
  77.                 HashMap<?, ?> filter) {  
  78.             super(config, src, f);  
  79.             _filter = filter;  
  80.         }  
  81.         protected StdSerializerProvider createInstance(  
  82.                 SerializationConfig config, SerializerFactory jsf) {  
  83.             return new BzStdSerializerProvider(config, this, jsf, _filter);  
  84.         }  
  85.         public HashMap<?, ?> getCurrentFilter() {  
  86.             if (_stack.isEmpty())  
  87.                 return _filter;  
  88.             return _stack.lastElement();  
  89.         }  
  90.         public void pushFilter(HashMap<?, ?> filter) {  
  91.             _stack.add(filter);  
  92.         }  
  93.         public void popFilter() {  
  94.             if (!_stack.isEmpty()) {  
  95.                 _stack.removeElement(_stack.lastElement());  
  96.             }  
  97.         }  
  98.     }  
  99.     /** 
  100.      * 把对应的bean转换成json串,并可以对多余的字段进行过滤 
  101.      * @param bean 要转换的bean 
  102.      * @param filter 过滤字符串 
  103.      * @return 
  104.      */  
  105.     public static String writeBean(ObjectMapper mapper,Object bean, String filter) {  
  106.         try {  
  107.             if (bean != null && filter != null) {  
  108.                 HashMap<?, ?> filterMap = mapper.readValue(filter,  
  109.                         HashMap.class);  
  110.                 mapper.setSerializerProvider(new BzStdSerializerProvider(  
  111.                         filterMap));  
  112.                 mapper.setSerializerFactory(new CustomBeanFactory());  
  113.                 return mapper.viewWriter(String.class).writeValueAsString(bean);  
  114.             }  
  115.         } catch (JsonParseException e) {  
  116.             e.printStackTrace();  
  117.         } catch (JsonMappingException e) {  
  118.             e.printStackTrace();  
  119.         } catch (IOException e) {  
  120.             e.printStackTrace();  
  121.         }  
  122.         return null;  
  123.     }  
  124.     /** 
  125.      * 把对应的bean转换成json串,并可以对多余的字段进行过滤 
  126.      * @param bean 要转换的bean 
  127.      * @param filter 过滤字符串 
  128.      * @return 
  129.      */  
  130.     public static String writeBean(Object bean, String filter) {  
  131.         try {  
  132.             if (bean != null && filter != null) {  
  133.                 HashMap<?, ?> filterMap = mapper.readValue(filter,  
  134.                         HashMap.class);  
  135.                 mapper.setSerializerProvider(new BzStdSerializerProvider(  
  136.                         filterMap));  
  137.                 mapper.setSerializerFactory(new CustomBeanFactory());  
  138.                 return mapper.viewWriter(String.class).writeValueAsString(bean);  
  139.             }  
  140.         } catch (JsonParseException e) {  
  141.             e.printStackTrace();  
  142.         } catch (JsonMappingException e) {  
  143.             e.printStackTrace();  
  144.         } catch (IOException e) {  
  145.             e.printStackTrace();  
  146.         }  
  147.         return null;  
  148.     }  
  149.     /** 
  150.      * 把javabean转换成json串 
  151.      * @param bean 
  152.      * @return 
  153.      */  
  154.     public static String writeBean(Object bean) {  
  155.         try {  
  156.             if (bean != null) {  
  157.                 return mapper.writeValueAsString(bean);  
  158.             }  
  159.         } catch (JsonParseException e) {  
  160.             e.printStackTrace();  
  161.         } catch (JsonMappingException e) {  
  162.             e.printStackTrace();  
  163.         } catch (IOException e) {  
  164.             e.printStackTrace();  
  165.         }  
  166.         return null;  
  167.     }  
  168. }  

上述类只是一个实现过滤功能的Bean to Json的工具类,当然你也可以继续扩展。下面我们继续完善,提供一个综合的,支持过滤的,能JSON互转的,转换内容以及方法能自定义的一个综合JSON转换工具,当然要有上边的类做支持了。这是一个基于接口的动态代理的实现,

具体代码如下。

view plaincopy to clipboardprint?

  1. package com.bzlccn.oa.common.json.jackson;  
  2.   
  3. import java.io.*;  
  4. import java.lang.reflect.InvocationHandler;  
  5. import java.lang.reflect.Method;  
  6. import java.lang.reflect.Proxy;  
  7. import java.lang.reflect.Type;  
  8. import java.net.URL;  
  9. import java.util.LinkedHashMap;  
  10. import java.util.Map;  
  11. import org.codehaus.jackson.JsonEncoding;  
  12. import org.codehaus.jackson.JsonGenerator;  
  13. import org.codehaus.jackson.JsonParser;  
  14. import org.codehaus.jackson.map.JsonMappingException;  
  15. import org.codehaus.jackson.map.ObjectMapper;  
  16. import org.codehaus.jackson.map.RuntimeJsonMappingException;  
  17. import org.codehaus.jackson.map.SerializationConfig;  
  18. import org.codehaus.jackson.map.type.TypeFactory;  
  19. import org.codehaus.jackson.type.JavaType;  
  20.   
  21. public class JacksonProxy {  
  22.      private JacksonProxy() {}  
  23.         public static <T> T newProxyInstance(Class<T> type, Class<?>... additionalTypes) {  
  24.             ObjectMapper objectMapper = new ObjectMapper();  
  25.             return newProxyInstance(objectMapper, type, additionalTypes);  
  26.         }  
  27.         public static <T> T newProxyInstance(ObjectMapper objectMapper, Class<T> type, Class<?>... additionalTypes) {  
  28.             ClassLoader classLoader = Thread.currentThread().getContextClassLoader();  
  29.             if (classLoader == null) classLoader = type.getClassLoader();  
  30.             Class<?>[] interfaces = new Class<?>[additionalTypes.length + 1];  
  31.             interfaces[0] = type;  
  32.             System.arraycopy(additionalTypes, 0, interfaces, 1, additionalTypes.length);  
  33.             InvocationHandler invocationHandler = new JsonInvocationHandler(objectMapper, interfaces);  
  34.             Object proxy = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);  
  35.             return type.cast(proxy);  
  36.         }  
  37.         public static ObjectMapper getObjectMapper(Object proxy) {  
  38.             InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);  
  39.             if (invocationHandler instanceof JsonInvocationHandler) {  
  40.                 JsonInvocationHandler jsonInvocationHandler = (JsonInvocationHandler) invocationHandler;  
  41.                 return jsonInvocationHandler.getObjectMapper();  
  42.             }  
  43.             throw new IllegalArgumentException("Proxy is not a JacksonProxy");  
  44.         }  
  45.         public static class JsonInvocationHandler implements InvocationHandler {  
  46.             private final ObjectMapper objectMapper;  
  47.             private final Map<Method, Handler> handlers = new LinkedHashMap<Method, Handler>();  
  48.             public JsonInvocationHandler(ObjectMapper objectMapper, Class<?>[] interfaces) {  
  49.                 if (objectMapper == nullthrow new NullPointerException("mapper is null");  
  50.                 if (interfaces == nullthrow new NullPointerException("type is null");  
  51.                 this.objectMapper = objectMapper;  
  52.                 for (Class<?> type : interfaces) {  
  53.                     for (Method method : type.getMethods()) {  
  54.                         String name = method.getName();  
  55.                         Class<?>[] parameterTypes = method.getParameterTypes();  
  56.                         Class<?> returnType = method.getReturnType();  
  57.                         if (name.startsWith("read")) {  
  58.                             if (parameterTypes.length == 1 && !returnType.equals(Void.TYPE)) {  
  59.                                 ReadHandler handler = new ReadHandler(objectMapper, method.getGenericReturnType(), canThrowIOException(method));  
  60.                                 handlers.put(method, handler);  
  61.                             }  
  62.                         } else if (name.startsWith("write")) {  
  63.                             if (Void.TYPE.equals(returnType)) {  
  64.                                 WriteHandler handler = new WriteHandler(objectMapper, null, canThrowIOException(method));  
  65.                                 handlers.put(method, handler);  
  66.                             }else{  
  67.                                 WriteHandler handler = new WriteHandler(objectMapper, returnType, canThrowIOException(method));  
  68.                                 handlers.put(method, handler);  
  69.                             }  
  70.                         }  
  71.                     }  
  72.                 }  
  73.             }  
  74.             public ObjectMapper getObjectMapper() {  
  75.                 return objectMapper;  
  76.             }  
  77.             @Override  
  78.             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  79.                 Handler handler = handlers.get(method);  
  80.                 if (handler == null) {  
  81.                     throw new UnsupportedOperationException(method.toString());  
  82.                 }  
  83.                 return handler.invoke(args);  
  84.             }  
  85.             private static boolean canThrowIOException(Method method) {  
  86.                 for (Class<?> exceptionType : method.getExceptionTypes()) {  
  87.                     if (IOException.class.isAssignableFrom(exceptionType)) {  
  88.                         return true;  
  89.                     }  
  90.                 }  
  91.                 return false;  
  92.             }  
  93.         }  
  94.         private static interface Handler {  
  95.             Object invoke(Object[] args) throws Throwable;  
  96.         }  
  97.         private static class ReadHandler implements Handler {  
  98.             private final ObjectMapper mapper;  
  99.             private final JavaType javaType;  
  100.             private final boolean canThrowIoException;  
  101.             public ReadHandler(ObjectMapper mapper, Type type, boolean canThrowIoException) {  
  102.                 this.mapper = mapper;  
  103.                 javaType = TypeFactory.fromType(type);  
  104.                 this.canThrowIoException = canThrowIoException;  
  105.             }  
  106.             @Override  
  107.             public Object invoke(Object[] args) throws Throwable {  
  108.                 try {  
  109.                     Object source = args[0];  
  110.                     return read(source);  
  111.                 } catch (IOException e) {  
  112.                     if (canThrowIoException) {  
  113.                         throw e;  
  114.                     } else {  
  115.                         throw new RuntimeJsonMappingException((JsonMappingException) e);  
  116.                     }  
  117.                 }  
  118.             }  
  119.             public Object read(Object source) throws IOException {  
  120.                 if (source == null) {  
  121.                     throw new NullPointerException("source is null");  
  122.                 }  
  123.                 JsonParser parser;  
  124.                 if (source instanceof String) {  
  125.                     String string = (String) source;  
  126.                     parser = mapper.getJsonFactory().createJsonParser(string);  
  127.                 } else if (source instanceof byte[]) {  
  128.                     byte[] bytes = (byte[]) source;  
  129.                     parser = mapper.getJsonFactory().createJsonParser(bytes);  
  130.                 } else if (source instanceof Reader) {  
  131.                     Reader reader = (Reader) source;  
  132.                     parser = mapper.getJsonFactory().createJsonParser(reader);  
  133.                     parser.disableFeature(JsonParser.Feature.AUTO_CLOSE_SOURCE);  
  134.                 } else if (source instanceof InputStream) {  
  135.                     InputStream inputStream = (InputStream) source;  
  136.                     parser = mapper.getJsonFactory().createJsonParser(inputStream);  
  137.                     parser.disableFeature(JsonParser.Feature.AUTO_CLOSE_SOURCE);  
  138.                 } else if (source instanceof File) {  
  139.                     File file = (File) source;  
  140.                     parser = mapper.getJsonFactory().createJsonParser(file);  
  141.                 } else if (source instanceof URL) {  
  142.                     URL url = (URL) source;  
  143.                     parser = mapper.getJsonFactory().createJsonParser(url);  
  144.                 } else {  
  145.                     throw new UnsupportedOperationException("Unsupported source type " + source.getClass() + " for JSON read method");  
  146.                 }  
  147.                 try {  
  148.                     return mapper.readValue(parser, javaType);  
  149.                 } finally {  
  150.                     parser.close();  
  151.                 }  
  152.             }  
  153.         }  
  154.         private static class WriteHandler implements Handler {  
  155.             private final ObjectMapper mapper;  
  156.             private final Class<?> returnType;  
  157.             private final boolean canThrowIoException;  
  158.             public WriteHandler(ObjectMapper mapper, Class<?> returnType, boolean canThrowIoException) {  
  159.                 this.mapper = mapper;  
  160.                 this.returnType = returnType;  
  161.                 this.canThrowIoException = canThrowIoException;  
  162.             }  
  163.             @Override  
  164.             public Object invoke(Object[] args) throws Throwable {  
  165.                 try {  
  166.                     Object value = args[0];  
  167.                     if (returnType == null) {  
  168.                         Object target = args[1];  
  169.                         write(value, target);  
  170.                         return null;  
  171.                     } else if (String.class.equals(returnType)) {  
  172.                         if (args.length>=2&&args[1]!=null) {//如果返回类型是String且有第二个参数,那么就默认第二个参数为过滤参数  
  173.                             return CustomSerialization.writeBean(value, args[1].toString());  
  174.                         } else {  
  175.                             StringWriter stringWriter = new StringWriter();  
  176.                             write(value, stringWriter);  
  177.                             return stringWriter.toString();  
  178.                         }  
  179.                     } else if (byte[].class.equals(returnType)) {  
  180.                         ByteArrayOutputStream out = new ByteArrayOutputStream();  
  181.                         write(value, out);  
  182.                         return out.toByteArray();  
  183.                     } else {  
  184.                         throw new UnsupportedOperationException("Unsupported target type " + returnType + " for JSON write method");  
  185.                     }  
  186.                 } catch (IOException e) {  
  187.                     if (canThrowIoException) {  
  188.                         throw e;  
  189.                     } else {  
  190.                         throw new RuntimeJsonMappingException((JsonMappingException) e);  
  191.                     }  
  192.                 }  
  193.             }  
  194.             public void write(Object value, Object target) throws IOException {  
  195.                 if (target == null) {  
  196.                     throw new NullPointerException("target is null");  
  197.                 }  
  198.                 JsonGenerator generator;  
  199.                 if (target instanceof Writer) {  
  200.                     Writer writer = (Writer) target;  
  201.                     generator = mapper.getJsonFactory().createJsonGenerator(writer);  
  202.                     generator.disableFeature(JsonGenerator.Feature.AUTO_CLOSE_TARGET);  
  203.                 } else if (target instanceof OutputStream) {  
  204.                     OutputStream outputStream = (OutputStream) target;  
  205.                     generator = mapper.getJsonFactory().createJsonGenerator(outputStream, JsonEncoding.UTF8);  
  206.                     generator.disableFeature(JsonGenerator.Feature.AUTO_CLOSE_TARGET);  
  207.                 } else if (target instanceof File) {  
  208.                     File file = (File) target;  
  209.                     generator = mapper.getJsonFactory().createJsonGenerator(file, JsonEncoding.UTF8);  
  210.                 } else {  
  211.                     throw new UnsupportedOperationException("Unsupported target type " + target.getClass() + " for JSON write method");  
  212.                 }  
  213.                 if (mapper.getSerializationConfig().isEnabled(SerializationConfig.Feature.INDENT_OUTPUT)) {  
  214.                     generator.useDefaultPrettyPrinter();  
  215.                 }  
  216.                   
  217.                 try {  
  218.                     mapper.writeValue(generator, value);  
  219.                 } finally {  
  220.                     generator.close();  
  221.                 }  
  222.             }  
  223.         }  
  224. }  

接口代码:

 

view plaincopy to clipboardprint?

  1. package com.bzlccn.oa.common.json.jackson;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.io.OutputStream;  
  5. import java.io.Reader;  
  6. import java.io.Writer;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9.   
  10. public  interface JsonInterface {  
  11.     String readString(String value) throws IOException;  
  12.     int readInt(String value);  
  13.     Integer readInteger(String value);  
  14.     Object readBean(String value);  
  15.     List<String> readStringList(String value) throws IOException;  
  16.     int[] readIntArray(String value);  
  17.     List<Integer> readIntegerList(String value);  
  18.       
  19.     List<Short> readShortList(String value);  
  20.       
  21.     List<Object> readBeanList(String value);  
  22.       
  23.     List<Map<String,Object>> readBeanByMap(String value);  
  24.     List<Object> readBeanList(byte[] value);  
  25.     List<Object> readBeanList(Reader value);  
  26.     List<Object> readBeanList(InputStream value);  
  27.     String writeString(String value) throws IOException;  
  28.     String writeInt(int value);  
  29.     String writeInteger(Integer value);  
  30.     String writeBean(Object value);  
  31.       
  32.     String writeBean(Object value,String filter);  
  33.     String writeStringList(List<String> value) throws IOException;  
  34.     String writeIntArray(int[] value);  
  35.     String writeIntegerList(List<Integer> value);  
  36.     String writeBeanList(List<?> value);  
  37.       
  38.     String writeBeanList(List<?> value,String filter);  
  39.     void writeBeanList(List<?> value, Writer writer);  
  40.     void writeBeanList(List<?> value, OutputStream writer);  
  41.     byte[] writeBeanListToByteArray(List<?> value);  
  42. }  

最终供调用的工具代码:

view plaincopy to clipboardprint?

  1. package com.bzlccn.oa.common.json;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.io.OutputStream;  
  5. import java.io.Reader;  
  6. import java.io.Writer;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9. import org.codehaus.jackson.map.ObjectMapper;  
  10. import org.codehaus.jackson.map.SerializationConfig.Feature;  
  11. import com.bzlccn.oa.common.json.jackson.JacksonProxy;  
  12. import com.bzlccn.oa.common.json.jackson.JsonInterface;  
  13.   
  14. /** 
  15.  * json处理工具集 
  16.  *  
  17.  * @author rain 
  18.  *  
  19.  */  
  20. public class JsonUtil{  
  21.     private static JsonInterface json;  
  22.     static{  
  23.         ObjectMapper mapper = new ObjectMapper();  
  24.         mapper.configure(Feature.INDENT_OUTPUT, true);  
  25.         json = JacksonProxy.newProxyInstance(mapper, JsonInterface.class);  
  26.     }  
  27.     public static JsonInterface getTool(){  
  28.         return json;  
  29.     }  
  30.       
  31. //**********************************************************************************  
  32.        static class ViewBean  
  33.        {  
  34.            public String name;  
  35.            public String value;  
  36.            public String secret;  
  37.            public  ViewBean  sibling;  
  38.            public  ViewBeanChild   child;  
  39.            public ViewBean(String name, String value, String secret) {  
  40.                this.name = name;  
  41.                this.value = value;  
  42.                this.secret = secret;  
  43.              child = new ViewBeanChild();  
  44.            }  
  45.        }  
  46.        static class ViewBeanChild  
  47.        {  
  48.            public  long  id = 123;  
  49.            public String name = "child";  
  50.            public String address = "123 Street";  
  51.        }  
  52.     public static void main(String[] args) throws Exception {  
  53.         ViewBean bean = new ViewBean("mr bean"null"secret!");  
  54.         bean.sibling = new ViewBean("sibling""lala""boooo");  
  55.         String  filter = "{\"name\":0,\"value\":0,\"sibling\":{\"name\":0}, \"child\":{\"id\":0,\"address\":0}}";  
  56.           
  57.         System.out.println(json.writeBean(bean,filter));  
  58.     }  
  59. }  

这样实现的一个好处就是方法可以自定义,向把json串转换成什么类型的bean只要在JsonInterface接口中申明就可以了。这个是基于

jackson1.5版本实现的。

你可能感兴趣的:(thread,json,bean,F#,JSF)