gson ajax 数字精度丢失问题的解决方法
ajax传输的json,gson会发生丢失,long > 15的时候会丢失0
解决方案:直接把属性为long的属性自动加上双引号成为js的字符串,这样就不会发生丢失了,ajax自动识别为字符串。
用法:
ajaxResult("",0,new Object()); //随便一个对象就可以,List 之类的
/** * 以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
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
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
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 数字精度丢失问题的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。
赞 (0)