• FastJson转换自定义枚举类


    在项目中有些状态需要采用枚举类型,在数据库中保存的是name(英文),而前台需要显示的是text(中文)。

    所以这就需要自己去实现序列。

    例如对象:

    import java.util.Date;
    import java.util.List;
    
    import com.alibaba.fastjson.annotation.JSONField;
    
    public class Project {
        
    
        /**
         *
         * 审核状态
         */
        @JSONField(name = "auditStatus")
        private AuditStatus auditStatus;
    
        
        /**
         *
         * 确认状态
         */
        @JSONField(name = "confirmStatus")
        private ConfirmStatus confirmStatus;
    
        /**
         * 获取审核状态
         */
        public AuditStatus getAuditStatus() {
            return auditStatus;
        }
    
        /**
         * 设置审核状态
         */
        public void setAuditStatus(AuditStatus auditingStatus) {
            this.auditStatus = auditStatus ;
        }
    
        
    
        /**
         * 获取确认状态
         */
        public ConfirmStatus getConfirmStatus() {
            return confirmStatus;
        }
    
        /**
         *设置确认状态
         */
        public void setConfirmStatus(ConfirmStatus confirmStatus) {
            this.confirmStatus = confirmStatus;
        }
    
        
    
        /**
         * 项目状态
         */
        @JSONField(name = "status")
        private Status status;
    
        /**
         *获取状态
         */
        public Status getStatus() {
            return status;
        }
        
        /**
         *设置状态
         */
        public void setStatus(Status status) {
            this.status = status;
        }
    
    
    
        /**
         * 状态枚举类
         * 
         * @ClassName: Status
         * @author liwenjian
         * @date 2016年11月11日上午11:33:28
         * @version 1.0.0
         */
        public enum Status {
            beginning("开始"), 
            finished("已结束");
    
            private String text;
    
            private Status(String text) {
                this.text = text;
            }
    
            public String getText() {
                return text;
            }
    
            public static Status enumOf(Integer ordinal) {
                for (Status s : Status.values()) {
                    if (ordinal == s.ordinal()) {
                        return s;
                    }
                }
                return null;
            }
    
            public static Status enumOf(String name) {
                for (Status s : Status.values()) {
                    if (name == s.name() || name.equalsIgnoreCase(s.name())) {
                        return s;
                    }
                }
                return null;
            }
    
            public static String getText(Integer code) {
                Status apf = enumOf(code);
                if (apf != null) {
                    return apf.text;
                }
                return null;
            }
    
            public static String getText(Status status) {
                return status.getText();
            }
    
        }
    
        
        /**
         * 审核状态
         * 
         * @ClassName: AuditStatus
         * @author liwenjian
         * @date 2016年11月27日下午2:42:46
         * @version 1.0.0
         */
        public enum AuditStatus {
            /**
             * 待审核
             */
            pending("待审核"),
            /**
             * 已审核
             */
            approve("已审核"),
            /**
             * 已退回
             */
            refuse("已退回"),
            /**
             * 已取消
             */
            cancel("已取消");
    
            private String text;
    
            private AuditStatus(String text) {
                this.text = text;
            }
    
            public String getText() {
                return text;
            }
    
            public static AuditStatus enumOf(Integer ordinal) {
                for (AuditStatus as : AuditStatus.values()) {
                    if (ordinal == as.ordinal()) {
                        return as;
                    }
                }
                return null;
            }
    
            public static AuditStatus enumOf(String name) {
                for (AuditStatus as : AuditStatus.values()) {
                    if (name == as.name() || name.equalsIgnoreCase(as.name())) {
                        return as;
                    }
                }
                return null;
            }
    
            public static String getText(Integer code) {
                AuditStatus as = enumOf(code);
                if (as != null) {
                    return as.text;
                }
                return null;
            }
    
            public static String getText(AuditStatus as) {
                return as.getText();
            }
    
        }
    
        /**
         * 
         * 确认状态
         * 
         * @ClassName: ConfirmStatus
         * @author liwenjian
         * @date 2016年11月29日上午11:15:18
         * @version 1.0.0
         */
        public enum ConfirmStatus {
            /**
             * 未确认
             */
            pending("未确认"),
            /**
             * 已确认
             */
            confirmed("已确认");
    
            private String text;
    
            private ConfirmStatus(String text) {
                this.text = text;
            }
    
            public String getText() {
                return text;
            }
    
            public static ConfirmStatus enumOf(Integer ordinal) {
                for (ConfirmStatus cs : ConfirmStatus.values()) {
                    if (ordinal == cs.ordinal()) {
                        return cs;
                    }
                }
                return null;
            }
    
            public static ConfirmStatus enumOf(String name) {
                for (ConfirmStatus cs : ConfirmStatus.values()) {
                    if (name == cs.name() || name.equalsIgnoreCase(cs.name())) {
                        return cs;
                    }
                }
                return null;
            }
    
            public static String getText(Integer code) {
                ConfirmStatus cs = enumOf(code);
                if (cs != null) {
                    return cs.text;
                }
                return null;
            }
    
            public static String getText(ConfirmStatus cs) {
                return cs.getText();
            }
    
        }
    
    }

    数据库保存的状态为:beginning,finished等英文字段

    采用JSONObject.toJSONString(project)来转会得到:{"status":"beginning","auditStatus":"pending","confirmStatus":"pending"}

    而我的期望是得到:{"status":"开始","auditStatus":"待审核","confirmStatus":"未确认"}

    下边就是我自己写的序列工具类:

    package cn.com.yodata.core.util;
    
    import java.io.IOException;
    import java.lang.reflect.Type;
    import java.text.DecimalFormat;
    
    import com.alibaba.fastjson.serializer.DoubleSerializer;
    import com.alibaba.fastjson.serializer.JSONSerializer;
    import com.alibaba.fastjson.serializer.ObjectSerializer;
    import com.alibaba.fastjson.serializer.SerializeConfig;
    import com.alibaba.fastjson.serializer.SerializeWriter;
    import com.alibaba.fastjson.serializer.SerializerFeature;
    
    import com.lwj.modules.project.model.Project;
    import com.lwj.modules.project.model.SubProject;
    
    /**
     * JSON序列
     * 
     * @ClassName: SerializeUtil
     * @author liwenjian
     * @date 2016年12月15日下午6:15:14
     * @version 1.0.0
     */
    public class SerializeUtil {
        private static SerializeConfig globalInstance = SerializeConfig.getGlobalInstance();
        static {
            // 配置需要序列的指定类
            globalInstance.put(Double.class, new DoubleSerializerConfig(new DecimalFormat("0.00")));
            globalInstance.put(Project.Status.class, EnumStatusSerializer.instance);
            globalInstance.put(Project.AuditStatus.class, EnumStatusSerializer.instance);
            globalInstance.put(Project.ConfirmStatus.class, EnumStatusSerializer.instance);
            globalInstance.put(SubProject.Status.class, EnumStatusSerializer.instance);
            globalInstance.put(SubProject.AuditStatus.class, EnumStatusSerializer.instance);
        }
    
        public static SerializeConfig instance() {
            return globalInstance;
        }
    
        /**
         * Double格式保留两位小数点(0.00)
         * 
         * @ClassName: DoubleSerializerConfig
         * @author liwenjian
         * @date 2016年12月17日下午3:09:43
         * @version 1.0.0
         */
        public static class DoubleSerializerConfig extends DoubleSerializer {
            public DoubleSerializerConfig(DecimalFormat decimalFormat) {
                this.decimalFormat = decimalFormat;
            }
    
            private DecimalFormat decimalFormat = null;
    
            public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
                    throws IOException {
                SerializeWriter out = serializer.out;
    
                if (object == null) {
                    out.writeNull(SerializerFeature.WriteNullNumberAsZero);
                    return;
                }
    
                double doubleValue = ((Double) object).doubleValue();
    
                if (Double.isNaN(doubleValue) || Double.isInfinite(doubleValue)) {
                    out.writeNull();
                } else {
                    if (decimalFormat == null) {
                        out.writeDouble(doubleValue, true);
                    } else {
                        String doubleText = decimalFormat.format(doubleValue);
                        out.write(""" + doubleText + """);
                    }
                }
            }
        }
    
        /**
         * 枚举类序列
         * 
         * @ClassName: EnumStatusSerializer
         * @author liwenjian
         * @date 2017年2月23日上午11:13:50
         * @version 1.0.0
         */
        public static class EnumStatusSerializer implements ObjectSerializer {
            
            public final static EnumStatusSerializer instance = new EnumStatusSerializer();
    
            @Override
            public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
                    throws IOException {
                SerializeWriter out = serializer.out;
                if (object instanceof Project.Status) {
                    // 总项目状态
                    Project.Status status = (Project.Status) object;
                    // 如果直接使用out.write(status.getText()),则输出的值没有双引号,json格式不对,所以这里前后加了双引号
                    out.write(""" + status.getText() + """);
                } else if (object instanceof Project.AuditStatus) {
                    // 总项目审核状态
                    Project.AuditStatus status = (Project.AuditStatus) object;
                    out.write(""" + status.getText() + """);
                } else if (object instanceof Project.ConfirmStatus) {
                    // 总项目确认状态
                    Project.ConfirmStatus status = (Project.ConfirmStatus) object;
                    out.write(""" + status.getText() + """);
                } else if (object instanceof SubProject.Status) {
                    SubProject.Status status = (SubProject.Status) object;
                    out.write(""" + status.getText() + """);
                } else if (object instanceof SubProject.AuditStatus) {
                    SubProject.AuditStatus status = (SubProject.AuditStatus) object;
                    out.write(""" + status.getText() + """);
                } else {
                    out.writeEnum((Enum<?>) object);
                }
            }
    
        }
    
    }

    转换的时候需要加入自己指定的SerializeConfig。

    JSONObject.toJSONString(project,SerializeUtil.instance());

    上面SerializeUtil序列工具类主要实现了ObjectSerializer序列化器,并实现接口write(),然后自己实现write方法组合自己需要的值。

    ObjectSerializer中原码如下:

    /*
     * Copyright 1999-2101 Alibaba Group.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    package com.alibaba.fastjson.serializer;
    
    import java.io.IOException;
    import java.lang.reflect.Type;
    
    /**
     * Interface representing a custom serializer for fastjson. You should write a custom serializer, if
     * you are not happy with the default serialization done by fastjson. You will also need to register
     * this serializer through {@link com.alibaba.fastjson.serializer.SerializeConfig#put(Type, ObjectSerializer)}.
     *
     * <pre>
     * public static class Result {
     *     public ResultCode code;
     * }
     * 
     * public static enum ResultCode {
     *     LOGIN_FAILURE(8), INVALID_ARGUMENT(0), SIGN_ERROR(17);
     *     public final int value;
     *     ResultCode(int value){
     *         this.value = value;
     *     }
     * }
     * 
     * public static class ResultCodeSerilaizer implements ObjectSerializer {
     *     public void write(JSONSerializer serializer, 
     *                       Object object, 
     *                       Object fieldName, 
     *                       Type fieldType,
     *                       int features) throws IOException {
     *         serializer.write(((ResultCode) object).value);
     *     }
     * }
     * 
     * SerializeConfig.getGlobalInstance().put(ResultCode.class, new ResultCodeSerilaizer());
     * 
     * Result result = new Result();
     * result.code = ResultCode.SIGN_ERROR;
     * String json = JSON.toJSONString(result, config); // {"code":17}
     * Assert.assertEquals("{"code":17}", json);
     * </pre>
     * @author wenshao[szujobs@hotmail.com]
     */
    public interface ObjectSerializer {
        
        /**
         * fastjson invokes this call-back method during serialization when it encounters a field of the
         * specified type.
         * @param serializer 
         * @param object src the object that needs to be converted to Json.
         * @param fieldName parent object field name
         * @param fieldType parent object field type
         * @param features parent object field serializer features
         * @throws IOException
         */
        void write(JSONSerializer serializer, //
                   Object object, //
                   Object fieldName, //
                   Type fieldType, //
                   int features) throws IOException;
    }

    SerializeUtil工具类实现后的方法:

    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
                    throws IOException {
                SerializeWriter out = serializer.out;
                if (object instanceof Project.Status) {
                    // 总项目状态
                    Project.Status status = (Project.Status) object;
              //注意
              //如果直接使用out.write(status.getText()),则输出的值没有双引号,json格式不对,所以这里前后加了双引号
    out.write(
    """ + status.getText() + """); } else if (object instanceof Project.AuditStatus) { // 总项目审核状态 Project.AuditStatus status = (Project.AuditStatus) object; out.write(""" + status.getText() + """); } else if (object instanceof Project.ConfirmStatus) { // 总项目确认状态 Project.ConfirmStatus status = (Project.ConfirmStatus) object; out.write(""" + status.getText() + """); } else if (object instanceof SubProject.Status) { SubProject.Status status = (SubProject.Status) object; out.write(""" + status.getText() + """); } else if (object instanceof SubProject.AuditStatus) { SubProject.AuditStatus status = (SubProject.AuditStatus) object; out.write(""" + status.getText() + """); } else { out.writeEnum((Enum<?>) object); } }
  • 相关阅读:
    Python接口自动化(四) https请求(SSLError解决办法)
    Python接口自动化(三)post请求四种传送正文方式
    Python接口自动化(二) 发送post请求的接口;发送post【data】;python中字典和json的区别
    requests高级用法
    HDU-1874-畅通工程续 (队列优化)
    Codeforces Round #387 (Div. 2) D. Winter Is Coming
    Codeforces Round #387 (Div. 2) C. Servers
    Codeforces Round #387 (Div. 2) B. Mammoth's Genome Decoding
    Codeforces Round #387 (Div. 2) A. Display Size
    Codeforces Round #386 (Div. 2) B. Decoding
  • 原文地址:https://www.cnblogs.com/lyxy/p/6192700.html
Copyright © 2020-2023  润新知