1 FastJson
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>x.x.x</version></dependency>
kimmking:JSON Best Practice(最佳实践)
1.1 SerializerFeature属性
| 名称 | 含义 | 备注 |
|---|---|---|
| QuoteFieldNames | 输出key时是否使用双引号,默认为true | |
| UseSingleQuotes | 使用单引号而不是双引号,默认为false | |
| WriteMapNullValue | 是否输出值为null的字段,默认为false | |
| WriteEnumUsingToString | Enum输出name()或者original,默认为false | |
| UseISO8601DateFormat | Date使用ISO8601格式输出,默认为false | |
| WriteNullListAsEmpty | List字段如果为null,输出为[],而非null | |
| WriteNullStringAsEmpty | 字符类型字段如果为null,输出为”“,而非null | |
| WriteNullNumberAsZero | 数值字段如果为null,输出为0,而非null | |
| WriteNullBooleanAsFalse | Boolean字段如果为null,输出为false,而非null | |
| SkipTransientField | 如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true | |
| SortField | 按字段名称排序后输出。默认为false | |
| WriteTabAsSpecial | 把\t做转义输出,默认为false | 不推荐 |
| PrettyFormat | 结果是否格式化,默认为false | |
| WriteClassName | 序列化时写入类型信息,默认为false。反序列化是需用到 | |
| DisableCircularReferenceDetect | 消除对同一对象循环引用的问题,默认为false | |
| WriteSlashAsSpecial | 对斜杠’/’进行转义 | |
| BrowserCompatible | 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false | |
| WriteDateUseDateFormat | 全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat); | |
| DisableCheckSpecialChar | 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false | |
| NotWriteRootClassName | 含义 | |
| BeanToArray | 将对象转为array输出 | |
| WriteNonStringKeyAsString | 含义 | |
| NotWriteDefaultValue | 含义 | |
| BrowserSecure | 含义 | |
| IgnoreNonFieldGetter | 含义 | |
| WriteEnumUsingName | 含义 |
1.2 $ref 的错误
设置一下序列化特性,DisableCircularReferenceDetect 即可。
2 对象转换(拷贝)
对象转换,都是找到的对应字段的映射关系。这个涉及到字段的类型,字段访问权限(private、protected等) ,特殊类型(日期等);
另外一点,就是深拷贝,浅拷贝问题,不同的转换采取的方式不同。
2.1 org.apache.commons.beanutils.PropertyUtils
http://commons.apache.org/proper/commons-beanutils/
2.2 org.springframework.beans.BeanUtils
2.3 Bull(Bean Utils Light Library)
https://github.com/ExpediaGroup/bull
2.4 Dozer
<dependency><groupId>net.sf.dozer</groupId><artifactId>dozer</artifactId><version>5.4.0</version></dependency>
2.5 mapstruct
https://github.com/mapstruct/mapstruct/
https://mapstruct.org/
...<properties><org.mapstruct.version>1.4.2.Final</org.mapstruct.version></properties>...<dependencies><dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${org.mapstruct.version}</version></dependency></dependencies>...<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><annotationProcessorPaths><path><groupId>org.mapstruct</groupId><artifactId>mapstruct-processor</artifactId><version>${org.mapstruct.version}</version></path></annotationProcessorPaths></configuration></plugin></plugins></build>...
2.6 Jackson Data Bind
https://github.com/FasterXML/jackson-databind
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency>
2.7 modelmapper
http://modelmapper.org/getting-started/
https://github.com/modelmapper/modelmapper
java 8
<dependency><groupId>org.modelmapper</groupId><artifactId>modelmapper</artifactId><version>2.4.2</version></dependency><dependency><groupId>com.github.jmnarloch</groupId><artifactId>modelmapper-spring-boot-starter</artifactId><version>1.1.0</version></dependency>
modelMapper 主要考虑匹配策略和隐式匹配,不同的规则不同。
3 hutools
| 模块 | 介绍 | 备注 |
|---|---|---|
| hutool-aop | JDK动态代理封装,提供非IOC下的切面支持 | |
| hutool-bloomFilter | 布隆过滤,提供一些Hash算法的布隆过滤 | |
| hutool-cache | 简单缓存实现 | |
| hutool-core | 核心,包括Bean操作、日期、各种Util等 | |
| hutool-cron | 定时任务模块,提供类Crontab表达式的定时任务 | |
| hutool-crypto | 加密解密模块,提供对称、非对称和摘要算法封装 | |
| hutool-db | JDBC封装后的数据操作,基于ActiveRecord思想 | |
| hutool-dfa | 基于DFA模型的多关键字查找 | |
| hutool-extra | 扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等) | |
| hutool-http | 基于HttpUrlConnection的Http客户端封装 | |
| hutool-log | 自动识别日志实现的日志门面 | |
| hutool-script | 脚本执行封装,例如Javascript | 不推荐 |
| hutool-setting | 功能更强大的Setting配置文件和Properties封装 | |
| hutool-system | 系统参数调用封装(JVM信息等) | |
| hutool-json | JSON实现 | |
| hutool-captcha | 图片验证码实现 | |
| hutool-poi | 针对POI中Excel和Word的封装 | |
| hutool-socket | 基于Java的NIO和AIO的Socket封装 | |
| hutool-jwt | JSON Web Token (JWT)封装实现 | |
| NotWriteRootClassName | 含义 | |
| BeanToArray | 将对象转为array输出 | |
| WriteNonStringKeyAsString | 含义 | |
| NotWriteDefaultValue | 含义 | |
| BrowserSecure | 含义 | |
| IgnoreNonFieldGetter | 含义 | |
| WriteEnumUsingName | 含义 |
4 easyExcel
https://github.com/alibaba/easyexcel/
https://www.yuque.com/easyexcel/doc/easyexcel
https://alibaba-easyexcel.github.io/
5 spring 内置的工具类
主要是 spring-boot-starter 中的
https://spring.io/blog/2021/01/27/ymnnalft-the-spring-utils-classes
package bootiful.utils;import lombok.AllArgsConstructor;import lombok.Data;import lombok.extern.log4j.Log4j2;import org.springframework.aop.support.AopUtils;import org.springframework.beans.BeanUtils;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.boot.context.event.ApplicationReadyEvent;import org.springframework.context.ApplicationListener;import org.springframework.context.annotation.Bean;import org.springframework.core.ResolvableType;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;import org.springframework.jmx.support.JmxUtils;import org.springframework.stereotype.Component;import org.springframework.util.*;import javax.annotation.PostConstruct;import java.beans.PropertyDescriptor;import java.io.InputStreamReader;import java.io.Reader;import java.io.Serializable;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.util.*;@Log4j2@SpringBootApplicationpublic class BootifulApplication {@Data@AllArgsConstructor@Componentpublic static class DemoClass {@PostConstructpublic void begin() {log.info("begin()");}private final List<Map<String, Object>> list = new ArrayList<>();}@BeanApplicationListener<ApplicationReadyEvent> ready(DemoClass demo) {return event -> {Assert.notNull(demo.getList(), "the list can't be null");beansUtils(demo);classUtils();systemPropertyUtils();fileCopyUtils();aop(demo);reflection();ensure();collections();serialize();};}private void ensure() {int counter = 2;Assert.state(counter == 2, () -> "the counter should be 2 or more. Was " + counter);Assert.hasText("Hello, world!", () -> "this string should be a non-null, non-empty String");}private void reflection() {ReflectionUtils.doWithFields(DemoClass.class, field -> log.info("field = " + field.toString()));ReflectionUtils.doWithMethods(DemoClass.class, method -> log.info("method = " + method.toString()));Field list = ReflectionUtils.findField(DemoClass.class, "list");log.info(Objects.requireNonNull(list).toString());ResolvableType rt = ResolvableType.forField(list);log.info(rt.toString());}private void aop(DemoClass demoClass) {Class<?> targetClass = AopUtils.getTargetClass(demoClass);log.info("Class<?> is " + targetClass);log.info("is AOP proxy? " + AopUtils.isAopProxy(demoClass));log.info("is CGlib proxy? " + AopUtils.isCglibProxy(demoClass));}private void collections() {Collection<String> names = Arrays.asList("Tammie", "Kimly", "Josh");boolean contains = CollectionUtils.containsAny(names, Arrays.asList("Josh"));Assert.state(contains, () -> "one or more of the names in " + names.toString() + " should be present");}private void serialize() {Customer in = new Customer(593232329, "Josh");byte[] bytes = SerializationUtils.serialize(in);Customer out = (Customer) SerializationUtils.deserialize(bytes);Assert.state(out.getId() == in.getId() && out.getName().equals(in.getName()),() -> "the " + Customer.class.getName() + " did not serialize correctlyy");}private void fileCopyUtils() {Resource cpr = new ClassPathResource("/application.properties");try (Reader r = new InputStreamReader(cpr.getInputStream())) {String contents = FileCopyUtils.copyToString(r);log.info("application.properties contents: " + contents);}catch (Exception e) {throw new RuntimeException(e);}}private void systemPropertyUtils() {String resolvedText = SystemPropertyUtils.resolvePlaceholders("my home directory is ${user.home}");log.info("resolved text: " + resolvedText);}private void classUtils() {Constructor<DemoClass> demoClassConstructor = ClassUtils.getConstructorIfAvailable(DemoClass.class);log.info("demoClassConstructor: " + demoClassConstructor);try {DemoClass demoClass = demoClassConstructor.newInstance();log.info("newInstance'd demoClass: " + demoClass);}catch (Exception e) {throw new RuntimeException(e);}}private void beansUtils(DemoClass demo) {PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(demo.getClass());for (PropertyDescriptor pd : descriptors) {log.info("pd: " + pd.getName());}}public static void main(String[] args) {SpringApplication.run(BootifulApplication.class, args);}}@Dataclass Customer implements Serializable {static final long serialVersionUID = 1L;private int id;private String name;public Customer(int id, String name) {this.id = id;this.name = name;}}
相关的工具类:
- BeanUtils - useful functions for dealing with JavaBeans
- ClassUtils - useful functions for asking questions reflectively about types
- SystemPropertyUtils - useful functions for dealing with System properties
- FileCopyUtils - useful functions for copying InputStream and OutputStream implementations
- AopUtils - useful functions for dealing with Spring’s AOP proxies
- ReflectionUtils - useful functions for dealing with reflection, broadly
- Assert - useful functions to help with design-by-contract-style assertions
- CollectionUtils - useful functions for working various Java java.util.Collection types
- SerializeUtils - useful functions for working with Java serialization
