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

    fread是一个函数.从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功返回 0. 函数原型 size_t fread ( void ...

  2. 手机端布局rem 与vm的使用

    手机端原来的时候,在项目中使用js判断出html的字体,然后根据rem设置字体,但是js本着少用的原则,考虑用vm,vh等(顺带说一句,vm vh是网页可视区域宽度 高度 即浏览器宽度减去约16px) ...

  3. union的限制, 临时表大小的优化

  4. Composer 学习笔记

    Composer 是 PHP 的一个依赖管理工具(据说是最优秀的).它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们.目前很多项目以Composer 作为依赖管理工具,目前正在学习yii2 ...

  5. sqlserver 索引的一些总结【转】

    1.1.1 摘要 如果说要对数据库进行优化,我们主要可以通过以下五种方法,对数据库系统进行优化. 1. 计算机硬件调优 2. 应用程序调优 3. 数据库索引优化 4. SQL语句优化 5. 事务处理调 ...

  6. H5 FormData对象的使用

    XMLHttpRequest Level2 添加了一个新的接口--FormData .[ 主要用于发送表单数据,但也可以独立使用于传输键控数据.与普通的Ajax相比,它能异步上传二进制文件 ] 利用F ...

  7. Sqlserver中 登录用户只能看到自己拥有权限的库

    执行之前新建用户时不要赋予任何权限 USE master GO --将所有数据库的查看权限给Public角色,每个登录用户只能查看指定的数据库 --此语句会导致服务器上所有的用户在没有设置数据库权限的 ...

  8. Oracle之nclob类型

    此类型会严重影响查询效率,请少用: nclob字段在查询结果中显示为<NCLOB>,查看nclob类型的值方法有两种 a.可点开...查看具体数据 b.选择所有数据,右击复制到Excel, ...

  9. Netty NIO 框架性能压测-短链接-对比Tomcat

    压测方案 准备多个文件大小分别为 1k 10k 100k 300k 使用ab分别按 [50,2000](按50逐渐叠加)压测服务,每次请求10W次 硬件信息:CPU:Intel(R) Xeon(R) ...

  10. ASP.NET MVC 表单submit()

    HTML代码 <form id="frmLogin"> <div class="form-group has-feedback"> &l ...