需要输入的实体示例如下:

/*** 云打印请求参数*/
@Data
public class YiRuiPrintResParam extends YiRuiCommonResParam implements Serializable {private String deviceName;private String token;private String transNo;private Integer type;private Nc nc;private String pc;
}
/*** 公共请求参数*/
@Data
public class YiRuiCommonResParam implements Serializable {private String productKey;private Long timestamp;private String signMethod;private String sign;
}
@Data
public class Nc {private Integer channel;private String ct;private String charset;
}

如果没有指定顺序,Gson会按实体类里的字段排列顺序来序列化(与字段设值顺序无关),包括里面的类Nc的输出字段顺序也是如此。

序列化输出代码:

Gson printGson = new Gson();
String printReq = printGson.toJson(printParam);
System.out.printf("云打印 request:%s\n", printReq);

序列化输出结果:

{"deviceName": "8115210800100022","token": "E75x+wmRF3eyo1IZxnn+s2PrhtAYIhX1Kchk9eVtx1niQulJx4QgUwYoYCe7Fugv1634089348814","transNo": "20211013141142","type": 0,"nc": {"channel": 1,"ct": "12345","charset": "abcde"},"pc": "{\"ct\":[{\"cols\":[{\"cv\":\"\"}],\"tp\":\"0\"},{\"tp\":\"3\"},{\"cols\":[{\"cv\":\"商户名称:\"},{\"cv\":\"测试商户\"}],\"tp\":\"1\"},{\"cols\":[{\"cv\":\"金额RMB:\"},{\"cv\":\"0.01元\"}],\"tp\":\"1\"}],\"cn\":1}","productKey": "78d077bf960c477b","timestamp": 1634105502,"signMethod": "MD5","sign": "394009CE36A0AD145D279AF84131E35D"
}

如果想指定顺序,应该如何实现呢?本人的需求是按字段的英文名称作为升序排序,参考了网上的一些做法,都是偏向于通过继承TypeAdapter类来实现,具体做法如下:

/*** 打印适配器*/
public class YiRuiPrintAdapter extends TypeAdapter<YiRuiPrintResParam> {@Overridepublic void write(JsonWriter out, YiRuiPrintResParam param) throws IOException {
//        Class<? extends Nc> ncClazz = param.getNc().getClass();
//        Field[] ncFields = ncClazz.getDeclaredFields();out.beginObject();// 按自定义顺序输出字段信息out.name("deviceName").value(param.getDeviceName());out.name("nc");out.beginObject();out.name("channel").value(param.getNc().getChannel());out.name("charset").value(param.getNc().getCharset());out.name("ct").value(param.getNc().getCt());
//        setWrite(ncFields, out, param.getNc());out.endObject();out.name("pc").value(param.getPc());out.name("productKey").value(param.getProductKey());out.name("sign").value(param.getSign());out.name("signMethod").value(param.getSignMethod());out.name("timestamp").value(param.getTimestamp());out.name("token").value(param.getToken());out.name("transNo").value(param.getTransNo());out.name("type").value(param.getType());out.endObject();}@Overridepublic YiRuiPrintResParam read(JsonReader jsonReader) throws IOException {return null;}//    /**
//     * 递归写入属性
//     *
//     * @param fields
//     * @param out
//     * @param object
//     * @return void
//     * @author liangzhaolinC
//     * @date 2021/10/13 10:50
//     */
//    public void setWrite(Field[] fields, JsonWriter out, Object object) {
//        for (int i = 0; i < fields.length; i++) {
//            Field field = fields[i];
//            field.setAccessible(true);
//            try {
//                Object type = field.get(object);
//                if (type == null) {
//                    continue;
//                }
//                if (!(type instanceof String)) {
//                    out.name(field.getName()).beginObject();
//                    Field[] subFields = type.getClass().getDeclaredFields();
//                    setWrite(subFields, out, type);
//                    out.endObject();
//                } else {
//                    out.name(field.getName()).value(type.toString());
//                }
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//    }
}

out.beginObject(); 的意思是json里加上左括号 {

out.endObject(); 的意思是json里加上右括号 }

out.name("nc"); 的意思是json里加上key "nc"

out.value(xxx); 的意思是json里加上value "xxx"

可以看下对应里面的源码理解下。

代码中已注释的代码部分,其实是为了想自动把Nc类里的字段打印出来,但因为代码是参考网上的,尝试的时候遇到点bug,项目比较急,所以先注释掉,待以后再研究(如果有小伙伴能修复也麻烦分享下)。取而代之的是将Nc的字段序列化顺序也是通过写死来控制。所以才有第二次 out.beginObject(); 的调用,和对应的 out.endObject();

序列化代码:

Gson printGson = new GsonBuilder().registerTypeAdapter(YiRuiPrintResParam.class, new YiRuiPrintAdapter()).create();
String printReq = printGson.toJson(printParam);
System.out.printf("云打印 request:%s\n", printReq);

序列化输出结果:

{"deviceName": "8115210800100022","nc": {"channel": 1,"charset": "abcde","ct": "12345"},"pc": "{\"ct\":[{\"cols\":[{\"cv\":\"\"}],\"tp\":\"0\"},{\"tp\":\"3\"},{\"cols\":[{\"cv\":\"商户名称:\"},{\"cv\":\"测试商户\"}],\"tp\":\"1\"},{\"cols\":[{\"cv\":\"金额RMB:\"},{\"cv\":\"0.01元\"}],\"tp\":\"1\"}],\"cn\":1}","productKey": "78d077bf960c477b","sign": "F6093E0B127D6B537D8BDD376C532097","signMethod": "MD5","timestamp": 1634106351,"token": "E75x+wmRF3eyo1IZxnn+s2PrhtAYIhX1Kchk9eVtx1niQulJx4QgUwYoYCe7Fugv1634089348814","transNo": "20211013142551","type": 0
}

参考资料:

java自定义Gson生成json字符串的顺序

gson改变输出字段的顺序

Gson按指定字段顺序序列化相关推荐

  1. fastjson如何指定字段不序列化

    fastjson是一款由阿里巴巴提供的性能出色的json序列化与反序列化库,而且使用很方便,我们可以使用JSON.toJSONString(object)将一个对象序列化为json格式,但是如果我们不 ...

  2. JSON序列化后按对象中声明顺序序列化或者指定顺序序列化(Java)

    JSON序列化后按对象中声明顺序序列化或者指定顺序序列化 阿里巴巴的fastjson对json字符串进行序列化,序列化之后发现顺序发生了改变按照字母顺序系列化,导致之后业务出现问题. 解决方法1: L ...

  3. mysql添加字段指定顺序_mysql 添加字段、删除字段、调整字段顺序

    添加字段: alter table `user_movement_log` Add column GatewayId int  not null default 0 AFTER `Regionid` ...

  4. JSON排除指定字段的4种方法

    通常在 本地存储 / 微服务 / 分布式 通讯场景下,会用到对象序列化,Serializable只是一个接口类,需要具体的对象实现它.本文主要介绍序列化时(如Fastjson.Gson.Jackson ...

  5. powerdesigner 同步mysql 报错_PowerDesigner实用技巧小结 及 导出word,想字段顺序跟模型中一致,如何设置...

    powerdesigner导出word,想字段顺序跟模型中一致,如何设置 右键List of columns of the table %PARENT% ,selection,define  sort ...

  6. PostgreSQL 数据库多列复合索引的字段顺序选择原理

    标签 PostgreSQL , 多列索引 , 复合索引 , 驱动列 , 顺序 , 等值查询 , 范围扫描 , 离散值 , 连续值 , 单列索引 , bitmap index scan 背景 当需要创建 ...

  7. MySQL为表的指定字段添加数据

    只向表的部分字段添加数据,而其他字段的值为表定义时的默认值 INSERT INTO 表名(字段1,字段2,--) VALUES(值1,值2,--); 参数说明 字段1,字段2,--表示数据表中的字段名 ...

  8. Hibernate hql 查询指定字段并获取结果集

    Hibernate hql 查询指定字段并获取结果集 在hibernate中,用hql语句查询实体类,采用list方法的返回结果为一个List,该List中封装的对象分为以下三种情况: 1.查询全部字 ...

  9. powerdesigner mysql 反引号_PowerDesigner实用技巧小结 及 导出word,想字段顺序跟模型中一致,如何设置...

    powerdesigner导出word,想字段顺序跟模型中一致,如何设置 右键List of columns of the table %PARENT% ,selection,define  sort ...

最新文章

  1. DLA实现跨地域、跨实例的多AnalyticDB读写访问
  2. 程序员基本功02对象与内存控制
  3. Activiti源码之建造者模式 Builder
  4. JS URL Parser
  5. cmd命令行启动、停止IIS,打开iis net start w3svc
  6. torch--[Pytorch函数] .masked_fill_() ;关于pytorch中@和*的用处
  7. Java的%=是什么意思?%=运算的正确使用
  8. HenCoder Android 开发进阶: 自定义 View 1-2 Paint 详解
  9. kaptcha生成java验证码
  10. linux 中文ssid 显示,【两招解决网络设置 支持中文SSID】
  11. Lucene实现全文检索
  12. 技术贴 - 收藏集 - 掘金
  13. java生成自增单号(字符+日期+数字)
  14. c语言 调用 .cpp,C语言三方库的调用和编写
  15. Nature子刊:灵活的语音皮质编码可增强与任务相关的声学信息的神经处理
  16. js将当前时间格式化为年-月-日 时:分:秒
  17. unity 所有版本下载地址
  18. python小作业初版之信用卡交易
  19. 看人脸技术如何识别真假美猴王
  20. 项目管理树状组织结构思维导图怎样绘制

热门文章

  1. node joi自定义错误提示,并处理返回给客户端
  2. 天玑机器人颈椎_第三代国产骨科手术机器人“天玑”在安徽“首秀”
  3. html如何显示动画gif,显示动画GIF
  4. 中国残障人童话爱情电影剧本《奇缘奇恋》招募投资人
  5. mysql查询1999年后出生的_1999年出生的属兔人2021年几岁了
  6. Flink中的Watermark是什么原理?它有什么用?
  7. 数学不好可以学编程吗?答案很肯定!
  8. 习题35逻辑判断,if elif else 函的定义和调用,导入模块
  9. JAVA里面一加到一百等于多少_1加到100计算公式1加到23等于多少
  10. 谷歌眼镜Mirror API开发指南之Timeline