json-view, 带Jackson的编程JSON视图

分享于 

16分钟阅读

GitHub

  繁體 雙語
Programmatic JSON views with Jackson
  • 源代码名称:json-view
  • 源代码网址:http://www.github.com/monitorjbl/json-view
  • json-view源代码文档
  • json-view源代码下载
  • Git URL:
    git://www.github.com/monitorjbl/json-view.git
    Git Clone代码到本地:
    git clone http://www.github.com/monitorjbl/json-view
    Subversion代码到本地:
    $ svn co --depth empty http://www.github.com/monitorjbl/json-view
    Checked out revision 1.
    $ cd repo
    $ svn up trunk
    

    Run Status

    编程JSON视图

    在使用Jackson序列化对象时,需要以编程方式包括或者排除字段? 那么,如果你已经知道了,现在很难做到。 Jackson本质上是非常声明性的(。所有内容的注释),所以以编程方式进行。

    虽然声明式样式当然有许多好处,但是不能简单地和编程地控制你的包含/排除,这是一个主要的。 在 VRaptor 启发下,这个库提供了一种简单的方式,可以在。

    JsonView

    这个库的所有功能都可以归结为定制的Jackson序列化程序。

    用法

    只需初始化一个标准 Jackson ObjectMapper 类,如下所示:

    importcom.fasterxml.jackson.databind.ObjectMapper;importcom.fasterxml.jackson.databind.module.SimpleModule;importcom.monitorjbl.json.JsonView;importcom.monitorjbl.json.JsonViewSerializer;//initialize jacksonObjectMapper mapper =newObjectMapper().registerModule(newJsonViewModule());

    包括

    使用它,只需使用你的构建工具将这个项目添加到你的。 这里项目在 Maven 中心可用,因此,如果你使用 Maven,你可以将它的添加到你的pom.xml 中:

    <dependency>
     <groupId>com.monitorjbl</groupId>
     <artifactId>json-view</artifactId>
     <version>0.16</version>
    </dependency>

    典型用例

    这个库的潜在用例很多,但是这里有一些可以让你开始。

    排除

    最常见的用例是,当你拥有一个具有昂贵( 大) 字段的对象时。 你可能并不总是想要序列化它。 假设你有这个类:

    publicclassMyObject{
     privateLong id;
     privateString name;
     privateMySmallObject smallObj;
     privateList<MyBigObject> contains; //expensive list with many entries//getters and setters and/or builder}

    返回 MyObject 列表,可能不希望显示 contains 字段;对于每个 MyObject 实例,实例的MyObject 和实例都是 MyBigObject 实例,你会返回n*m实例。

    典型建议的Pattern 建议在字段上使用 @JsonIgnore 注释。 然而,这有效地让这个字段在你的应用程序。 如果只希望在处理单个实例而不是 List 时显示这里字段,该怎么办?

    使用 JsonView,你可以快速轻松地过滤这里字段:

    importcom.monitorjbl.json.JsonView;import staticcom.monitorjbl.json.Match.match;//get a list of the objectsList<MyObject> list = myObjectService.list();//exclude expensive fieldString json = mapper.writeValueAsString(JsonView.with(list).onClass(MyObject.class, match().exclude("contains")));

    包含

    这也是可能的。 例如假设这是你的类:

    publicclassMyObject{
     privateLong id;
     privateString name;
     privateMySmallObject smallObj;
     @JsonIgnoreprivateList<MyBigObject> contains; //expensive list with many entries//getters and setters and/or builder}

    可以编程方式包括默认情况下忽略的字段:

    importcom.monitorjbl.json.JsonView;import staticcom.monitorjbl.json.Match.match;//get a list of the objectsList<MyObject> list = myObjectService.list();//exclude expensive fieldString json = mapper.writeValueAsString(JsonView.with(list).onClass(MyObject.class, match().include("contains")));

    高级用例

    等等,还有更多...

    通配符匹配器

    如果你有一组有限的字段,你实际上想包括。

    importcom.monitorjbl.json.JsonView;import staticcom.monitorjbl.json.Match.match;//get a list of the objectsList<MyObject> list = myObjectService.list();String json = mapper.writeValueAsString(JsonView.with(list).onClass(MyObject.class, match()
    . exclude("*")
    . include("name")));

    使用trenary逻辑实现通配符。 如果指定一个没有通配符的匹配器,它将用通配符替换任何其他匹配器。

    类匹配器

    你也可以忽略类引用的类上的字段 ! 只需在点路径中引用该字段即可执行这里操作。 在下面的示例中,忽略类 MySmallObject 上的字段 id:

    importcom.monitorjbl.json.JsonView;import staticcom.monitorjbl.json.Match.match;List<MyObject> list = myObjectService.list();String json = mapper.writeValueAsString(JsonView.with(list).onClass(MyObject.class, match()
    . exclude("smallObj.id")
    . exclude("contains")));

    或者,你可以为其他类创建一个单独的匹配器:

    importcom.monitorjbl.json.JsonView;import staticcom.monitorjbl.json.Match.match;//get a list of the objectsList<MyObject> list = myObjectService.list();String json = mapper.writeValueAsString(JsonView.with(list)
    . onClass(MyObject.class, match()
    . exclude("contains"))
    . onClass(MySmallObject.class, match()
    . exclude("id"));

    自定义序列化程序

    由于json视图的工作方式,它必须假定它可以序列化任何类( 除了某些特定的特殊类型外)。 如果你想在 JsonViewSerializer 旁边使用其他定制序列化程序,则必须使用 JsonViewSerializer 实例显式地对它们进行 register。 这与正常注册工作的方式相比有点落后,但很不幸。 但是,JsonViewModule 类提供了一种简单的方法来执行这里操作:

    ObjectMapper mapper =newObjectMapper().registerModule(newJsonViewModule()
    . registerSerializer(Date.class, newMyCustomDateSerializer())
    . registerSerializer(URL.class, newMyCustomURLSerializer()));

    域转换

    如果你有一个需要以编程方式转换的领域,那么有方法可以这样做:在Jackson内部进行 它们通常是 static 转换,而且它们可以动态方式使用,它们通常是很痛苦的。 json视图可以用于动态执行与lambdas的转换:

    JsonView.with(ref)
    . onClass(TestObject.class, match()
    . exclude("*")
    . include("str1")
    . transform("str1", (TestObject t, String f) -> f.toUpperCase()))

    规则

    为了简单地包含/排除pojo中的字段,构建了 JsonView 对象。 但是,在解析指定的配置时,应注意以下规则:

    • 匹配逻辑是trenary和通配符 MATCHES 比特定匹配的"减少 true"。
    • includes()excludes() 替换为匹配的等效级别。
    • 类继承是遵守的。如果在类的父字段上 match(),则不需要对父类进行独立的match()
    • Match.match() 中较高的类特殊性替代了低,它是基于类的;使用matcher是基于声明它的类是基于类的all-or-nothing事务。 下面是一些对记住这一点非常重要的例子:
    • 如果为类的和父类提供匹配器,父类的匹配器将被使用。
    • 如果为类A 和类B 提供匹配器,并且类A 具有类型为B的字段,则将发生下列情况
    • 类A的匹配器引用类A 中的字段,则将遵循A 类匹配器
    • 如果类的匹配器引用类B 中带有路径的字段,则将遵循类匹配器的类匹配器
    • 字段( 非方法) 和 @JsonIgnoreProperties@JsonIgnore 被尊重,除非被 include() 覆盖。
    • 所有序列化都只通过字段完成。 目前没有基于方法的序列化支持。
    • spring-集成

    这个 Spring Integration 实际上是 JsonView 对象的ThreadLocal 封装器。

    包括

    使用它,只需使用你的构建工具将这个项目添加到你的。 这里项目在 Maven 中心可用,因此,如果你使用 Maven,你可以将它的添加到你的pom.xml 中:

    <dependency>
     <groupId>com.monitorjbl</groupId>
     <artifactId>spring-json-view</artifactId>
     <version>0.14</version>
    </dependency>

    配置

    警告:这个项目是为 spring 4 + 构建的,但是还不支持与 spring 3集成。 确保你使用的版本正确。 如果是,只需将它的作为bean添加到上下文中:

    Java配置

    @EnableWebMvc@ConfigurationpublicclassContextextendsWebMvcConfigurerAdapter {
     @BeanpublicJsonViewSupportFactoryBeanviews() {
     returnnewJsonViewSupportFactoryBean();
     }
    }

    XML配置

    <beanid="jsonViewSupport"class="com.monitorjbl.json.JsonViewSupportFactoryBean"/>

    用法

    使用它非常简单:

    importcom.monitorjbl.json.JsonResult;importcom.monitorjbl.json.JsonView;importcom.monitorjbl.json.Match;importcom.monitorjbl.json.model.TestObject;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.ResponseBody;importjava.util.List;@ControllerpublicclassJsonController {
     privateJsonResult json =JsonResult.instance();
     @AutowiredprivateTestObjectService service;
     @RequestMapping(method=RequestMethod.GET, value="/bean")
     @ResponseBodypublicvoidgetTestObject() {
     List<TestObject> list = service.list();
     json.use(JsonView.with(list)
    . onClass(TestObject.class, Match.match()
    . exclude("int1")
    . include("ignoredDirect")));
     }
    }

    返回值

    虽然该方法的返回值并不实际与这个库一起使用,但是像Swagger这样的文档库可能依赖于它正在。 要使生命更简单,可以简单地在 .returnValue() 上键入以抓取正在操作的对象:

    importcom.monitorjbl.json.JsonResult;importcom.monitorjbl.json.JsonView;importcom.monitorjbl.json.Match;importcom.monitorjbl.json.model.TestObject;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RequestMethod;importorg.springframework.web.bind.annotation.ResponseBody;importjava.util.List;@ControllerpublicclassJsonController {
     privateJsonResult json =JsonResult.instance();
     @AutowiredprivateTestObjectService service;
     @RequestMapping(method=RequestMethod.GET, value="/bean")
     @ResponseBodypublicList<TestObject>getTestObject() {
     List<TestObject> list = service.list();
     return json.use(JsonView.with(list)
    . onClass(TestObject.class, Match.match()
    . exclude("int1")
    . include("ignoredDirect")))
    . returnValue();
     }
    }

    默认视图

    如果你想为特定的类设置公共视图,只需在 JsonViewSupportFactoryBean 中包含一个 DefaultView 实例。

    Java配置

    @EnableWebMvc@ConfigurationpublicclassContextextendsWebMvcConfigurerAdapter {
     @BeanpublicJsonViewSupportFactoryBeanviews() {
     returnnewJsonViewSupportFactoryBean(DefaultView.create()
    . onClass(TestObject.class, Match.match()
    . exclude("int1")
    . include("ignoredDirect")));
     }
    }

    XML配置

    对于一个实际示例,请查看以下测试文件:

    <beanid="jsonViewSupport"class="com.monitorjbl.json.JsonViewSupportFactoryBean">
     <constructor-argref="defaultView"/>
    </bean><!-- Bean in which you create a factory method to generate a DefaultView instance --><beanid="defaultView"class="com.monitorjbl.json.server.DefaultViewFactory"factory-method="instance"/>
    基于源代码的

    你需要的是 Maven 8 +,3 + 和 git:

    
    # Checkout code from GitHub
    
    
    git clone https://github.com/monitorjbl/json-view.git
    
    
    cd json-view
    
    
    
    # Build and install to local Maven repo
    
    
    mvn clean install
    
    
    
    

    完成这里操作后,你可以在POM中引用库的最新版本,如下所示:

    
    <dependency>
    
    
     <groupId>com.monitorjbl</groupId>
    
    
     <artifactId>json-view</artifactId>
    
    
     <version>0.17-SNAPSHOT</version>
    
    
    </dependency>
    
    
    
    

    VIEW  查看  JACK  Jackson  json-view