com.alibaba.fastjson使用介紹

首先,介紹一下fastjson。fastjson是由alibaba開源的一套json處理器。與其餘json處理器(如Gson,Jackson等)和其餘的Java對象序列化反序列化方式相比,有比較明顯的性能優點。html

maven 添加配置:前端

<!-- 阿里fastjson包JSON轉換-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>
String queryJson1 = JSON.toJSONString(studentQuery); //序列化
String queryJson2 = JSON.toJSONString(studentQuery, SerializerFeature.WriteDateUseDateFormat); //序列化時指定格式
String queryJson3 = JsonUtils.toJSONString(studentQuery, true); //自定義序列化格式
StudentQuery queryParam = JSON.parseObject(queryJson, StudentQuery.class); //反序列化

也能夠自定義序列化JsonUtils類繼承自JSON,解決序列化時字段格式和是否輸出等,以下:java

package com.demo.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * @ProjectName: ssm.maven
 * @Package: com.demo.utils
 * @ClassName: JsonUtils
 * @Description: 自定義JSON
 * @Author: XXX
 * @Date: 2019/6/21 9:57
 * @Version: 1.0
 */
public class JsonUtils extends JSON {
    /**
     * 序列化配置
     * @param object
     * @param isFeatures
     * @return
     */
    public static String toJSONString(Object object, boolean isFeatures) {
        if (isFeatures) {
            SerializerFeature[] features = new SerializerFeature[3];
            features[0] = SerializerFeature.WriteDateUseDateFormat;
            features[1] = SerializerFeature.WriteMapNullValue;
            features[2] = SerializerFeature.WriteNullStringAsEmpty;
            return toJSONString(object, features);
        }
        else {
            return toJSONString(object);
        }
    }
}
View Code

案例一:spring

後端把Long類型的數據序列化成JSON後傳給前端,前端可能會出現精度丟失的狀況

例如:201511200001725439 這樣一個Long類型的整數,傳給前端後會變成201511200001725440json

fastjson將Long類型轉換成String類型,解決先後端交互,Java序列化JSON丟失精度問題的方法後端

解決方法:mvc

  方法一:在後臺將這個Long類型的字段轉換成String類型的,風險比較大。app

  方法二:使用fastjson的提供的註解,@JSONField(serializeUsing = ToStringSerializer.class)。        async

須要導入包:maven

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.ToStringSerializer;
@JSONField(serializeUsing = ToStringSerializer.class)
private Long id;

備註:  

  fastjson com.alibaba.fastjson.serializer 包下面提供了多種數據類型轉換的註解。

另外本身也能夠拓展這些註解,經過實現ObjectSerializer 接口來完成。

例如自定義ToStringSerializer將Long轉String的代碼:

import java.io.IOException;
import java.lang.reflect.Type;

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;

public class LongToStringSerializer implements ObjectSerializer {
    public static final LongToStringSerializer instance = new LongToStringSerializer();

    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
                    throws IOException {
          SerializeWriter out = serializer.out;
          if (object == null) {
                out.writeNull();
                return;
          }
          String strVal = object.toString();
          out.writeString(strVal);
    }
}
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    
/**
* 利用fastJson替換掉jackson,且解決中文亂碼問題
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

          FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
          FastJsonConfig fastJsonConfig = new FastJsonConfig();


          fastJsonConfig.setSerializerFeatures(
                           SerializerFeature.DisableCircularReferenceDetect,
                           SerializerFeature.WriteMapNullValue,
                           SerializerFeature.WriteNullNumberAsZero,
                           SerializerFeature.WriteNullStringAsEmpty,
                           SerializerFeature.WriteNullListAsEmpty,
                           SerializerFeature.WriteNullBooleanAsFalse,
                           SerializerFeature.WriteNonStringKeyAsString,
                           SerializerFeature.BrowserCompatible);       

        /**
         * 序列換成json時,將全部的long變成string,解決Long轉json精度丟失的問題
         * 由於js中得數字類型不能包含全部的java long值
         */

          SerializeConfig serializeConfig = SerializeConfig.globalInstance;
          serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
          serializeConfig.put(Long.class, ToStringSerializer.instance);
          serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
          fastJsonConfig.setSerializeConfig(serializeConfig);

 
 

          //處理中文亂碼問題
          List<MediaType> fastMediaTypes = new ArrayList<>();
          fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);

 
 

          fastConverter.setSupportedMediaTypes(fastMediaTypes);
          fastConverter.setFastJsonConfig(fastJsonConfig);
          converters.add(fastConverter);

    }

}

案例二:

讓@ResponseBody用fastjson來序列化JSON返回到前端,如何在配置文件中設置

因爲@ResponseBody返回的是默認用Jackson來序列化的,因此要讓spring的消息轉換器換成fastjson來序列化 

這樣配置解決了以下問題:

      一、讓@ResponseBody返回採用fastjson來序列化

      二、字段類型爲Date,輸出爲"yyyy-MM-dd HH:mm:ss"

      三、是否輸出值爲null的字段

      四、字符類型字段若是爲null,輸出爲"",而非null

      五、等等其餘。。。

maven 添加配置:

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>

在springmvc.xml中配置@ResponseBody使用fastjson

<!-- 配置註解驅動 從新設置@RequestMapping中對@ResponseBody以String類型消息轉換器的字符集 -->
    <mvc:annotation-driven>
        <mvc:async-support default-timeout="3000"/>
        <mvc:message-converters register-defaults="true">
            <!-- 解決Controller返回json中文亂碼問題 -->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <!-- <property name="supportedMediaTypes" value="text/html;charset=UTF-8" /> -->
                <!-- <property name="supportedMediaTypes" value="application/json;charset=UTF-8" > -->
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                        <value>application/xml;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <!-- 默認@ResponseBody返回的是jackson來序列化的, 因此要讓spring的消息轉換器換成fastjson來序列化 -->
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="fastJsonConfig">
                    <bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
                        <!-- 序列化配置 -->
                        <property name="serializerFeatures">
                            <list value-type="com.alibaba.fastjson.serializer.SerializerFeature">
                                <!-- 字段類型爲Date,輸出爲"yyyy-MM-dd HH:mm:ss" -->
                                <value>WriteDateUseDateFormat</value>
                                <!-- 是否輸出值爲null的字段,默認是false -->
                                <value>WriteMapNullValue</value>
                                <!-- 字符類型字段若是爲null,輸出爲"",而非null -->
                                <value>WriteNullStringAsEmpty</value>
                                <!--<value>WriteNullNumberAsZero</value>-->
                                <!--<value>WriteNullListAsEmpty</value>-->
                                <!--<value>WriteNullBooleanAsFalse</value>-->
                                <!--<value>QuoteFieldNames</value>-->
                            </list>
                        </property>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
View Code

 若是上面配置文件中只是簡單配置了一下fastjson來序列化,而沒有配置那些「序列化配置」項目,則須要經過在實體對象屬性上加註解方式實現了

package com.demo.model.vo;

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.ToStringSerializer;
//import com.fasterxml.jackson.annotation.JsonFormat;
//import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * @ProjectName: maven
 * @Package: com.demo.model.vo
 * @ClassName: StudentVO
 * @Description: 返回請求對象
 * @Author: XXX
 * @Date: 2019/6/18 10:44
 * @Version: 1.0
 */
@Data
@ApiModel(value = "StudentVO", description = "返回請求對象")
public class StudentVO implements Serializable {
    @ApiModelProperty(value = "主鍵")
    @JSONField(serializeUsing = ToStringSerializer.class)
    //@JsonSerialize(using = com.fasterxml.jackson.databind.ser.std.ToStringSerializer.class)
    private Long id;

    @ApiModelProperty(value = "學生姓名")
    private String name;

    @ApiModelProperty(value = "學生年齡")
    private Integer age;

    @ApiModelProperty(value = "建立日期")
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    //@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createtime;
}
View Code

切記:這種配置只使用於@ResponseBody返回json格式,而不使用於經過在代碼中經過JSON.toJSONString()方式來直接序列化的json,若想達到一樣效果能夠經過下面方式

方式一:

String queryJson = JSON.toJSONString(studentQuery, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty);

方式二:使用上面提到的自定義序列化類JsonUtils

String queryJson = JsonUtils.toJSONString(studentQuery, true);
相關文章
相關標籤/搜索