近期使用这个json生成sign签名,因为顺序问题导致一直验证不成功,说下解决方法。
使用的为alibaba的fastjson,版本为1.1.29
类定义
public class DetailBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<detail> detail;
private int years;
public class detail {
private String name;
private String serviceKey;
private BigDecimal price = new BigDecimal("0");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getServiceKey() {
return serviceKey;
}
public void setServiceKey(String serviceKey) {
this.serviceKey = serviceKey;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
public List<detail> getDetail() {
return detail;
}
public void setDetail(List<detail> detail) {
this.detail = detail;
}
public int getYears() {
return years;
}
public void setYears(int years) {
this.years = years;
}
@Override
public String toString() {
return "DetailBean [detail=" + detail + ", years=" + years + "]";
}
}
然后存放进JSON里面
JSONObject contentMap = new JSONObject();
contentMap.put("detail", detail.getDetail());
contentMap.put("years", detail.getYears());
DetailBean实体类的属性为
{
"detail":[{
"name": "abc",
"serviceKey": "servicepackage_base",
"price": 2400
}, {
"name": "def",
"serviceKey": "addedvalue_repurchase",
"price": 600
}],
"years": 2
}
然后输出JSON为
{"detail":[{"name":"abc","price":2400,"serviceKey":"servicepackage_base"},{"name":"def","price":600,"serviceKey":"addedvalue_repurchase"}],"years":2}
但是我想要的是按照输入的顺序显示
{"detail":[{"name":"abc","serviceKey":"servicepackage_base","price":2400},{"name":"def","serviceKey":"addedvalue_repurchase","price":600}],"years":2}
JSONObject的排序为字母排序,就是按照abcd…排序,按照固定排序的话,有三种方法:
第一种更改版本,升级为1.1.42以上的版本,这个版本支持使用JSONField,改变指定顺序
public class detail {
@JSONField(ordinal = 1)
private String name;
@JSONField(ordinal = 2)
private String serviceKey;
@JSONField(ordinal = 3)
private BigDecimal price = new BigDecimal("0");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getServiceKey() {
return serviceKey;
}
public void setServiceKey(String serviceKey) {
this.serviceKey = serviceKey;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
第二种: 使用低版本的情况下,使用JSONType也可以达到要求
@JSONType(orders = { "name", "serviceKey", "price" })
public class detail {
private String name;
private String serviceKey;
private BigDecimal price = new BigDecimal("0");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getServiceKey() {
return serviceKey;
}
public void setServiceKey(String serviceKey) {
this.serviceKey = serviceKey;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
第三种更改属性名字,使用低版本,但同时,使用这种方法,就只能使用更改的名字获取值。
public class detail {
@JSONField(name="a")
private String name;
@JSONField(name="b")
private String serviceKey;
@JSONField(name="c")
private BigDecimal price = new BigDecimal("0");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getServiceKey() {
return serviceKey;
}
public void setServiceKey(String serviceKey) {
this.serviceKey = serviceKey;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}