`
阿尔萨斯
  • 浏览: 4398345 次
社区版块
存档分类
最新评论

Jackson应用二 Full Data Binding

 
阅读更多

Data Binding第二种应用是Full Data Binding.也就是可以支持自定义的Java类到JSON对象的互相转换。

下面的代码演示了简单的使用方法:

类Response的定义:

import lombok.Getter;
import lombok.Setter;

/**
 *
 * @author chenshu
 */
public class Response {
    
    @Getter @Setter
    private String status;
    
    @Getter @Setter
    private String message;
}

调用代码:

public class App {
    public static void main( String[] args ) throws IOException {
        ObjectMapper mapper = new ObjectMapper(); // create once, reuse
        String jsonSource = "{\"message\":\"Login succeeded!\",\"status\":null}";
        Response response = mapper.readValue(jsonSource, Response.class);
        
        String result = mapper.writeValueAsString(response);
    }
}


先通过命令mvn dependency:sources获取源代码。然后就可以调试进入代码观察。

readValue方法内部代码如下:

    @SuppressWarnings("unchecked")
    public <T> T readValue(String content, Class<T> valueType)
        throws IOException, JsonParseException, JsonMappingException
    {
     // !!! TODO
//    	_setupClassLoaderForDeserialization(valueType);
        return (T) _readMapAndClose(_jsonFactory.createJsonParser(content), _typeFactory.constructType(valueType));
    } 
_typeFactory.constructType(valueType)使用参数Response.class创建一个SimpleType对象(JavaType的子类),创建时有一个LinkedHashMap对象做的缓存,如果已经创建过,则不再重复创建,取出来直接使用,因此还用到了多线程锁。参考TypeFactory.java里面的代码:

    /**
     * @param context Mapping of formal parameter declarations (for generic
     *   types) into actual types
     */
    protected JavaType _fromClass(Class<?> clz, TypeBindings context)
    {
        // Very first thing: small set of core types we know well:
        if (clz == String.class) return CORE_TYPE_STRING;
        if (clz == Boolean.TYPE) return CORE_TYPE_BOOL;
        if (clz == Integer.TYPE) return CORE_TYPE_INT;
        if (clz == Long.TYPE) return CORE_TYPE_LONG;
        
        // Barring that, we may have recently constructed an instance:
        ClassKey key = new ClassKey(clz);
        JavaType result;
        
        synchronized (_typeCache) {
            result = _typeCache.get(key);
        }
        if (result != null) {
            return result;
        }

        // If context was needed, weed do:
        /*
        if (context == null) {
            context = new TypeBindings(this, cls);
        }
        */
        
        // First: do we have an array type?
        if (clz.isArray()) {
            result = ArrayType.construct(_constructType(clz.getComponentType(), null), null, null);
        /* Also: although enums can also be fully resolved, there's little
         * point in doing so (T extends Enum<T>) etc.
         */
        } else if (clz.isEnum()) {
            result = new SimpleType(clz);
        /* Maps and Collections aren't quite as hot; problem is, due
         * to type erasure we often do not know typing and can only assume
         * base Object.
         */
        } else if (Map.class.isAssignableFrom(clz)) {
            result = _mapType(clz);
        } else if (Collection.class.isAssignableFrom(clz)) {
            result =  _collectionType(clz);
        } else {
            result = new SimpleType(clz);
        }
        
        synchronized (_typeCache) {
            _typeCache.put(key, result);
        }
        
        return result;
    }

我没有进一步跟踪,但是推测后面将利用Response.class.getMethods()获得并调用Response的setStatus和setMessage方法。

再看看调用代码:

return (T) _readMapAndClose(_jsonFactory.createJsonParser(content), _typeFactory.constructType(valueType));

_jsonFactory.createJsonParser(content)创建了Jackson Streaming库里面的JsonParser对象。

_jsonFactory.createJsonParser(content)
下面代码来自于Streaming库的JsonFactory.java

    /**
     * Method for constructing parser for parsing
     * contents of given String.
     */
    public JsonParser createJsonParser(String content)
        throws IOException, JsonParseException
    {
	Reader r = new StringReader(content);
        // true -> we own the Reader (and must close); not a big deal
        IOContext ctxt = _createContext(r, true);
        // [JACKSON-512]: allow wrapping with InputDecorator
        if (_inputDecorator != null) {
            r = _inputDecorator.decorate(ctxt, r);
        }
	return _createJsonParser(r, ctxt);
    }
这里只是大概了解一下用到了StringReader读取JSON字符串。因为属于Streaming库的内容,先放一放。

真正从JSON字符串读取对象需要用到叫做反序列化对象的东西,这个东西也是只创建一次,然后缓存。

ObjectMapper.java类里面的代码如下:

    /**
     * Method called to locate deserializer for the passed root-level value.
     */
    protected JsonDeserializer<Object> _findRootDeserializer(DeserializationContext ctxt,
            JavaType valueType)
        throws JsonMappingException
    {
        // First: have we already seen it?
        JsonDeserializer<Object> deser = _rootDeserializers.get(valueType);
        if (deser != null) {
            return deser;
        }
        // Nope: need to ask provider to resolve it
        deser = ctxt.findRootValueDeserializer(valueType);
        if (deser == null) { // can this happen?
            throw new JsonMappingException("Can not find a deserializer for type "+valueType);
        }
        _rootDeserializers.put(valueType, deser);
        return deser;
    }
_rootDeserializers 变量类型是ConcurrentHashMap<JavaType, JsonDeserializer<Object>>,因此也是线程安全的。

结论:

1.每个自定义类型,都只会创建一个JavaType(其实是子类SimpleType),并缓存在LinkedHashMap变量中。该缓存变量位于ObjectMapper对象的TypeFactory变量中。

2.每个自定义类型都只有一个反序列化解析器,缓存在ConcurrentHashMap<JavaType, JsonDeserializer<Object>>变量中,该缓存变量是ObjectMapper的变量。

3.为了保证效率,要尽可能的只使用一个ObjectMapper对象。由于1和2的缓存读取和更新都是线程安全的,其他的代码也是线程安全,因此在多线程环境下使用一个ObjectMapper对象也是安全的。



分享到:
评论

相关推荐

    Android Data Binding

    Android Data Binding库是Google推出的一种强大的MVVM(Model-View-ViewModel)架构支持技术,它旨在简化Android应用中的UI逻辑,提高代码可读性和可维护性。本教程将深入探讨如何将Data Binding与RecyclerView结合...

    Data Binding with Windows Forms 2.0

    Data Binding with Windows Forms 2.0: Programming Smart Client Data Applications with .NET By Brian Noyes ............................................... Publisher: Addison Wesley ...

    Android Data Binding 代码实战 demo

    **Android Data Binding 框架详解与实战演示** 在Android应用开发中,数据绑定是一种将UI组件和数据源紧密关联的技术,它可以帮助开发者减少在Activity或Fragment中的样板代码,提高代码可读性和维护性。本实战项目...

    Android Data Binding实战-入门篇

    Android Data Binding是Google推出的一种强大的数据绑定库,它旨在简化Android应用中的UI逻辑,通过将数据绑定到XML布局文件中,使代码更加清晰、可读性更强,同时也减少了Activity或Fragment中的样板代码。...

    Data Binding with Windows Forms 2.0 Programming

    This book is all about the what and the why of binding to data sources in a Windows Forms application built using Visual Studio 2005. The book goes into great detail in explaining the rationale behind...

    AdventureWorks Data Binding sample

    《AdventureWorks 数据绑定示例详解...总之,AdventureWorks Data Binding sample是VB.NET开发者学习数据绑定技术的一个宝贵资源,它通过实际操作展示了数据绑定的各个方面,有助于提升开发者构建数据驱动应用的能力。

    WPF Data Binding with LINQ to SQL

    These tutorials describe how to map your classes to your tables manually (rather than with an automated tool like SqlMetal) so that you can have support for M:M relationships and data binding against ...

    ADF的data binding

    4. **Binding Context**:Binding Context是整个应用程序的上下文,它包含所有Binding Containers和Data Controls的信息。Binding Context提供了一个全局视图,使得在多个界面间共享数据和资源成为可能。 一个典型...

    Flex Data Binding详解

    Flex Data Binding是Adobe Flex框架中的核心特性之一,它允许开发者创建数据驱动的应用程序,通过将UI组件的属性与数据模型的属性直接关联,实现实时的数据同步。在Flex中,数据绑定确保当数据源发生变化时,相关的...

    Android Data Binding 在 library module 中遇到错误及解决办法

    在使用Android Data Binding时,有时会遇到在library module中出现错误的情况。这通常是由于Data Binding在编译过程中生成的binding类与library module的特定规则不兼容导致的。本文将深入探讨这个问题并提供解决...

    AndroidDataBindingExample, Android Data Binding 代码实战.zip

    这个压缩包"AndroidDataBindingExample, Android Data Binding 代码实战.zip"提供了一个实际的项目案例,帮助我们深入理解如何在实际开发中应用Android Data Binding。 1. **数据绑定的基本概念**: - 数据绑定...

    Android数据绑定Data Binding

    在Android开发中,数据绑定(Data Binding)是一个强大的框架,它允许开发者更加直观地将UI组件与业务数据关联起来,从而简化代码并提高可维护性。这个Demo程序旨在展示数据绑定和事件绑定的基本用法,帮助开发者...

    安卓-Data Binding+RecyclerView打造可以选择的三级列表

    在安卓应用开发中,构建可交互的用户界面是至关重要的,而Data Binding库与RecyclerView的结合使用能够有效地提高代码的可读性和维护性,同时实现复杂的列表展示,如本示例中的三级列表。本文将详细解析如何利用Data...

    jackson-jar

    3.2 Full Data Binding 用于json和Java Bean的相互转换。 下面从使用的角度上比较三种处理方式: Streaming API 执行效率最高,读写速度最快,另外两种方式都基于它实现; Tree Model 是最灵活的; Data ...

    C#应用BindingSource实现数据同步的方法

    在本篇文章中,我们将深入探讨如何使用`BindingSource`来实现数据同步,以及其在实际应用中的工作原理。 首先,`BindingSource`组件的主要功能是作为数据源和控件之间的中间层,它能够帮助我们轻松地将控件的数据...

    Data Binding and Explicit Transactions

    在IT行业中,数据绑定(Data Binding)和显式事务(Explicit Transactions)是两个非常关键的概念,尤其是在处理数据存储和更新时。这篇博文“Data Binding and Explicit Transactions”将深入探讨这两个主题,帮助...

    Data Binding with Windows Forms 2.0 Programming Smart Client Data Applications with .NET

    《Data Binding with Windows Forms 2.0:编程智能客户端数据应用程序与.NET》是一本深入探讨.NET框架下Windows Forms 2.0数据绑定技术的专业书籍。数据绑定是将用户界面(UI)组件与数据源连接的过程,它使得应用...

    鸿蒙应用开发view-binding插件,消除findComponentById模版代码

    这一特性是基于 Android 的 Data Binding 概念,并被华为的 HarmonyOS 移植和优化。 `HarmonyOS`,全称为 `OpenHarmony`,是一个开源的操作系统项目,旨在为多种智能设备提供统一的操作平台。`OpenHarmony` 提供了...

    Android Data Binding Library 官方文档(译)

    Android Data Binding Library 官方文档中文翻译,出自https://blog.csdn.net/jjwwmlp456/article/details/54915981的博客,被我制作成离线版pdf以供保存, Google官方文档地址:...

Global site tag (gtag.js) - Google Analytics