在项目中有些状态需要采用枚举类型,在数据库中保存的是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);
} }

FastJson转换自定义枚举类的更多相关文章

  1. java 28 - 4 JDK5的新特性 之 枚举的概述和自定义枚举类

    枚举 枚举概述 是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内.举例:一周只有7天,一年只有12个月等. 回想单例设计模式:单例类是一个类只有一个实例 那么多例类就是一个类有多个实例,但 ...

  2. Java分享笔记:自定义枚举类 & 使用enum关键字定义枚举类

    在JDK1.5之前没有enum关键字,如果想使用枚举类,程序员需要根据Java语言的规则自行设计.从JDK1.5开始,Java语言添加了enum关键字,可以通过该关键字方便地定义枚举类.这种枚举类有自 ...

  3. MyBatis 查询映射自定义枚举

    背景                  MyBatis查询若想映射枚举类型,则需要从 EnumTypeHandler 或者 EnumOrdinalTypeHandler 中选一个来使用         ...

  4. Enum 枚举类

    目录 Enum 枚举类 基础 定义与用途 基本方法 示例 进阶 实现原理 枚举与Class对象 自定义枚举类和构造方法及toString() Enum中使用抽象方法来实现枚举实例的多态性 Enum与接 ...

  5. Mybatis 枚举类处理

    目录 类型处理器(TypeHandler) 内置的枚举处理器 EnumTypeHandler源码 自定义枚举类处理 通用枚举处理器 Git 类型处理器(TypeHandler) 无论是 MyBatis ...

  6. SpringMVC 自动封装枚举类的方法

    springmvc默认无法自动封装枚举类,解决方法如下: 1.枚举类 public enum GoodsPromoteEnum { /** * 0 精品 */ fine("精品", ...

  7. java枚举类

    enum关键字用于定义枚举类,若枚举只有一个成员, 则可以作为一种单例模式的实现方式.   枚举类对象的属性不应允许被改动, 所以应该使用 private final 修饰. 枚举类的使用 priva ...

  8. Java语法基础学习DayThirteen(枚举类和注解)

    一.枚举类 1.概述:即一个类中只能有有限个对象,若只有一个对象,则可以作为单例模式的一种实现. 2.自定义枚举类(JDK1.5以前这么做) //枚举类 class Season{ //1.提供类的属 ...

  9. 第8章 枚举类&注解

    8.枚举及注解 8.1 如何自定义枚举类 1课时 8.2 如何使用关键字enum定义枚举类 1课时 8.3 枚举类的主要方法 1课时 8.4 实现接口的枚举类 1课时 8-1 枚举类 枚举类入门 枚举 ...

随机推荐

  1. 【转】logback logback.xml常用配置详解(二)<appender>

    原创文章,转载请指明出处:http://aub.iteye.com/blog/1101260, 尊重他人即尊重自己 详细整理了logback常用配置, 不是官网手册的翻译版,而是使用总结,旨在更快更透 ...

  2. 【emWin】例程八:绘制位图

    实验指导书及代码包下载: 链接:http://pan.baidu.com/s/1bpeMYpp 密码:wgtp 实验现象:

  3. spring的显示装配bean(1)------通过XML文件装配

    1:spring环境的简单搭建 (1)导入spring相关的jar包. 2:准备要进行装配的Java类 这里给出两个举例类 (1) (2) 3:配置XML文件 (1)在配置文件的顶部声明多个XML模式 ...

  4. Git系列教程二 基础介绍

    一.存储方式 如果让我们设计一个版本控制系统,最简单的方式就是每做一次更改就生成一个新的文件. 这样的方式太占用空间,所以传统的版本控制系统都是保存一个文件的某个版本的全部内容以及其他版本相对于这个版 ...

  5. Neil·Zou 语录二

    1 “Later equals never !”LeBlanc法则   2 爱情使人忘记时间,时间也会使人忘记爱情,不要让太多的昨天占据你的今天,请相信:是你的不管你怎样任性他都不会离开你:失去的其实 ...

  6. MVC中使用EF的技巧集

    1.从数据库生成模型后,再次更新模型时,之前设置的验证规则会丢失. 解决方法:在Models文件夹中新建一个空白类,把它命名为shujuyanzh.cs(类名可以自定),然后把Models中自动生成的 ...

  7. python类型转换

    1.数字转字符串 str(42) == "42" 2.字符串转数字 int("42") == 42 3.字符转ascii码 ord("a") ...

  8. 常用数据库的驱动程序及JDBC URL:

    Oracle数据库: 驱动程序包名:ojdbc14.jar 驱动类的名字:oracle.jdbc.driver.OracleDriver JDBC URL:jdbc:oracle:thin:@dbip ...

  9. android必须要进行为不同分辨率设备切图

    以分辨率为1920×1080的android设备为例.在项目中加载资源的位置为xxhdpi文件夹: 例如将图片放入mdpi文件夹中就会出现,图片的横纵尺寸分别乘3被的后果,因为它认为在这个文件夹中是低 ...

  10. android studio 2.0 GPU Debugger使用说明

    GPU Debugger GPU Debugging Tools The GPU debugging tools are an experimental feature intended to hel ...