好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

1、应用场景:

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

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

@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" ));

}

例子就在这里:

?

1

.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排序。

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

?

1

JSONObject jsonObject = new JSONObject( true );

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

?

1

LinkedHashMap<String, Object> jsonMap = JSON.parseObject(facilities,LinkedHashMap. class , Feature.OrderedField);

?

1

2

3

4

JSONArray jsonArray = new JSONArray();

   JSONObject jsonObject = new JSONObject( true );

   jsonObject.putAll(jsonMap);

   jsonArray.add(jsonObject);

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

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

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)

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

//学生类

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

//学生类

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的键值对

?

1

2

3

4

5

6

7

//在学生类上加上这个

方式一:(已经过时的方法)

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字段

?

1

2

import com.fasterxml.jackson.databind.DeserializationFeature;

MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );

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

?

1

2

3

4

5

6

方式一:

@JsonIgnoreProperties :该注解将在类曾级别上使用以忽略json属性。在下面的栗子中,我们将从albums的dataset中忽略[tag]属性;

@JsonIgnoreProperties ({ "tags" })

方式二:

@JsonIgnore :该注释将在属性级别上使用以忽略特定属性;get方法上

@JsonIgnore

7. jackson 常用注解

?

1

2

3

4

@JsonAlias ( "Name" )  反序列化时生效

private String name;

@JsonProperty ( "Name" ) 反序列化和序列化都时生效

private String name;

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

原文链接:https://blog.csdn.net/weixin_39214304/article/details/80652931

查看更多关于解决json字符串序列化后的顺序问题的详细内容...

  阅读:110次