zoukankan      html  css  js  c++  java
  • com.alibaba.fastjson使用介绍

    首先,介绍一下fastjson。fastjson是由alibaba开源的一套json处理器。与其他json处理器(如Gson,Jackson等)和其他的Java对象序列化反序列化方式相比,有比较明显的性能优势。

    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,解决序列化时字段格式和是否输出等,如下:

    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

    案例一:

    后端把Long类型的数据序列化成JSON后传给前端,前端可能会出现精度丢失的情况

    例如:201511200001725439 这样一个Long类型的整数,传给前端后会变成201511200001725440

    fastjson将Long类型转换成String类型,解决前后端交互,Java序列化JSON丢失精度问题的方法

    解决方法:

      方法一:在后台将这个Long类型的字段转换成String类型的,风险比较大。

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

    需要导入包:

    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来序列化 

    这样配置解决了如下问题:

          1、让@ResponseBody返回采用fastjson来序列化

          2、字段类型为Date,输出为"yyyy-MM-dd HH:mm:ss"

          3、是否输出值为null的字段

          4、字符类型字段如果为null,输出为"",而非null

          5、等等其他。。。

    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);
  • 相关阅读:
    Windows Azure Web Site (19) Azure Web App链接到VSTS
    Windows Azure Virtual Machine (35) Azure VM通过Linked DB,执行SQL Job
    Azure PowerShell (16) 并行开关机Azure ARM VM
    Windows Azure Virtual Network (12) 虚拟网络之间点对点连接VNet Peering
    Azure ARM (21) Azure订阅的两种管理模式
    Windows Azure Platform Introduction (14) 申请海外的Windows Azure账户
    Azure ARM (20) 将非托管磁盘虚拟机(Unmanage Disk),迁移成托管磁盘虚拟机(Manage Disk)
    Azure ARM (19) 将传统的ASM VM迁移到ARM VM (2)
    Azure ARM (18) 将传统的ASM VM迁移到ARM VM (1)
    Azure Automation (6) 执行Azure SQL Job
  • 原文地址:https://www.cnblogs.com/li150dan/p/11016260.html
Copyright © 2011-2022 走看看