前言:
  JAVA总是把实体对象(数据库/Nosql等)转换为POJO对象再处理, 虽然有各类框架予以强力支持. 但实体对象和POJO, 由于"饮食习惯", "民族特色", "地域区别"等等差异, 需要有些定制需求, 使得能够完美的映射. 这个性化定制需求, 包括名称/时间格式/字段过滤等等约定.
  springmvc的学习笔记系列:
  • idea创建springmvc项目
  • 面向移动端支持REST API
  本文讲讲述如何把pojo对象转化为约定好的json数据格式. 权当笔记.

疑问篇:
  springmvc在使用注解@ResponseBody返回一个POJO对象时, 其内部会借助Jackson来完成POJO转化为JSON的工作.
  比如对于如下的POJO类:

public class Message {

  private String userId; // 用户id

  private String message; // 消息实体

  private Date timestamp; // 时间信息, yyyy-MM-dd HH:mm:ss

  private String extra; // 额外附带信息

}

  其最终讲转换为如下的json格式:
  
  如果开发者需要如下需求:
  1). json实体的key命名规则, 全小写化, 不同单词以"_"字符连接.
  2). 返回时间字段, 需满足"yyyy-MM-dd HH:mm:ss"格式
  3). 省略掉extra字段
  由此可见我们的最终目标是:

{"user_id":"1001","message":"message","timestamp":"2015-08-31 12:16:30"}

解决篇:
  • 重命名
  jackson对重命名的处理, 引入注解JsonProperty来实现. 其对单个属性配置有效.

@JsonProperty(value="user_id")
private String userId; // 用户id

  注: value属性设置为用户想要的命名即可.
  当然还有另一种方式注解方式, 是JsonNaming, 其修饰于POJO类上. 用于对所有属性, 进行统一的命名转换.

@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
public class Message {
  ...
}

  注: PropertyNamingStrategy就非常漂亮地把所有的类属性名称都转换为小写, 同时单词(驼峰命令法)之间使用'_'字符来分割.
  自定义的Strategy类, 需要实现如下抽象类:

public abstract class PropertyNamingStrategy implements Serializable {
  public abstract static class PropertyNamingStrategyBase extends PropertyNamingStrategy {
    public abstract String translate(String var1);
  }
}

  • 字段可见性
  过滤某些字段属性, jackson引入了注解JsonIgnore. 其对单个属性生效.

@JsonIgnore
private String extra; // 额外附带信息

  还有另外一种方式, 是采用JsonIgnoreProperties, 其修饰POJO类, 指定一组需要忽略的字段.

// *) 字典{}内是property name列表
@JsonIgnoreProperties({"extra", "extra1", "extra2"})
public class Message {
  ...
}

  • 自定义序列化/反序列化
  jackson采用@JsonSerialize@JsonDeserialize来实现自定义序列化/反序列化的实现. 如之前的时间字段作为例子.
  定义时间序列化的实现类.

public class Message {

  @JsonSerialize(using=DemoDateSerializer.class)
  @JsonDeserialize(using=DemoDateDeserializer.class)
  private Date timestamp; // 时间信息, yyyy-MM-dd HH:mm:ss } // *) JSON的序列化类
class DemoDateSerializer extends JsonSerializer<Date> {
  @Override
  public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    jgen.writeString(dateFormat.format(value));
  }
} // *) JSON的反序列化类
class DemoDateDeserializer extends JsonDeserializer<Date> {
  @Override
  public Date deserialize(JsonParser jp, DeserializationContext dctx) throws IOException, JsonProcessingException {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    try {
      return dateFormat.parse(jp.getValueAsString());
    } catch (ParseException e) {
      e.printStackTrace();
    } finally {
    }
    return null;
  }
}

  除了常规的时间格式转换, 还能正则提取等功能. 序列化和反序列化的自定义, 使得Jackson更加的强大. 犹如hive中的UDF函数.

实验效果:
  最终的定义的类修改如下:

public class Message {

  @JsonProperty(value="user_id")
  private String userId; // 用户id   private String message; // 消息实体   @JsonSerialize(using=DemoDateSerializer.class)
  @JsonDeserialize(using=DemoDateDeserializer.class)
  private Date timestamp; // 时间信息, yyyy-MM-dd HH:mm:ss   @JsonIgnore
  private String extra; // 额外附带信息 }

  最终的效果如图所示:
  
  与最初期望的效果保持一致, 值得小小庆祝一下.

总结:
  jackson还有很多高阶的用法, 比如破除循环引用的处理机制, 多类别的处理等等. 这边暂时忽略, 本文参考了博文"jackson annotations注解详解" , 深表敬意和感谢.

写在最后:
  
如果你觉得这篇文章对你有帮助, 请小小打赏下. 其实我想试试, 看看写博客能否给自己带来一点小小的收益. 无论多少, 都是对楼主一种由衷的肯定.

  

公众号&游戏站点:
  个人微信公众号: 木目的H5游戏世界
  

spring学习笔记---Jackson的使用和定制的更多相关文章

  1. 【Spring学习笔记-MVC-3】SpringMVC返回Json数据-方式1

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

  2. 1.《Spring学习笔记-MVC》系列文章,讲解返回json数据的文章共有3篇,分别为:

    转自:https://www.cnblogs.com/ssslinppp/p/4528892.html [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://w ...

  3. spring学习笔记(七)HttpMessageConverter

    spring学习笔记(七)HttpMessageConverter 1. HttpMessageConverter的加载 2. 从StringMessageConverter探究消息转换器的原理 1. ...

  4. 【Spring学习笔记-MVC-3.1】SpringMVC返回Json数据-方式1-扩展

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

  5. spring学习笔记(一) Spring概述

    博主Spring学习笔记整理大部分内容来自Spring实战(第四版)这本书.  强烈建议新手购入或者需要电子书的留言. 在学习Spring之前,我们要了解这么几个问题:什么是Spring?Spring ...

  6. Java框架spring 学习笔记(十八):事务管理(xml配置文件管理)

    在Java框架spring 学习笔记(十八):事务操作中,有一个问题: package cn.service; import cn.dao.OrderDao; public class OrderSe ...

  7. Spring学习笔记2——表单数据验证、文件上传

    在上一章节Spring学习笔记1——IOC: 尽量使用注解以及java代码中,已经搭建了项目的整体框架,介绍了IOC以及mybatis.第二节主要介绍SpringMVC中的表单数据验证以及文件上传. ...

  8. 不错的Spring学习笔记(转)

    Spring学习笔记(1)----简单的实例 ---------------------------------   首先需要准备Spring包,可从官方网站上下载.   下载解压后,必须的两个包是s ...

  9. 【Spring学习笔记-MVC-15.1】Spring MVC之异常处理=404界面

    作者:ssslinppp       异常处理请参考前篇博客:<[Spring学习笔记-MVC-15]Spring MVC之异常处理>http://www.cnblogs.com/sssl ...

随机推荐

  1. PHP后台

    一.ajax提交表单 先引入ajax.js function ajax(url, fnSucc, fnFaild) { //1.创建Ajax对象 var oAjax=null; if(window.X ...

  2. js基础之BOM

    一.window.open 栗子:阿里西西运行代码功能 var oBtn = document.getElementById('btn1'); var oTxt = document.getEleme ...

  3. HTTPS是如何保证连接安全,你知道吗?

    HTTPS协议的工作原理是什么?”这是我在数天前工作项目中需要解决的问题. 作为一名Web开发者,我当然知道 HTTPS 协议是保障用户敏感数据的好办法,但并不知道这种协议的内在工作机制. 它怎么保护 ...

  4. pthread_create如何传递两个参数以上的参数

    涉及多参数传递给线程的,都需要使用结构体将参数封装后,将结构体指针传给线程 定义一个结构体 struct mypara { var para1;//参数1 var para2;//参数2 } 将这个结 ...

  5. 文件浏览器及数码相框 -2.3.2-freetype_arm-2

    显示多行文字 两行文字左边对齐 简单使用两个循环显示两行字体 根据上一行字体的宽度来进行下一行左边的计算 #include <sys/mman.h> #include <sys/ty ...

  6. format 字符串

    http://www.cnblogs.com/mumble/archive/2011/05/25/2056462.html ShowMessage( Format('this is %.0f',[ t ...

  7. K2 BPM+Microsoft Dynamics CRM,妥妥的~

    啊~~~~七夕 ▼ 你比巴西少一xi 你比山西多四xi 对有情人来说今天就是情人节,对单身汪来说,今天就是个星期四. but,软件也是要秀恩爱的! ♥ 晒晒我家亲爱的CRM,它的全名叫Microsof ...

  8. Android 微信分享图文资料

    上个项目做Android的微信分享,需要分享的内容有图片有文字,看了微信分享的SDK,貌似没有这个API,在网上搜了好久,总算找到解决方法了,直接上代码: public void sendReq(Co ...

  9. c#读取文本文档实践3-写入到文本本文档

    首先通过File.ReadAllLines()方法读入文本文档中内容并返回字符串数组contents,这样每行数据就成为了这个字符串数组contents的一个元素,再利用split()方法将每一个元素 ...

  10. 对于C#中的一些点滴你真的理解了吗?

    废话不多说看题目,看看我们自己真的理解了吗? 1.如下代码输出的结果是什么? public class A{ public virtual void Func(int  number=10) { Co ...