解决json字符串序列化后的顺序问题

1、应用场景:

如果项目中用到json字符串转为jsonObject的需求,并且,需要保证字符串的顺序转之前和转成jsonObject之后输出的结果完全一致。可能有点绕口,下面举一个应用场景的例子。

在做项目的过程中,需要写Junit单元测试,有一个方法如下:

 @Test
 @SuppressWarnings("unchecked")
 public void facilitySoftwareQueryByPageExample() throws Exception {
  facilitySoftwareRepository.deleteAll();
  FacilitySoftwareConfig facilitySoftware = createFacilitySoftware();
  facilitySoftwareRepository.save(facilitySoftware);
  String userId = "1";
  int pageNumber = 1;
  int pageSize = 5;
  String facilities = objectMapper.writeValueAsString(facilitySoftware);
  LinkedHashMap<String, Object> jsonMap = JSON.parseObject(facilities,LinkedHashMap.class, Feature.OrderedField);
  JSONArray jsonArray = new JSONArray();
  JSONObject jsonObject = new JSONObject(true);
  jsonObject.putAll(jsonMap);
  jsonArray.add(jsonObject);
  this.mockMvc
   .perform(get("/v1/facilitysoftware/userid/" + userId + "/page/" + pageNumber
     + "/pagesize/" + pageSize + ""))
   .andExpect(status().isOk()).andExpect(jsonPath("content",is(jsonArray)))
   .andExpect(jsonPath("totalPages", is(1)))
   .andExpect(jsonPath("totalElements", is(1)))
   .andExpect(jsonPath("last", is(true)))
   .andExpect(jsonPath("number", is(0)))
   .andExpect(jsonPath("size", is(5)))
   .andExpect(jsonPath("numberOfElements", is(1)))
   .andExpect(jsonPath("first", is(true)))
   .andDo(document("facilitySoftware-query-example"));
 }

例子就在这里:

.andExpect(status().isOk()).andExpect(jsonPath("content",is(jsonArray)))

大家应该都能读懂,这行代码意思就是你用Api获取到的json字符串和你定义的字符串是否一致,一致则该条件测试通过。

这里的比较不仅仅要求所有的key和value都相同,而且需要保证两个json串的顺序完全相同,才可以完成该条件的测试。

查了资料解决途径过程如下:首先我们使用的是阿里的fastJson,需要引入fastJson的依赖,具体百度maven仓库,注意这里尽量使用稳定版本的较高版本。如 1.2.*

在解决问题过程中,遇到如下解决方案

1、在初始化json对象的时候加上参数true,这里不完全符合我们的需求,加上true之后,是让json串按照key的hashcode排序。

可以自定义升序或者降序,因为解决不了该场景的问题。这里不赘述,自行百度。

JSONObject jsonObject = new JSONObject(true);

2、解决问题,代码如下,第一个参数是需要转换的json字符串。

LinkedHashMap<String, Object> jsonMap = JSON.parseObject(facilities,LinkedHashMap.class, Feature.OrderedField);
JSONArray jsonArray = new JSONArray();
  JSONObject jsonObject = new JSONObject(true);
  jsonObject.putAll(jsonMap);
  jsonArray.add(jsonObject);

补充:JSON 序列化key排序问题和序列化大小写问题

1. JSON 序列化key排序问题(fastjson)

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
//创建学生对象
Student student = new Student();
student.setName("小明");
student.setSex(1);
student.setAge(18);
//序列化 json key按字典排序
System.out.println(JSONObject.toJSONString(student ,SerializerFeature.MapSortField));
//过滤不要的key age
 System.out.println(JSONObject.toJSONString(student , new PropertyFilter() {
   public boolean apply(Object source, String name, Object value) {
    if ("age".equals(name)) {
     return false;
    }
    return true;
   }
  }, SerializerFeature.MapSortField));

2. JSON 序列化大小写问题(fastjson)

//学生类
import com.alibaba.fastjson.annotation.JSONField;
public class Student {
 private String name;
 private Integer sex;
 private Integer age;
 @JSONField(name = "Name") //用于序列化成json,key Name
 public String getName() {
  return name;
 }
 @JSONField(name = "Name") 用于json(Name)反序列化成学生对象
 public void setName(String name) {
  this.name = name;
 }
 public Integer getSex() {
  return sex;
 }
 public void setSex(Integer sex) {
  this.sex = sex;
 }
 public Integer getAge() {
  return age;
 }
 public void setAge(Integer age) {
  this.age = age;
 }
}

3. jackson 序列化大小写问题

@ResponseBody和@RequestBody中的序列化和反序列化就是用的jackson

 //学生类
import com.fasterxml.jackson.annotation.JsonProperty;
public class Student {
 @JsonProperty("Name")
 private String name;
 private Integer sex;
 private Integer age;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public Integer getSex() {
  return sex;
 }
 public void setSex(Integer sex) {
  this.sex = sex;
 }
 public Integer getAge() {
  return age;
 }
 public void setAge(Integer age) {
  this.age = age;
 }
}
//自己测试下
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
@Test
public void test() throws Exception{
 Student student = new Student();
 student.setName("小明");
 ObjectMapper MAPPER = new ObjectMapper();
 //jackson序列化
 String json = MAPPER.writeValueAsString(student);
 System.out.println(json);
 //jackson反序列化
 Student student2 = MAPPER.readValue(json, Student.class);
 System.out.println(student2.getName());
}

4. jackson 序列化null值的问题

fastjson序列化默认会去掉值为null的键值对

//在学生类上加上这个
方式一:(已经过时的方法)
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
方式二:
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)

5. jackson 反序列化忽略多余的json字段

import com.fasterxml.jackson.databind.DeserializationFeature;
MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

6. jackson 序列化忽略多余的json字段

方式一:
@JsonIgnoreProperties:该注解将在类曾级别上使用以忽略json属性。在下面的栗子中,我们将从albums的dataset中忽略“tag”属性;
@JsonIgnoreProperties({ "tags" })
方式二:
@JsonIgnore:该注释将在属性级别上使用以忽略特定属性;get方法上
@JsonIgnore

7. jackson 常用注解

@JsonAlias("Name")  反序列化时生效
private String name;
@JsonProperty("Name") 反序列化和序列化都时生效
private String name;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • C#实现JSON字符串序列化与反序列化的方法

    C#将对象序列化成JSON字符串 public string GetJsonString() { List<Product> products = new List<Product>(){ new Product(){Name="苹果",Price=5}, new Product(){Name="橘子",Price=5}, new Product(){Name="干柿子",Price=00} }; ProductList

  • JavaScript实现的反序列化json字符串操作示例

    本文实例讲述了JavaScript实现的反序列化json字符串操作.分享给大家供大家参考,具体如下: JavaScript中如何反序列化json字符串呢? 有如下两种方法: (1) 使用万能的eval var jsonText = '{"name":"acwong","age":23,"address":{"province":"GuangDong","city":&

  • JSON PHP中,Json字符串反序列化成对象/数组的方法

    如下所示: <?php //php反编码解析json信息 //json_decode(json字符串); $city = array('shandong'=>'jinan','henan'=>'zhengzhou','hebei'=>'shijiazhuang'); $jn_city = json_encode($city); //反编码json $fan_city = json_decode($jn_city,false);//第二个参数false则返回object类型,fals

  • Python 将json序列化后的字符串转换成字典(推荐)

    一般而言下面的就可以完成需求了. def convertToDic(data): jsonDic=json.loads(data) return dict(jsonDic) 但实际应用中可能会出现一些问题,因此有时候也可以增加一些异常处理: def convertToDic(data): try: jsonDic=json.loads(data) except json.decoder.JSONDecodeError: jsonDic={} try: dic=dict(jsonDic) exce

  • 解决Golang json序列化字符串时多了\的情况

    我们在对外提供API接口,返回响应的时候,很多时候需要使用如下的数据结构 type Response struct { Code int `json:"code"` Msg string `json:"msg"` Data interface{} `json:"data"` } 该API接口返回一个状体码,状态信息,以及具体的值.但是具体的值可能根据各个接口的不同而不同. 在实际的开发过程中我们可能会得到一个实际的数据值,并将这个值赋值给data

  • 解决json字符串序列化后的顺序问题

    1.应用场景: 如果项目中用到json字符串转为jsonObject的需求,并且,需要保证字符串的顺序转之前和转成jsonObject之后输出的结果完全一致.可能有点绕口,下面举一个应用场景的例子. 在做项目的过程中,需要写Junit单元测试,有一个方法如下: @Test @SuppressWarnings("unchecked") public void facilitySoftwareQueryByPageExample() throws Exception { facilityS

  • 解决json日期格式问题的3种方法

    开发中有时候需要从服务器端返回json格式的数据,在后台代码中如果有DateTime类型的数据使用系统自带的工具类序列化后将得到一个很长的数字表示日期数据,如下所示: 复制代码 代码如下: //设置服务器响应的结果为纯文本格式            context.Response.ContentType = "text/plain";           //学生对象集合            List<Student> students = new List<St

  • MySQL存储Json字符串遇到的问题与解决方法

    目录 环境依赖 问题描述 原因分析 解决方案 方案一 转义符替换 方案二 修改sql书写方式 方案三 DataFrame.to_sql() 补充:不同情况 总结 环境依赖 Python 2.7MySQL 5.7MySQL-python 1.2.5Pandas 0.18.1 在日常的数据处理中,免不了需要将一些序列化的结果存入到MySQL中.这里以插入JSON数据为例,讨论这种问题发生的原因和解决办法.现在的MySQL已经支持JSON数据格式了,在这里不做讨论:主要讨论如何保证存入到MySQL字段

  • Json_decode 解析json字符串为NULL的解决方法(必看)

    从APP端或从其他页面post,get过来的数据一般因为数组形式.因为数组形式不易传输,所以一般都会转json后再发送.本以为发送方json_encode(),接收方json_decode(),就解决的问题,结果发现,json_decode()后是NULL. 一般会反应是少了一个参数"true",但是回去看就是 json_decode($data,true); 那怎么还会是NULL呢?难道是编码,不会啊,接收后直接打印是一个完整json字符串的形式,在网上json解析网站,也是可以正常

  • jQuery序列化后的表单值转换成Json

    小朋友有一个表单,他想以Json的方式获取到表单的内容.小朋友尝试了以下方式. 通过$("#form").serialize()可以获取到序列化的表单值字符串. 例如: a=1&b=2&c=3&d=4&e=5 通过$("#form").serializeArray()输出以数组形式序列化表单值. [ {name: 'firstname', value: 'Hello'}, {name: 'lastname', value: 'Worl

  • PHP处理JSON字符串key缺少双引号的解决方法

    本文实例讲述了PHP处理JSON字符串key缺少引号的解决方法,分享给大家供大家参考之用.具体方法如下: 通常来说,JSON字符串是key:value形式的字符串,正常key是由双引号括起来的. 例如: <?php $data = array('name'=>'fdipzone'); echo json_encode($data); // {"name":"fdipzone"} print_r(json_decode(json_encode($data)

  • C#解析json字符串总是多出双引号的原因分析及解决办法

    json好久没用了,今天在用到json的时候,发现对字符串做解析的时候总是多出双引号. 代码如下: string jsonText = "{'name':'test','phone':'18888888888'}"; JObject jo = (JObject)JsonConvert.DeserializeObject(jsonText); string zone = jo["name"].ToString(); string zone_en = jo["

  • 快速解决owin返回json字符串多带了双引号"多了重string转义字符串

    解决方法: [HttpGet] public HttpResponseMessage getsystemtime() { cltime time = new cltime(); time.datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); string relsut = JsonConvert.SerializeObject(time); var resp = new HttpResponseMessage { Conten

随机推荐