gson ajax 数字精度丢失问题的解决方法

时间:2022-05-05 04:13:01

ajax传输的json,gson会发生丢失,long > 15的时候会丢失0

解决方案:直接把属性为long的属性自动加上双引号成为js的字符串,这样就不会发生丢失了,ajax自动识别为字符串。

用法:

ajaxResult("",0,new Object()); //随便一个对象就可以,List 之类的

?
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
   * 以Ajax方式输出常规操作结果
   *
   * @param status
   *      返回状态,200表示成功, 500表示错误
   * @param message
   *      操作结果描述
   * @param tag
   *      附加数据
   * @return
   */
  protected ActionResult ajaxResult(int status, final String message, Object tag) {
    JsonObject json = new JsonObject();
    json.addProperty("status", status);
    json.addProperty("message", message);
 
    String strJson = json.toString();
 
    if (tag != null) {
      StringBuffer sb = new StringBuffer();
      sb.append(strJson.substring(0, strJson.length() - 1));
      sb.append(",\"tag\":");
      sb.append(GsonUtils.toJsonWithGson(tag));
      sb.append("}");
      strJson = sb.toString();
    }
 
    return writeJson(strJson);
  }
 
/**
   * 向客户端输出文本信息
   *
   * @param message
   * @return
   */
  protected ActionResult write(final String message) {
    return new ActionResult() {
      @Override
      public void render(BeatContext arg0) throws Exception {
        beat.getResponse().setCharacterEncoding("UTF-8");
        beat.getResponse().setContentType("text/json;charset=UTF-8");
        PrintWriter out = beat.getResponse().getWriter();
        out.print(message);
        out.close();
      }
 
    };
  }
 
  /**
   * 向客户端输出文本信息
   *
   * @param message
   * @return
   */
  protected ActionResult writeText(final String message) {
    return new ActionResult() {
      @Override
      public void render(BeatContext arg0) throws Exception {
        beat.getResponse().setCharacterEncoding("UTF-8");
        beat.getResponse().setContentType("application/text");
        PrintWriter out = beat.getResponse().getWriter();
        out.print(message);
        out.close();
      }
 
    };
  }

GsonUtils.java

?
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package com.xxx.xxx.common.util.gson;
 
import com.google.gson.*;
 
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
 
public class GsonUtils {
  //private static Log logger = LogFactory.getLog(GsonUtils.class);
  public static String toJsonWithGson(Object obj) {
    Gson gson = createGson();  //new Gson();
    return gson.toJson(obj);
  }
 
  public static String toJsonWithGson(Object obj, Type type) {
    Gson gson = createGson();  //new Gson();
    return gson.toJson(obj, type);
  }
 
  @SuppressWarnings("unchecked")
  public static String toJsonWithGson(List list) {
    Gson gson = createGson();  //new Gson();
    return gson.toJson(list);
  }
 
  @SuppressWarnings("unchecked")
  public static String toJsonWithGson(List list, Type type) {
    Gson gson = createGson();  //new Gson();
    return gson.toJson(list, type);
  }
 
  public static String toJsonWithGsonBuilder(Object obj) {
    Gson gson = new GsonBuilder().setExclusionStrategies(new MyExclusionStrategy()).serializeNulls().create();
    return gson.toJson(obj);
  }
 
  public static String toJsonWithGsonBuilder(Object obj, Type type) {
    Gson gson = new GsonBuilder().setExclusionStrategies(new MyExclusionStrategy()).serializeNulls().create();
    return gson.toJson(obj, type);
  }
 
  @SuppressWarnings("unchecked")
  public static String toJsonWithGsonBuilder(List list) {
    Gson gson = new GsonBuilder().setExclusionStrategies(new MyExclusionStrategy()).serializeNulls().create();
    return gson.toJson(list);
  }
 
  @SuppressWarnings("unchecked")
  public static String toJsonWithGsonBuilder(List list, Type type) {
    Gson gson = new GsonBuilder().setExclusionStrategies(new MyExclusionStrategy()).serializeNulls().create();
    return gson.toJson(list, type);
  }
 
  public static <T> Object fromJson(String json, Class<T> clazz) {
    Object obj = null;
    try {
      Gson gson = new Gson();
      obj = gson.fromJson(json, clazz);
    } catch (Exception e) {
      //logger.error("fromJson方法转换json串到实体类出错", e);
    }
    return obj;
  }
 
  /**
   * 如果 Long 的数字超过15位,转换为String,在json中数字两边有引号
   * @return
   */
  private static Gson createGson(){
    GsonBuilder gsonBuilder = new GsonBuilder();
    LongSerializer serializer = new LongSerializer();
    gsonBuilder.registerTypeAdapter(Long.class, serializer);
    gsonBuilder.registerTypeAdapter(long.class, serializer);
    Gson gson = gsonBuilder.create();
    return gson;
  }
 
  public static void main(String... args) throws Exception{
//    long a = 12345678901234578L;
//
//    GsonBuilder builder = new GsonBuilder();
//    builder.registerTypeAdapter(Long.class, new LongSerializer());
//    Gson gson2 = builder.create();
//    System.out.println(gson2.toJson(a));
//
//    Gson gson = new GsonBuilder().setExclusionStrategies(new MyExclusionStrategy()).serializeNulls().create();
//    String str = gson.toJson(a);
//    System.out.println(str);
 
    TestVO vo = new TestVO();
    vo.setId(618708732263538688L);
    vo.setId2(918708732263538688L);
    System.out.println(toJsonWithGson(vo));
 
  }
 
  static class LongSerializer implements JsonSerializer<Long> {
    public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
      if(src!=null){
        String strSrc = src.toString();
        if(strSrc.length()>15){
          return new JsonPrimitive(strSrc);
        }
      }
      return new JsonPrimitive(src);
    }
  }
 
  static class TestVO {
    public long getId() {
      return id;
    }
 
    public void setId(long id) {
      this.id = id;
    }
 
    private long id;
 
    public Long getId2() {
      return id2;
    }
 
    public void setId2(Long id2) {
      this.id2 = id2;
    }
 
    private Long id2;
  }
}

MyExclusionStrategy.java

?
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
package com.xxx.xxx.common.util.gson;
 
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
 
public class MyExclusionStrategy implements ExclusionStrategy {
 
  private final Class<?> typeToSkip;
   
  public MyExclusionStrategy(){
    this.typeToSkip=null;
  }
   
  public MyExclusionStrategy(Class<?> typeToSkip) {
    this.typeToSkip = typeToSkip;
  }
   
  public boolean shouldSkipClass(Class<?> clazz) {
    return (clazz == typeToSkip);
  }
 
  public boolean shouldSkipField(FieldAttributes f) {
    return f.getAnnotation(NotSerialize.class) != null;
  }
 
}

NotSerialize

?
1
2
3
4
5
6
7
8
9
10
11
package com.xxx.xxx.common.util.gson;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface NotSerialize {
}

以上这篇gson ajax 数字精度丢失问题的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。