栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Gson按指定字段顺序序列化

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Gson按指定字段顺序序列化

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

@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:%sn", 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 {

    @Override
    public void write(JsonWriter out, YiRuiPrintResParam param) throws IOException {
//        Class 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();
    }

    @Override
    public YiRuiPrintResParam read(JsonReader jsonReader) throws IOException {
        return null;
    }

//    
//    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:%sn", 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改变输出字段的顺序

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/322148.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号