springmvc+fastjson enum(枚举)支持属性get转json
maven引用
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
springxml配置
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8" />
</bean>
<bean
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="charset" value="UTF-8" />
<property name="supportedMediaTypes">
<list>
<value>application/json</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
<property name="fastJsonConfig">
<bean class="com.xxx.xxx.CustomerFastJsonConfig">
<property name="serializerFeatures">
<list>
<value>QuoteFieldNames</value>
<value>DisableCircularReferenceDetect</value>
</list>
</property>
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
自定义配置类
public class CustomerFastJsonConfig extends com.alibaba.fastjson.support.config.FastJsonConfig{
@SuppressWarnings("unchecked")
public CustomerFastJsonConfig(){
super();
//获取指定包名下所有的有JsonFormat注解的类,因为这样可以兼容jackson的enum转换
//然后在springmvc转json时,就会把标记有JsonFormat注解的枚举中的get方法转为json格式,当然也可以自定义一个注解
Set<Class<?>> classes = ClassUtil.getClasses("com.xxx.cores.enums", true,JsonFormat.class);
SerializeConfig serializeConfig = getSerializeConfig();
for (Class<?> clazz : classes) {
Class<? extends Enum<?>> eclazz=(Class<? extends Enum<?>>)clazz;
serializeConfig.configEnumAsJavaBean(eclazz);
}
}
}
ClassUtil
package com.xxx.xxx.utils; import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile; import org.apache.commons.lang3.ClassUtils; import com.fasterxml.jackson.annotation.JsonFormat; public class ClassUtil extends ClassUtils{ /**
* 是否有注解
*
* @param clazz
* a {@link java.lang.Class} object.
* @param annotationClass
* a {@link java.lang.Class} object.
* @return a boolean.
*/
public static boolean hasClassAnnotation(Class<?> clazz, Class<? extends Annotation> annotationClass) {
return getClassAnnotation(clazz, annotationClass) != null;
} /**
* 获取类注解
*
* @param clazz
* 类
* @param annotationClass
* 注解类
* @return a A object.
*/
public static <A extends Annotation> A getClassAnnotation(Class<?> clazz, Class<A> annotationClass) {
return clazz.getAnnotation(annotationClass);
} /**
* 从包package中获取所有的Class
*
* @param pagekageName
* 包名
* @param recursive
* 是否递归
* @param annotationClass 不为null时,取存在注解的类
* @return a {@link java.util.Set} object.
*/
public static Set<Class<?>> getClasses(String pagekageName, boolean recursive, Class<? extends Annotation> annotationClass) {
// 第一个class类的集合
Set<Class<?>> classes = new LinkedHashSet<Class<?>>();
// 获取包的名字 并进行替换
String packageName = pagekageName;
String packageDirName = packageName.replace('.', '/');
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
Enumeration<URL> dirs;
try {
dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
// 循环迭代下去
while (dirs.hasMoreElements()) {
// 获取下一个元素
URL url = dirs.nextElement();
// 得到协议的名称
String protocol = url.getProtocol();
// 如果是以文件的形式保存在服务器上
if ("file".equals(protocol)) {
// 获取包的物理路径
String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
// 以文件的方式扫描整个包下的文件 并添加到集合中
findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes,annotationClass);
} else if ("jar".equals(protocol)) {
// 如果是jar包文件
// 定义一个JarFile
JarFile jar;
try {
// 获取jar
jar = ((JarURLConnection) url.openConnection()).getJarFile();
// 从此jar包 得到一个枚举类
Enumeration<JarEntry> entries = jar.entries();
// 同样的进行循环迭代
while (entries.hasMoreElements()) {
// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
JarEntry entry = entries.nextElement();
String name = entry.getName();
// 如果是以/开头的
if (name.charAt(0) == '/') {
// 获取后面的字符串
name = name.substring(1);
}
// 如果前半部分和定义的包名相同
if (name.startsWith(packageDirName)) {
int idx = name.lastIndexOf('/');
// 如果以"/"结尾 是一个包
if (idx != -1) {
// 获取包名 把"/"替换成"."
packageName = name.substring(0, idx)
.replace('/', '.');
}
// 如果可以迭代下去 并且是一个包
if ((idx != -1) || recursive) {
// 如果是一个.class文件 而且不是目录
if (name.endsWith(".class") && !entry.isDirectory()) {
// 去掉后面的".class" 获取真正的类名
String className = name.substring(packageName.length() + 1, name.length() - 6);
try {
// 添加到classes
Class<?> forName = Class.forName(packageName + '.' + className);
if(annotationClass!=null) {
if(forName.getAnnotation(annotationClass)!=null) {
classes.add(forName);
}
}else {
classes.add(forName);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
// log
// .error("添加用户自定义视图类错误 找不到此类的.class文件");
}
}
}
}
}
} catch (IOException e) {
// log.error("在扫描用户定义视图时从jar包获取文件出错");
throw new RuntimeException(e);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} return classes;
} /**
* 以文件的形式来获取包下的所有Class
*
* @param packageName
* a {@link java.lang.String} object.
* @param packagePath
* a {@link java.lang.String} object.
* @param recursive
* a boolean.
* @param classes
* a {@link java.util.Set} object.
*/
public static void findAndAddClassesInPackageByFile(String packageName,
String packagePath, final boolean recursive, Set<Class<?>> classes, Class<? extends Annotation> annotationClass) {
// 获取此包的目录 建立一个File
File dir = new File(packagePath);
// 如果不存在或者 也不是目录就直接返回
if (!dir.exists() || !dir.isDirectory()) {
// log.warn("用户定义包名 " + packageName + " 下没有任何文件");
return;
}
// 如果存在 就获取包下的所有文件 包括目录
File[] dirfiles = dir.listFiles(new FileFilter() {
// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
public boolean accept(File file) {
return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
}
});
// 循环所有文件
for (File file : dirfiles) {
// 如果是目录 则继续扫描
if (file.isDirectory()) {
findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes,annotationClass);
} else {
// 如果是java类文件 去掉后面的.class 只留下类名
String className = file.getName().substring(0, file.getName().length() - 6);
try {
// 添加到集合中去
Class<?> forName = Class.forName(packageName + '.' + className);
if(annotationClass!=null) {
if(forName.getAnnotation(annotationClass)!=null) {
classes.add(forName);
}
}else {
classes.add(forName);
}
} catch (ClassNotFoundException e) {
// log.error("添加用户自定义视图类错误 找不到此类的.class文件");
e.printStackTrace();
}
}
}
} public static void main(String[] args) {
Set<Class<?>> classes = getClasses("com.xxx.cores.enums", true,JsonFormat.class);
System.out.println(classes.size());
for (Class<?> class1 : classes) {
System.out.println(class1.getName());
}
}
}
枚举定义
package com.xxx.xxx.enums.community;/**
*
* @Description:文件类型
* @author:xxx
* @date:2017年7月8日 上午11:57:37
*/
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum FileType {
VIDEO("视频"),
IMAGE("图片")
;
private FileType(String displayName) {
this.displayName = displayName;
} private String displayName; public String getDisplayName() {
return displayName;
} public String getCode(){
return this.name();
} public void setDisplayName(String displayName) {
this.displayName = displayName;
}
}
输出结果
//FileType.IMAGE
{"code":"IMAGE","displayName":"图片"}
springmvc+fastjson enum(枚举)支持属性get转json的更多相关文章
- 怎样让enum枚举支持string
原文发布时间为:2011-03-02 -- 来源于本人的百度文章 [由搬家工具导入] 大家都知道enum是以下两种情况,不能支持string 1,enum类型是静态 2,enum类型仅限于long、i ...
- MVC3不能正确识别JSON中的Enum枚举值
一.背景 在MVC3项目里,如果Action的参数中有Enum枚举作为对象属性的话,使用POST方法提交过来的JSON数据中的枚举值却无法正确被识别对应的枚举值. 二.Demo演示 为了说明问题,我使 ...
- 读书笔记 enum枚举之位标志属性(Flags)浅析
针对enum枚举来说,可以定义位标志属性,从而使该枚举类型的实例可以存储枚举列表中定义值的任意组合.可以用 与(&).或(|).异或(^)进行相应的运算.废话不多说,代码最直接. //每一个定 ...
- 1.0 基础、标示符、常量、数据类型(enum 枚举,struct 结构体)、操作符、循环、数组
一.程序 现实生活中,程序是指完成某些事务的一种既定方法和过程,可以把程序看成是一系列动作执行过程的描述. 在计算机世界,程序是指令,即为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集 ...
- 获取Enum枚举值描述的几法方法
原文:获取Enum枚举值描述的几法方法 1.定义枚举时直接用中文 由于VS对中文支持的很不错,所以很多程序员都采用了此方案. 缺点:1.不适合多语言 2.感觉不太完美,毕竟大部分程序员大部分代码都使用 ...
- Swift Enum 枚举
前言 枚举是一种自定义的数据类型,在 Swift 中枚举类型拥有相当高的自由度.在 Swift 语言中枚举是一级类型,它拥有在其他语言中只有类才拥有的一些特性,比如实例方法,实例构造器等. 枚举声明的 ...
- 集合 enum 枚举 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Python3标准库:enum枚举
1. enum枚举 枚举是一组符号名称(枚举成员)的集合,枚举成员应该是唯一的.不可变的.在枚举中,可以对成员进行恒等比较,并且枚举本身是可迭代的. 1.1 创建枚举 可以使用class语法派生Enu ...
- Java实用类-Enum(枚举)
1. 历史 在 JDK 1.5 之前没有枚举类型,那时候一般用接口常量来替代(例如,public static final String male ).JKD1.5之后使用 Java 枚举类型 e ...
随机推荐
- python tips:列表推导
看一个代码: a=[1,2,3,4,5,6,7,8,9] b=[5 if (i >3) else 1 for i in a] print(b) 这就是列表推导. 列表推导一般用在通过一个list ...
- Python 进阶 之 lambda 匿名函数
lambda 是个匿名函数,通常用于简单判断或者处理,例如判断一个数的奇偶性,过滤字符串,逻辑运算等等. lambda表达式: >>>lambda x:x*x >>> ...
- 更换介质:请把标有…… DVD 的盘片插入驱动器“/media/cdrom/”再按回车键“ 解决方法
https://blog.csdn.net/no7oor/article/details/12776815
- android studio 自定义路径安装报错"You are attempting to install the android SDK
android studio 自定义路径安装报错"You are attempting to install the android SDK 解决方法: 出现这个提示 主要是安装 Andro ...
- 关于存储权限WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE:写入权限 READ_EXTERNAL_STORAGE:读取权限 最近申请存储权限时,在纠结是否需要同时申明WRITE_EXTERNAL_STORAGE 和 ...
- 用 grunt-contrib-connect 构建实时预览开发环境 实时刷新
本文基本是参照着 用Grunt与livereload构建实时预览的开发环境 实操了一遍,直接实现能实时预览文件列表,内容页面.不用刷新页面了,这比以前开发网页程序都简单. 这里要用到的 Grunt 插 ...
- sed replace HEX sequence in your binary file:
Here is how to replace a HEX sequence in your binary file: $ sed 's/\x0D\x4D\x53\x48/\x0D\x0A\x4D\x5 ...
- intellij idea android错误: Missing styles. Is the correct theme chosen for this layout?
Missing styles. Is the correct theme chosen for this layout? Use the Theme combo box above the layou ...
- [JOISC2014]JOIOJI
题目大意: 给你一串仅包含'J''O''I'的字符串,问满足三种字符出现次数相等的最大字串是多少? 思路: 用map存一下出现次数前缀和两两之差出现的最早位置,每次看一下当前的两两之差最早的出现位置是 ...
- XAMPP 下apache部署网站,多个虚拟机(空间)配置
1.首先修改C盘WINDOWS/system32/drivers/etc目录下的 hosts 文件,用记事本打开,加入: 127.0.0.1 www.a.com 127.0.0.1 www.b.com ...