Fastjson SerializerFeature&@JSONField的使用

本文详细介绍了 FastJSON 的使用方法及技巧,包括 SerializerFeature 的各项功能、JSONField 注解的使用方式,以及 JSONPath 的基本操作。

依赖

 <dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>fastjson</artifactId>
       <version>1.2.7</version>
 </dependency>

SerializerFeature

 public static void main(String[] args) {
        @Data
        @Accessors
        @AllArgsConstructor
        class Xsd{
            private Integer id;
            private String name;
            private Date brDate;
            private String clazz;
            private Integer size;
            private List list;
        }
        Xsd xsd=new Xsd(1,"\"张林\"",new Date(),null,null,null);
        System.out.println("===========================");
        System.out.println(JSON.toJSONString(xsd));

        System.out.println("显示为null的字段===========================");
        System.out.println(JSON.toJSONString(xsd,SerializerFeature.WriteMapNullValue));

        System.out.println("null显示''===========================");
        System.out.println(JSON.toJSONString(xsd,SerializerFeature.WriteNullStringAsEmpty));

        System.out.println("转换array===========================");
        System.out.println(JSON.toJSONString(xsd,SerializerFeature.BeanToArray));

        System.out.println("全局修改日期格式,默认为false===========================");
        JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd";
        System.out.println(JSON.toJSONString(xsd,SerializerFeature.WriteDateUseDateFormat));

        System.out.println("PrettyFormat格式化json===========================");
        System.out.println(JSON.toJSONString(xsd,SerializerFeature.PrettyFormat));

        System.out.println("按字段名称排序后输出===========================");
        System.out.println(JSON.toJSONString(xsd,SerializerFeature.SortField));

        System.out.println("Date使用ISO8601格式输出===========================");
        System.out.println(JSON.toJSONString(xsd, SerializerFeature.UseISO8601DateFormat));

        System.out.println("单引号UseSingleQuotes=====双引号QuoteFieldNames========");
        System.out.println(JSON.toJSONString(xsd, SerializerFeature.UseSingleQuotes));

        System.out.println("数字为null输出0========");
        System.out.println(JSON.toJSONString(xsd, SerializerFeature.WriteNullNumberAsZero));

        System.out.println("中文转义支持IE6========");
        System.out.println(JSON.toJSONString(xsd, SerializerFeature.BrowserCompatible));

        System.out.println("特殊字符转义========");
        System.out.println(JSON.toJSONString(xsd, SerializerFeature.DisableCheckSpecialChar));

        System.out.println("list为null转[]========");
        System.out.println(JSON.toJSONString(xsd, SerializerFeature.WriteNullListAsEmpty));

    }

@JSONField

注意:1、若属性是私有的,必须有set*方法。否则无法反序列化。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.Date;
import java.util.List;

@Data
@Accessors
public class TestCor {
    /**
     *     int ordinal() default 0  字段排序
     *     String name() default ""; 重命名
     *     String format() default ""; 格式化
     *     boolean serialize() default true; 是否序列化
     *     boolean deserialize() default true;是否反序列化
     *     SerializerFeature[] serialzeFeatures() default {}; 序列化枚举
     *     Feature[] parseFeatures() default {}; 控制反序列化的一些规则
     *     String label() default ""; 批量处理某一类的属性,比如不序列化某一类属性。
     *     boolean jsonDirect() default false; 可直接赋值为JSON  xxx="{'size':1}"
     *     Class<?> serializeUsing() default Void.class;  定制序列化
     *     Class<?> deserializeUsing() default Void.class; 定制反序列化
     *     String[] alternateNames() default {}; 反序列化时使用多个不同的字段名称  AJSON{"AField":1} BJSON{"BField":2}
     *                                          alternateNames={"AField","BField"}  那么2个key都会相应的赋值到当前字段
     *     boolean unwrapped() default false;  把子对象的内容放到父对象里面
     *     String defaultValue() default "";  默认值
     */
        @JSONField(ordinal = 3,label = "b")
        private Integer id=5;
        @JSONField(ordinal = 2,name = "othername",label = "a",alternateNames={"othername"})
        private String name="张";
        @JSONField(ordinal = 1,format = "yyyy-MM-dd",label = "a",deserialize =false)
        private Date format=new Date();
        @JSONField(ordinal = 4,jsonDirect = true)
        private String jsonDirect="{'size':1}";
        @JSONField(ordinal = 5,serializeUsing = NumberCon.class,label = "b",deserializeUsing =NumberConUn.class )
        private Double hight=175.2;
        @JSONField(ordinal = 6,serialzeFeatures = SerializerFeature.WriteNullListAsEmpty)
        private List list=null;
        @JSONField(ordinal = 7,defaultValue = "--")
        private String defaultValue;
        @JSONField(ordinal = 9,unwrapped = false)
        private Objs testCor2=new Objs();

        @JSONField(unwrapped = true)
        private Objs testCor1=new Objs();
        @Data
        @Accessors
        class Objs{
            private String childObj="childObj";
        }
    public static void main(String[] args) {
        TestCor t=new TestCor();
        System.out.println(JSON.toJSONString(t));

        String str="{\"childObj\":\"childObj\",\"format\":\"2021-06-29\",\"othername\":\"张\",\"id\":5,\"jsonDirect\":{\"size\":1},\"hight\":\"175.2CM\",\"list\":[],\"defaultValue\":\"--\",\"testCor2\":{\"childObj\":\"childObj\"}}";
        TestCor testCor = JSONObject.parseObject(str, TestCor.class);
        System.out.println(JSON.toJSONString(testCor,SerializerFeature.PrettyFormat));
    }
public class DecimalUtil extends JsonSerializer<BigDecimal> {
    @Override
    public void serialize(BigDecimal bigDecimal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(bigDecimal.setScale(2, RoundingMode.HALF_UP).toString());
//        jsonGenerator.writeNumber(bigDecimal.setScale(2));
    }
}

JSONPath

  public static void main(String[] args) {
        String str="{\"asd\":[{\"id\":1,\"name\":\"小明\"},{\"id\":2,\"name\":\"张3\"}]}";
        String str2="[{\"id\":1,\"name\":\"小明\"},{\"id\":2,\"name\":\"张3\"},{\"id\":3,\"name\":null}]";
        JSONObject json1=JSONObject.parseObject(str);
        JSONArray json2=JSONArray.parseArray(str2);
        //数组全部对象
        System.out.println(JSONPath.eval(json1, "$"));
        //访问数组
        System.out.println(JSONPath.eval(json2, "$"));
        //访问数组第一个
        System.out.println(JSONPath.eval(json2, "$[0]"));
        //访问数组第一个的id
        System.out.println(JSONPath.eval(json2, "$[0].id"));
        //访问数组下标0-1的id
        System.out.println(JSONPath.eval(json2, "$[0,1].id"));
        //访问对象非空过滤
        System.out.println(JSONPath.eval(json2, "$[?(name)]"));
        //过滤id>1
        System.out.print(JSONPath.eval(json2, "$[id>1]"));
        System.out.println(JSONPath.eval(json1, "$.asd[id>1]"));
        //过滤比较
        System.out.print(JSONPath.eval(json2, "$[name='张3']"));
        System.out.println(JSONPath.eval(json1, "$.asd[name='张3']"));
        //字符匹配
        System.out.print(JSONPath.eval(json2, "$[name like '%张%']"));
        System.out.println(JSONPath.eval(json1, "$.asd[name='张3']"));
        //in 包含
        System.out.print(JSONPath.eval(json2, "$[name in ('张三','张3')]"));
        System.out.println(JSONPath.eval(json1, "$.asd[name in ('张三','张3')]"));
        // 数组长度
        System.out.println(JSONPath.eval(json1, "$.asd.size()"));

    }
@Data @TableName("BIZ_MAINTENANCE_PLAN") public class BizMaintenancePlanEntity { @TableId(value ="ID" ) @JSONField(name = "id") private String id; @TableField(value = "SID" ) @JSONField(name = "sid") private Integer sid; @TableField(value = "MAINTENANCE_STATUS" ) @JSONField(name = "maintenanceStatus") private Integer maintenanceStatus; @TableField(value = "PLAN_NAME" ) @JSONField(name = "planName") private String planName; @TableField(value = "MAINTENANCE_CYCLE" ) @JSONField(name = "maintenanceCycle") private Integer maintenanceCycle; @TableField(value = "CYCLE_UNIT" ) @JSONField(name = "cycleUnit") private Integer cycleUnit; @TableField(value = "RELATED_STRATEGY_ID" ) @JSONField(name = "relatedStrategyId") private String relatedStrategyId; @TableField(fill = FieldFill.INSERT, value = "CREATED_AT") @JSONField(name = "createdAt") private Date createdAt; @TableField(fill = FieldFill.INSERT_UPDATE, value = "UPDATED_AT") @JSONField(name = "updatedAt") private Date updatedAt; @TableField(value = "DELETED_AT" ) @JSONField(name = "deletedAt") private Date deletedAt; @TableField(value = "F_TENANT_ID",fill = FieldFill.INSERT_UPDATE) @JSONField(name = "tenantId") private String tenantId; @TableField("F_FLOW_ID") @JSONField(name = "flowId") private String flowId; @TableField("F_FLOW_TASK_ID") @JSONField(name = "flowTaskId") private String flowTaskId; @TableField("MAINTENANCE_DURATION") @JSONField(name = "maintenanceDuration") private String maintenanceDuration; /** 设备id **/ @TableField("DEVICE_ID") @JSONField(name = "deviceId") private String deviceId; @TableField(exist = false) @JSONField(name = "deviceName") private String deviceName; @TableField(exist = false) @JSONField(name = "kks") private String kks; /** fmea项目对应的故障模式list **/ @TableField(exist = false) @JSONField(name = "relatedStrategyList") private List<BizMainPlanFaultModeEntity> relatedStrategyList; } */ @Data @TableName("BIZ_MAIN_PLAN_FAULT_MODE") public class BizMainPlanFaultModeEntity { @TableId(value ="ID" ) @JSONField(name = "id") private String id; @TableField(value = "REPAIR_PLAN_ID" ) @JSONField(name = "repairPlanId") private String repairPlanId; @TableField(value = "CAUSE_GROUP_DESC" ) @JSONField(name = "causeGroupDesc") private String causeGroupDesc; @TableField(value = "DET" ) @JSONField(name = "det") private Integer det; @TableField(value = "FAULT_MODE_NAME" ) @JSONField(name = "faultModeName") private String faultModeName; @TableField(value = "FUNCTION_DESC" ) @JSONField(name = "functionDesc") private String functionDesc; @TableField(value = "MAINTENANCE_CONTENT" ) @JSONField(name = "maintenanceContent") private String maintenanceContent; @TableField(value = "MAINTENANCE_STRATEGY" ) @JSONField(name = "maintenanceStrategy") private String maintenanceStrategy; @TableField(value = "OCC" ) @JSONField(name = "occ") private Integer occ; @TableField(value = "OPTIMIZATION_SUGGESTION" ) @JSONField(name = "optimizationSuggestion") private String optimizationSuggestion; @TableField(value = "PART_AFFECT_DESC" ) @JSONField(name = "partAffectDesc") private String partAffectDesc; @TableField(value = "RISK_LEVEL" ) @JSONField(name = "riskLevel") private String riskLevel; @TableField(value = "RPN" ) @JSONField(name = "rpn") private Integer rpn; @TableField(value = "STRUCTURE_CHILD_NAME" ) @JSONField(name = "structureChildName") private String structureChildName; @TableField(value = "STRUCTURE_NAME" ) @JSONField(name = "structureName") private String structureName; @TableField(value = "STRUCTURE_PARENT_NAME" ) @JSONField(name = "structureParentName") private String structureParentName; @TableField(value = "TOP_AFFECT_DESC" ) @JSONField(name = "topAffectDesc") private String topAffectDesc; @TableField(value = "F_TENANT_ID",fill = FieldFill.INSERT_UPDATE) @JSONField(name = "tenantId") private String tenantId; @TableField("F_FLOW_ID") @JSONField(name = "flowId") private String flowId; @TableField("F_FLOW_TASK_ID") @JSONField(name = "flowTaskId") private String flowTaskId; }
最新发布
10-15
根据提供的实体类代码和问题描述,以下是关于`relatedStrategyList`中null值字段不显示问题的详细分析和解决方案: --- ### **核心问题定位** 1. **实体类注解冲突**: - 同时使用了`@JSONField`(Fastjson)和`@TableField`(MyBatis-Plus)注解 - 未明确指定JSON序列化的null值处理策略 2. **字段定义问题**: ```java @TableField(exist = false) // 表示非数据库字段 @JSONField(name = "relatedStrategyList") private List<BizMainPlanFaultModeEntity> relatedStrategyList; ``` --- ### **解决方案** #### 方案1:强制序列化null字段(Fastjson配置) ```java // 方法1:实体类注解配置 @JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue) private String faultModeName; // 方法2:全局配置(推荐) JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteMapNullValue.getMask(); ``` #### 方案2:修改Map转换逻辑 ```java // 替换原来的JsonUtil.entityToMap() Map<String, Object> map = new LinkedHashMap<>() {{ put("id", entity.getId()); put("faultModeName", entity.getFaultModeName()); // 即使为null也会保留key // 其他字段... }}; ``` #### 方案3:DTO模式(推荐) ```java @Data public class BizMainPlanFaultModeDTO { @JSONField(serialzeFeatures = SerializerFeature.WriteMapNullValue) private String faultModeName = ""; // 设置默认值 // 其他字段... } // 在Service层转换 public List<BizMainPlanFaultModeDTO> convertToDTO(List<BizMainPlanFaultModeEntity> list) { return list.stream().map(entity -> { BizMainPlanFaultModeDTO dto = new BizMainPlanFaultModeDTO(); BeanUtils.copyProperties(entity, dto); return dto; }).collect(Collectors.toList()); } ``` --- ### **关键验证步骤** 1. **检查Fastjson版本**: ```xml <!-- 确保使用最新版 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.39</version> </dependency> ``` 2. **测试序列化行为**: ```java String json = JSON.toJSONString(entity, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty); System.out.println(json); ``` 3. **前端联调建议**: ```javascript // 测试接口时添加参数 axios.get('/api', { params: { showNull: true } }) ``` --- ### **字段处理对照表** | 字段名 | 数据库可为空 | 当前表现 | 解决方案 | |--------|-------------|----------|----------| | `faultModeName` | YES | 不显示 | 方案1+方案3 | | `maintenanceStrategy` | YES | 不显示 | 添加`@JSONField`注解 | | `optimizationSuggestion` | YES | 不显示 | 设置DTO默认值 | --- ### **代码优化建议** 1. **统一序列化工具**: ```java // 移除重复注解 @Data public class BizMainPlanFaultModeEntity { @TableId("ID") private String id; // 保持单一职责 } ``` 2. **添加日志追踪**: ```java @PostMapping("/getList") public ActionResult list(@RequestBody BizMaintenancePlanPagination pagination) { log.debug("原始数据: {}", JSON.toJSONString( bizMainPlanFaultModeService.listByRepairPlanId("1"), SerializerFeature.PrettyFormat )); // ... } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值