需要输入的实体示例如下:
@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 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(); } @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改变输出字段的顺序



