kaka的gravatar头像
kaka 2017-05-26 09:47:00
java枚举常量、int类型的日期、Date类型的日期可视化转换

在项目开发中,展示的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<Integer>  {
    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<String,Object> map = new HashMap<String,Object>();
                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<OrderTypeEnum> 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已经被自动转化成可视化的展示方式了。

java枚举常量、int类型的日期、Date类型的日期可视化转换

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<Integer> {


    @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 millions=new Long(date)*1000;
		return new DateTime(millions).toString("yyyy-MM-dd HH:mm:ss");
	}

定义JsonIntDateFormat

package 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:

       <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.5.1</version>
        </dependency>

打赏

已有1人打赏

dmzhjg的gravatar头像
最近浏览
拾光979  LV11 2020年5月18日
你的小可爱666  LV1 2019年11月3日
PalyBoy  LV9 2019年10月18日
SCAUHilbert  LV1 2019年7月23日
zh88781 2019年6月19日
暂无贡献等级
茫茫人海中的小牛  LV10 2019年2月20日
liusansan  LV11 2018年10月20日
wujiawei0926 2018年6月5日
暂无贡献等级
梦醒繁华丶  LV19 2018年4月26日
微微上翘  LV23 2018年2月26日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友