FastJson轉換自定義枚舉類

在項目中有些狀態須要採用枚舉類型,在數據庫中保存的是name(英文),而前臺須要顯示的是text(中文)。java

因此這就須要本身去實現序列。數據庫

例如對象:express

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等英文字段apache

採用JSONObject.toJSONString(project)來轉會獲得:{"status":"beginning","auditStatus":"pending","confirmStatus":"pending"}json

而個人指望是獲得:{"status":"開始","auditStatus":"待審覈","confirmStatus":"未確認"}app

下邊就是我本身寫的序列工具類:less

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。ide

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

上面SerializeUtil序列工具類主要實現了ObjectSerializer序列化器,並實現接口write(),而後本身實現write方法組合本身須要的值。ui

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); } }
相關文章
相關標籤/搜索