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的更多相关文章

  1. 怎样让enum枚举支持string

    原文发布时间为:2011-03-02 -- 来源于本人的百度文章 [由搬家工具导入] 大家都知道enum是以下两种情况,不能支持string 1,enum类型是静态 2,enum类型仅限于long、i ...

  2. MVC3不能正确识别JSON中的Enum枚举值

    一.背景 在MVC3项目里,如果Action的参数中有Enum枚举作为对象属性的话,使用POST方法提交过来的JSON数据中的枚举值却无法正确被识别对应的枚举值. 二.Demo演示 为了说明问题,我使 ...

  3. 读书笔记 enum枚举之位标志属性(Flags)浅析

    针对enum枚举来说,可以定义位标志属性,从而使该枚举类型的实例可以存储枚举列表中定义值的任意组合.可以用 与(&).或(|).异或(^)进行相应的运算.废话不多说,代码最直接. //每一个定 ...

  4. 1.0 基础、标示符、常量、数据类型(enum 枚举,struct 结构体)、操作符、循环、数组

    一.程序 现实生活中,程序是指完成某些事务的一种既定方法和过程,可以把程序看成是一系列动作执行过程的描述. 在计算机世界,程序是指令,即为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集 ...

  5. 获取Enum枚举值描述的几法方法

    原文:获取Enum枚举值描述的几法方法 1.定义枚举时直接用中文 由于VS对中文支持的很不错,所以很多程序员都采用了此方案. 缺点:1.不适合多语言 2.感觉不太完美,毕竟大部分程序员大部分代码都使用 ...

  6. Swift Enum 枚举

    前言 枚举是一种自定义的数据类型,在 Swift 中枚举类型拥有相当高的自由度.在 Swift 语言中枚举是一级类型,它拥有在其他语言中只有类才拥有的一些特性,比如实例方法,实例构造器等. 枚举声明的 ...

  7. 集合 enum 枚举 简介 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  8. Python3标准库:enum枚举

    1. enum枚举 枚举是一组符号名称(枚举成员)的集合,枚举成员应该是唯一的.不可变的.在枚举中,可以对成员进行恒等比较,并且枚举本身是可迭代的. 1.1 创建枚举 可以使用class语法派生Enu ...

  9. Java实用类-Enum(枚举)

    1. 历史 ​ 在 JDK 1.5 之前没有枚举类型,那时候一般用接口常量来替代(例如,public static final String male ).JKD1.5之后使用 Java 枚举类型 e ...

随机推荐

  1. docker从零开始网络(五)null网络

    禁用容器的网络连接 预计阅读时间: 1分钟 如果要完全禁用容器上的网络堆栈,可以--network none在启动容器时使用该标志.在容器内,仅创建环回设备.以下示例说明了这一点. 1.创建容器. [ ...

  2. pytest学习(2)

    可以把多个test放在一个class里, class TestClass(object): def test_one(self): x = "this" assert 'h' in ...

  3. hdu4240 求一条流量最大的路/(此题网上百分之90以上算法是错误的)

    题意:求最大流/一条流量最大的路的流量.(此题HDU上数据水,下面俩种错误的都能过....) 思路1;每次增广的时候更新流量,保存最大的那条.  错误性:每次更新,有可能最大的那条流量是前几次已经增广 ...

  4. P2819 图的m着色问题

    题目背景 给定无向连通图G和m种不同的颜色.用这些颜色为图G的各顶点着色,每个顶点着一种颜色.如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的.图的m着色问题是对于给定图G和m ...

  5. 51nod 最长公共子序列问题(动态规划)(LCS)(递归)

    最长公共子序列问题 输入 第1行:字符串A 第2行:字符串B (A,B的长度 <= 1000) 输出 输出最长的子序列,如果有多个,随意输出1个. 输入示例 abcicba abdkscab 输 ...

  6. 数据结构-二叉搜索树(BST binary search tree)

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来 ...

  7. 【2-SAT】【并查集】ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) D. The Door Problem

    再来回顾一下2-SAT,把每个点拆点为是和非两个点,如果a能一定推出非b,则a->非b,其他情况同理. 然后跑强连通分量分解,保证a和非a不在同一个分量里面. 这题由于你建完图发现都是双向边,所 ...

  8. 【DFS序】【线段树】bzoj4034 [HAOI2015]T2

    分开维护树的入栈序和出栈序,用两棵线段树.回答时就是用一颗的减去另一棵的. #include<cstdio> #include<algorithm> using namespa ...

  9. 【线性基】【贪心】【独立环】bzoj2115 [Wc2011] Xor

    网上到处都是题解,自己画个图也很好理解.虽然环的个数很多,但是都可以通过独立环之间异或出来,不用管. 独立环求法:生成树之后,每次向图里添加非树边(u,v),则这个独立环的异或和为sum[u]^sum ...

  10. 一个页面如何放多个百度编辑器 Ueditor 1.4.3?PHP如何获取Ueditor 的值?

    问题1:一个页面如何放置多个Ueditor? 参考代码如下: <form  method="post" action="save.php"> < ...