在项目开发中,展示的VO通过Spring MVC序列化后展示给前端,这种方式很常见,但是我们项目中有时会定义很多枚举类,这些枚举类的值是int类型的值存入库中,或者表中的时间类型是int类型或者Date类型,需要转化成可视化的string类型展示到页面上,通常的做法是对这些枚举常量或者时间类型的字段进行逐个转意,这样做不仅多一次遍历,而且重复多了重复的代码工作量。下面提供一些工具类来简化这些多余的操作。

1.枚举类型可视化转换

对于枚举类型,必须继承apache的ValuedEnum这个类org.apache.commons.lang.enums.ValuedEnum

定义JsonViewValueEnum类import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.apache.commons.lang.enums.ValuedEnum;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@JacksonAnnotationsInside
@JsonSerialize(using = JsonViewValueEnumSerializer.class)
public @interface JsonViewValueEnum {
/**
* 所有集成valueenum
* @return
*/
Class extends ValuedEnum> value();
/**
* 显示json的格式
* string 则为单字符
* jsonobj 为 {name:'',value:''}
*
*
{
"kaka": {
"name": "kaka",
"value": 0
},
"kakaName": "kaka"
}
* @return
*/
JsonType jsontype() default JsonType.string;
enum JsonType {
string,
jsonobj
}
}
定义常量解析序列化类import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.enums.ValuedEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* 常量解析序列化
*
*/
public class JsonViewValueEnumSerializer extends JsonSerializer {
private final Logger log = LoggerFactory.getLogger(JsonViewValueEnumSerializer.class);
@Override
public void serialize(Integer value, JsonGenerator gen, SerializerProvider serializers) throws IOException{
if(null!=value){
Object currentValue = gen.getCurrentValue();
String currentName = gen.getOutputContext().getCurrentName();
try {
Field declaredField = currentValue.getClass().getDeclaredField(currentName);
JsonViewValueEnum annotation = declaredField.getAnnotation(JsonViewValueEnum.class);
//获取对应的常量的名称
String name = jsonNameValue(value,annotation);
//根据注解类型判断输出格式
jsonGeneratorwrite(name,value,annotation,gen);
} catch (NoSuchFieldException e) {
e.printStackTrace();
log.error("JsonViewValueEnumSerializer序列化异常",e);
} catch (IllegalAccessException e) {
log.error("JsonViewValueEnumSerializer序列化异常",e);
e.printStackTrace();
}
}else {
gen.writeString("");
}
}
private void jsonGeneratorwrite(String name, Integer value, JsonViewValueEnum annotation, JsonGenerator gen) throws IOException {
JsonViewValueEnum.JsonType jsontype = annotation.jsontype();
if(jsontype==JsonViewValueEnum.JsonType.jsonobj){
if(StringUtils.isNotEmpty(name)){
Map map = new HashMap();
map.put("name",name);
map.put("value",value);
gen.writeObject(map);
}else{
gen.writeString(name);
}
}else {
gen.writeString(name);
}
}
private String jsonNameValue(Integer value, JsonViewValueEnum annotation) throws NoSuchFieldException, IllegalAccessException {
Class extends ValuedEnum> valueenum = annotation.value();
Field[] declaredFields = valueenum.getFields();
String name="";
if(null!=declaredFields && declaredFields.length>0){
for (Field field : declaredFields) {
ValuedEnum v = (ValuedEnum)field.get(valueenum);
if(v.getValue() == value){
name = v.getName();
break;
}
}
}
return name;
}
}
以上这两个类就可以搞定枚举类常量的可视化转换了,举个例子,定义如下常量/**
* Created by kaka on 2017/5/25.
*/
import org.apache.commons.lang.enums.ValuedEnum;
import java.util.List;
/**
* 测试枚举
*
* @author kaka
* @create 2017-05-25 10:24
**/
public class OrderTypeEnum extends ValuedEnum {
/**
* Constructor for enum item.
*
* @param name the name of enum item
* @param value the value of enum item
*/
protected OrderTypeEnum(String name, int value) {
super(name, value);
}
private static final Integer incidentWorkFlow = 0;//事件流程
private static final Integer problemWorkFlow = 1;//问题流程
private static final Integer changeWorkFlow = 2;//变更流程
private static final Integer releaseWorkFlow = 3;//发布流程
public static final OrderTypeEnum INCIDENT_ORDER = new OrderTypeEnum( "事件工单", incidentWorkFlow );
public static final OrderTypeEnum PROBLEM_ORDER = new OrderTypeEnum( "问题工单", problemWorkFlow );
public static final OrderTypeEnum CHANGE_ORDER = new OrderTypeEnum( "变更工单", changeWorkFlow );
public static final OrderTypeEnum PUBLISH_ORDER = new OrderTypeEnum( "发布工单", releaseWorkFlow );
public static OrderTypeEnum getEnum(String type ) {
return (OrderTypeEnum)getEnum( OrderTypeEnum.class, type );
}
public static OrderTypeEnum getEnum(int type ) {
return (OrderTypeEnum)getEnum( OrderTypeEnum.class, type );
}
public static List getWorkFlowEnumList(){
return getEnumList(OrderTypeEnum.class);
}
}
定义一个测试demo,需要转意的常量上面添加 @JsonViewValueEnum(OrderTypeEnum.class),OrderTypeEnum为需要转意的枚举类/**
* Created by kaka on 2017/5/25.
*/
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author kaka
* @create 2017-05-25 10:35
**/
public class DemoVo {
@JsonViewValueEnum(OrderTypeEnum.class)
private Integer orderType;
private String name;
public Integer getOrderType() {
return orderType;
}
public void setOrderType(Integer orderType) {
this.orderType = orderType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) throws Exception{
DemoVo demoVo = new DemoVo();
demoVo.setName("kaka");
demoVo.setOrderType(1);
ObjectMapper objectMapper = new ObjectMapper();
System.out.println(objectMapper.writeValueAsString(demoVo));
}
}
运行结果:可以看出orderType已经被自动转化成可视化的展示方式了。
2.int类型的日期可视化转换
定义JsonIntDateFormatSerializer 用于序列化package com.suninfo.util.annotation;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.suninfo.util.date.DateUtil;
import java.io.IOException;
/**
* int类型日期 转为换 yyyy-MM-dd hh:mm:ss
*
*/
public class JsonIntDateFormatSerializer extends JsonSerializer {
@Override
public void serialize(Integer value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if(null!=value){
gen.writeString(DateUtil.intToStringDate(value));
}else {
gen.writeString("");
}
}
}
DateUtil是我自定义的一个类,贴出intToStringDate方法/**
* @author:kaka
* @time:2017年2月21日下午4:35:05
* @return:String
* @param date
* @describe:int格式时间 转换为String(yyy-MM-dd HH:mm:ss)时间格式
*/
public static String intToStringDate( int date ) {
long millinotallow=new Long(date)*1000;
return new DateTime(millions).toString("yyyy-MM-dd HH:mm:ss");
}
定义JsonIntDateFormatpackage com.suninfo.util.annotation;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用于前端显示int类型日期
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@JacksonAnnotationsInside
@JsonSerialize(using = JsonIntDateFormatSerializer.class)
public @interface JsonIntDateFormat {
}
使用方式和上面demo类似,直接在要转化的字段上@JsonIntDateFormat
3.Date类型的日期可视化转换
直接使用com.fasterxml.jackson.annotation.JsonFormat这个注解去做
使用方式如下:@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date claimTime;//任务领取时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date createTime;//任务创建时间
以上需要的pom:
com.fasterxml.jackson.core
jackson-core
2.5.1
com.fasterxml.jackson.core
jackson-annotations
2.5.1
com.fasterxml.jackson.core
jackson-databind
2.5.1