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

    PVOID p = ExAllocatePool(Pool_Type, Size); PVOID p = ExAllocatePoolWithTag(Pool_Type, Size, Tag); 调用 ...

  2. PHP 天巡机票接口

    一个旅游网站项目,网站需要机票预订接入了天巡机票接口,获取机票信息,不搞不知道,一搞吓一跳比较麻烦. 搜索机票信息需要分2步,首先POST获得一个SESSION,2秒之后,根据这个SESSION,从一 ...

  3. java-int类型:int默认为0导致更新操作未赋值的情况下将值更新为0

    日常开发中,做更新操作的时候的处理方法为:当这个字段有值则更新,没有值就不更新,在mybatis的xml中表现为: <!-- 修改记录,只修改只不为空的字段 --> <update ...

  4. 球谐光照(Spherical Harmonics Lighting)及其应用-实验篇

    简介 之前在一篇实时深度图优化的论文中看到球谐光照(Spherical Harmonics Lighting)的应用,在查阅了许许多多资料之后还是无法完全理解,我个人觉得如果之前对实时渲染技术不是很了 ...

  5. HTML5 头部标签定义

    <!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --> <html lang="zh-cmn-Hans"&g ...

  6. 掌握Thinkphp3.2.0----内置标签

    使用内置标签的时候,一定要注意闭合-----单标签自闭合,双标签对应闭合 标签的学习在于记忆和应用 一. 判断比较 //IF 语句的完整格式 <if condition="$user ...

  7. MULTITHREADING AND CHIP MULTIPROCESSORS

    COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION The most important me ...

  8. 一个node项目的框架搭建流程

    项目服务端编程语言node,前端js,数据库mongodb, 开发工具用webstorm. 使用express应用生成器,生成项目雏形. 安装应用生成器工具,命令是npm install expres ...

  9. input range样式更改,模拟滑块

    input range 样式更改,js模拟滑块实时更新数据. 效果图: html 代码: <div> <span class="slider"></s ...

  10. 游记——noip2016

    2016.11.18 (day 0) 呆在家. 悠闲地呆在家.. 明后天可能出现的错误: 1)没打freopen.打了ctime: 2)对拍程序忘记怎么写了...忘记随机化种子怎么写了: 3)不知道厕 ...