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);
  • 相关阅读:
    代码守恒定律
    第一个Dockerfile
    服务器项目白名单设置
    TOMCAT禁用不安全请求方式
    标准单例模式
    二进制,八进制,十进制,十六进制!!!!
    JAVA按层级遍历二叉树
    String的+
    安装 Rational Rose 启动报错:无法启动此程序,因为计算机中丢失 suite objects.dll
    java中文乱码问题
  • 原文地址:https://www.cnblogs.com/li150dan/p/11016260.html
Copyright © 2011-2022 走看看