在項目中有些狀態須要採用枚舉類型,在數據庫中保存的是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); } }