徹底解決JS處理Long類型精度丟失問題(二)

當你的序列化方式採用的FastJson時,該如何處理這種類型轉換問題呢?一模一樣的套路…

SpringMVC 使用FastJson序列化方式

1.增加類型轉換類:

public class FastJsonConfigExt  extends FastJsonConfig {
    public FastJsonConfigExt(){
        super();
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
        serializeConfig.put(Long.class,ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE,ToStringSerializer.instance);
        this.setSerializeConfig(serializeConfig);
    }
}

2.spring mvc 配置文件增加:

    <!--解決fastJson 轉換long型,精度丟失的問題-->
    <bean id="fastJsonConfigExt" class="com.ymm.web.configuration.FastJsonConfigExt"/>

    <!-- 解決@ResponseBody註解直接返回對象並轉換成JSON時出現406問題,同時解決了返回String類型亂碼的問題 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="fastJsonConfig" ref="fastJsonConfigExt" />
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json; charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded; charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
                <property name="features">
                   <list>
                       <!-- null String也要輸出 -->
                       <value>WriteMapNullValue</value>
                       <!-- 輸出key時是否使用雙引號 -->
                       <value>QuoteFieldNames</value>
                       <!-- 字符類型字段如果爲null,輸出爲"",而非null -->
                       <value>WriteNullStringAsEmpty</value>
                   </list>
               </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

執行完以上兩個步驟,便可以將Long類型轉爲String類型,然後在序列化爲JSON數據。但是存在一個問題:fastjson不支持基礎類型如long double等的轉換,僅支持包裝類型。如何解決呢,請看下文。

使用FastJson自定義過濾器,過濾指定字段

1.通過實現FastJson的ValueFilter接口,增加自定義類型轉換器。

public class FastJsonFilterExt implements ValueFilter {
    @Override
    public Object process(Object object, String name, Object value) {
        String userIdStr = "";
        switch (name.toLowerCase()) {
            case "userid":
            case "orderid":{
                if (value != null) {
                    userIdStr = String.valueOf(value);
                    return userIdStr;
                }
            }
        }
        return value;
    }
}

2.xml追加配置:

 <!--解決fastJson 轉換long型,精度丟失的問題-->
    <bean id="fastJsonFilterExt" class="com.ymm.web.configuration.FastJsonFilterExt"/>

    <!-- 解決@ResponseBody註解直接返回對象並轉換成JSON時出現406問題,同時解決了返回String類型亂碼的問題 -->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json; charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
               <property name="features">
                   <list>
                       <!-- null String也要輸出 -->
                       <value>WriteMapNullValue</value>
                       <!-- 輸出key時是否使用雙引號 -->
                       <value>QuoteFieldNames</value>
                       <!-- 字符類型字段如果爲null,輸出爲"",而非null -->
                       <value>WriteNullStringAsEmpty</value>
                   </list>
               </property>
                <property name="filters">
                    <list>
                        <ref bean="fastJsonFilterExt"></ref>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

上面通過指定字段名稱的方式進行過濾轉換類型,解決了long等基礎數據類型不能轉換爲String的問題,同時指定字段進行類型轉換避免了所有Long類型字段都被轉換的尷尬。

使用自定義註解,過濾指定字段

當然也可以通過增加自定義註解方式,在實體屬性上面增加自定義註解,指定要轉換的字段,在轉換器中判斷是否包含註解。

1.增加自定義註解:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface FieldToString {
    public  String  value()  default "true";
}

2.增加轉換器:

    public class BeanPropertyFilter implements ValueFilter {
        private Field field = null;
        @Override
        public Object process(Object obj, String name, Object value) {
            Boolean flag = false;
            try {
                field = obj.getClass().getDeclaredField(name);
                // 獲取註解
                flag = field.getAnnotation(FieldToString.class).value().equals("true");
                if (flag == true && value != null) {
                    // 將其他類型轉換成String類型
                    value = String.valueOf(value);
                }
            } catch (NoSuchFieldException e) {
                return value;
            } catch (Exception e) {
                return value;
            }
            return value;
        }
    }

3.使用方式

直接在要轉換的字段上增加@FieldToString註解即可。


參考:
https://www.jianshu.com/p/8d8152725114?from=singlemessage

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章