将Bean转换为Json形式的一个工具类
这边遇到一个问题:
1.做一个bean类,实现一个函数,能够把bean生成json字符串。按字段作为key,字段值作为value的方式生成,并且按key的ascii码的升序生成。
2.提示:bean的字段可以是基本类型(int,long,boolean...),或长用的类类型(Integer,String,Date,ArrayList...)或自己定义的bean对象类型或bean对象类型的数组, ArrayList中也可能包含bean对象类型。可能用的SortMap,接口,反射,递归调用等相关知识
参考了一下别人的博客:链接
但是其中涉及一个问题,就是无法对数组类型的进行转换,当涉及到数组类型的值得时候就会出错,另外原文没有针对ascii进行排序
之后修改之后代码如下,涉及到一些递归的知识以及反射的知识
package com.shenshang.demo.Demo;
import java.lang.reflect.Field;
import java.util.*;
import static jdk.nashorn.internal.runtime.regexp.joni.Config.DEBUG;
/**
* ClassName: BeanToJsonUtil
* Description:
* date: 2019/1/25 11:22
*
* @author tangtang
* @version 1.0
* @since JDK 1.8
*/
public class BeanToJsonUtil {
//需要解决的问题
//1.怎么获取字段名,怎么获取字段的值
//2.怎么判断是基本类型,基本类型的值,不需要加隐含
//3.怎么判断是常用的类型,如果是常用类型里面的集合话,需要递归判断
//4.如何判断是自定义的bean对象 如果是自定义的bean对象,需要再次进行解析,
//5.数组的话,需要遍历展示
//6.将key按照ascii码升序排列
//修改部分:原文存在bug.当类型为数组类型的时候,会出现问题, 以修正为需要的逻辑
public static <T> String toJson(T t) {
if (t == null) {
return "{}";
}
return beanToJson(t);
}
public static <T> String beanToJson(T t) {
//先获取所有字段名
Field[] fields = t.getClass().getDeclaredFields();
String[] keys = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
keys[i] = fields[i].getName();
}
//获取按照Ascii排序之后的顺序
keys = getUrlParam(keys);
StringBuilder sb = new StringBuilder();
sb.append("{");
Map<String, Field> map = new HashMap<>();
for (int i = 0; i < keys.length; i++) {
for (Field field : fields) {
if (field.getName().equals(keys[i])) {
map.put(keys[i], field);
// 当方法名满足键值得时候结束当前层循环
continue;
}
}
}
for (String name : keys) {
Field field = map.get(name);
field.setAccessible(true);
Class<?> type = field.getType();
Object value = null;
try {
value = field.get(t);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
// 内部类的外部类引用(指针)字段
if (name.contains("this$")) {
continue;
}
String typeName = type.getName();
if (typeName.equals("java.lang.String")) {
try {
sb.append("\"" + name + "\":");
sb.append(stringToJson((String) field.get(t)));
sb.append(",");
} catch (Exception e) {
if (DEBUG) {
e.printStackTrace();
}
}
} else if (typeName.equals("boolean") ||
typeName.equals("java.lang.Boolean") ||
typeName.equals("int") ||
typeName.equals("java.lang.Integer") ||
typeName.equals("float") ||
typeName.equals("java.lang.Float") ||
typeName.equals("double") ||
typeName.equals("java.lang.Double") ||
typeName.equals("long") ||
typeName.equals("java.lang.Long")) {
try {
sb.append("\"" + name + "\":");
sb.append(field.get(t));
sb.append(",");
} catch (Exception e) {
if (DEBUG) {
e.printStackTrace();
}
}
} else if (typeName.equals("java.util.List") ||
typeName.equals("java.util.ArrayList")) {
try {
List<?> objList = (List<?>) field.get(t);
if (null != objList && objList.size() > 0) {
sb.append("\"" + name + "\":");
sb.append("[");
String toJson = listToJson((List<?>) field.get(t));
sb.append(toJson);
sb.setCharAt(sb.length() - 1, ']');
sb.append(",");
}
} catch (Exception e) {
if (DEBUG) {
e.printStackTrace();
}
}
} else if (value.getClass().isArray()) {
Object[] arr = (Object[]) value; // 装换成数组
List list = Arrays.asList(arr);
try {
if (null != list && list.size() > 0) {
sb.append("\"" + name + "\":");
sb.append("[");
String toJson = listToJson(list);
sb.append(toJson);
sb.setCharAt(sb.length() - 1, ']');
sb.append(",");
}
} catch (Exception e) {
if (DEBUG) {
e.printStackTrace();
}
}
} else {
try {
sb.append("\"" + name + "\":");
sb.append("{");
sb.append(beanToJson(field.get(t)));
sb.setCharAt(sb.length() - 1, '}');
sb.append(",");
} catch (Exception e) {
if (DEBUG) {
e.printStackTrace();
}
}
}
}
if (sb.length() == 1) {
sb.append("}");
}
sb.setCharAt(sb.length() - 1, '}');
return sb.toString();
}
/**
* 将 List 对象编码为 JSON格式
*
* @param objList 待封装的对象集合
* @return String:封装后JSONArray String格式
* @version 1.0
*/
private static <T> String listToJson(List<T> objList) {
final StringBuilder sb = new StringBuilder();
for (T t : objList) {
if (t instanceof String) {
sb.append(stringToJson((String) t));
sb.append(",");
} else if (t instanceof Boolean ||
t instanceof Integer ||
t instanceof Float ||
t instanceof Double) {
sb.append(t);
sb.append(",");
} else {
sb.append(beanToJson(t));
sb.append(",");
}
}
return sb.toString();
}
/**
* 将 String 对象编码为 JSON格式,只需处理好特殊字符
*
* @param str String 对象
* @return String:JSON格式
* @version 1.0
*/
private static String stringToJson(final String str) {
if (str == null || str.length() == 0) {
return "\"\"";
}
final StringBuilder sb = new StringBuilder();
sb.append('\"');
for (int i = 0; i < str.length(); i++) {
final char c = str.charAt(i);
sb.append(c == '\"' ? "\\\"" : c == '\\' ? "\\\\"
: c == '/' ? "\\/" : c == '\b' ? "\\b" : c == '\f' ? "\\f"
: c == '\n' ? "\\n" : c == '\r' ? "\\r"
: c == '\t' ? "\\t" : c + "");
}
sb.append('\"');
return sb.toString();
}
/**
* 对字符串数组进行排序
*
* @param keys
* @return
*/
private static String[] getUrlParam(String[] keys) {
for (int i = 0; i < keys.length - 1; i++) {
for (int j = 0; j < keys.length - i - 1; j++) {
String pre = keys[j];
String next = keys[j + 1];
if (isMoreThan(pre, next)) {
String temp = pre;
keys[j] = next;
keys[j + 1] = temp;
}
}
}
return keys;
}
/**
* 比较两个字符串的大小,按字母的ASCII码比较
*
* @param pre
* @param next
* @return
*/
private static boolean isMoreThan(String pre, String next) {
if (null == pre || null == next || "".equals(pre) || "".equals(next)) {
return false;
}
char[] c_pre = pre.toCharArray();
char[] c_next = next.toCharArray();
int minSize = Math.min(c_pre.length, c_next.length);
for (int i = 0; i < minSize; i++) {
if ((int) c_pre[i] > (int) c_next[i]) {
return true;
} else if ((int) c_pre[i] < (int) c_next[i]) {
return false;
}
}
if (c_pre.length > c_next.length) {
return true;
}
return false;
}
}
运行效果图如下:
将Bean转换为Json形式的一个工具类的更多相关文章
- java中使用反射做一个工具类,来为指定类中的成员变量进行赋值操作,使用与多个类对象的成员变量的赋值。
//------------------------------------------------我是代码的分割线 // 首选是一个工具类,在该工具类里面,定义了一个方法,public void s ...
- 通过一个工具类更深入理解动态代理和Threadlocal
动态代理和Threadlocal 一个代理类返回指定的接口,将方法调用指定的调用处理程序的代理类的实例.返回的是一个代理类,由指定的类装载器的定义和实现指定接口指定代理实例调用处理程序最近用到一个工具 ...
- 用Java开发一个工具类,提供似于js中eval函数功能的eval方法
今天在看到<Java疯狂讲义>中一个章节习题: 开发一个工具类,该工具类提供一个eval()方法,实现JavaScript中eval()函数的功能--可以动态运行一行或多行程序代码.例如: ...
- JSON转换的原创工具类
进来在项目中总是遇到ArrayList线性表需要转化成JSONArray的场景,或者Java对象和JSON字符串之间的转化问题,于是乎自己写了一个粗糙的工具类,经过初步的测试,暂时还未发现什么bug, ...
- json数据与Gson工具类的使用
JS中使用JSON JSON对象 --> JSON字符串:JSON.stringify(对象) JSON字符串 --> JSON对象:JSON.parse(JSON字符串) <scr ...
- JDBC的增删改写成一个方法,调用一个工具类
package com.hx.jdbc.connection; import java.sql.Connection; import java.sql.Statement; import com.my ...
- Jackson 对象与json数据互转工具类JacksonUtil
1,User对象 package com.st.json; import java.util.Date; /** * @Description: JSON序列化和反序列化使用的User类 * @aut ...
- json转字符串,json转list,json转pojo的工具类
package com.loveshop.util; import java.util.List; import com.fasterxml.jackson.core.JsonProcessingEx ...
- C# Json 序列化和反序列化 工具类 Newtonsoft.Json.dll
引用: Newtonsoft.Json.dll // 引用: using Newtonsoft.Json; using Newtonsoft.Json.Converters; // 定义 实体测试类 ...
随机推荐
- python网络爬虫(8)多媒体文件抽取
目的 批量下载网页图片 导入库 urllib中的request中的urlretrieve方法,可以下载图片 lxml用于解析网页 requests用于获取网站信息 import urllib from ...
- 多线程编程-- part 9 信号量:Semaphore
Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可:当信号量 ...
- Nginx安装目录详解
Nginx安装目录详解 1. 查看有关nginx的所有目录列表,输入命令 rpm -ql nginx 可以查看有关nginx目录信息,但是注意 这种命令只能是在基于yum安装的方式才可以. 2. 下 ...
- 获取图书isbn信息 共享图书开发 图书信息接口开发过程中的心得体会
最近做一个图书共享的项目,需要用户扫一扫书籍后面的一维码,获取到书籍的isbn号码,然后通过这个isbn号码能够直接获取到这本书的名字.简介.价格.图片等信息. 于是百度搜了下,之前很多的豆瓣的接口, ...
- windows环境变量和相关命令操作
1.很多程序在windows上运行都需要设置环境变量. 2.具体步骤 复制路径 打开系统设置 高级系统设置 环境变量 设置path 重启cmd 3.可以把路径设置成变量,这样就不用随时 改path而是 ...
- mysql 存储过程(二)
存储过程(Stored Procedure): 一组可编程的函数,是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行. 优点(为什 ...
- 【AGC005 F】Many Easy Problems
神他吗一天考一道码农题两道 FFT(其实还是我推式子一窍不通) 题意 给你一棵 \(n\) 个点的树,再给你一个常数 \(k\). 设 \(S\) 为树上某些点的集合,定义 \(f(S)\) 为最小的 ...
- 【NOI 2019】同步赛 / 题解 / 感想
非常颓写不动题怎么办…… 写下这篇博客警示自己吧…… 游记 7.16 我并不在广二参加 NOI,而是在距离广二体育馆一公里远的包间打同步赛(其实就是给写不动题找个理由) 上午身体不舒服,鸽了半天才看题 ...
- Angular2 父子组件通信方式
https://www.jb51.net/article/133868.htm 这次给大家带来Angular2 父子组件通信方式,使用Angular2 父子组件通信方式的注意事项有哪些,下面就是实战案 ...
- 用Python实现九九乘法表打印
#!usr/bin/env python # -*- coding:utf-8 -*- # dic={ # 'apple':10, # 'iphon':5000, # 'wwatch Tv':3000 ...