原文网址:SpringBoot--手写常用工具类_IT利刃出鞘的博客-CSDN博客
本文介绍我自己手写的一些SpringBoot的工具类,很好用。
说明
可以通过本工具类静态获取ApplicationContext,从而进一步使用ApplicationContext进行处理,比如:从容器中获取bean。
优点
方便快捷,调用者直接使用静态方法即可,调用者无需自己再去实现ApplicationContextAware接口。
相关网址
Spring(SpringBoot)--ApplicationContext--使用/教程/原理_IT利刃出鞘的博客-CSDN博客
代码
package com.knife.common.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
public void setApplicationContext(ApplicationContext context) throws BeansException {
ApplicationContextHolder.context = context;
}
public static ApplicationContext getContext() {
return context;
}
}
用法
说明
本工具是对Jackson(也就是ObjectMapper)的封装。
优点
相关网址
Jackson--使用/教程/示例_IT利刃出鞘的博客-CSDN博客_jackson教程
代码
package com.knife.common.util;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import java.util.Map;
/**
* Json工具
*/
public class JsonUtil {
private static final ObjectMapper objectMapper = new ObjectMapper();
static {
// 反序列化:JSON字段中有Java对象中没有的字段时不报错
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 反序列化:不允许基本类型为null
//objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true);
// 序列化:序列化BigDecimal时不使用科学计数法输出
objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
// 序列化:Java对象为空的字段不拼接JSON
//objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
public static T getObjectFromString(String string, Class cls) {
try {
return objectMapper.readValue(string, cls);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("rawtypes")
public static Map getMapFromString(String str) {
try {
return objectMapper.readValue(str, Map.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static T getMapFromString(String str, TypeReference valueTypeRef) {
try {
return objectMapper.readValue(str, valueTypeRef);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static String getStringFromObject(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static List getObjectListFromString(String string, TypeReference> typeReference) {
try {
return objectMapper.readValue(string, typeReference);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static JsonNode getTreeFromString(String string) {
try {
return objectMapper.readTree(string);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
用法
跟ObjectMapper一样。例如:User user = JsonUtil.getObjectFromString(str, User.class);
说明
可以获得某个对象中值为空(为null或者空字符串等)的属性名,然后可以用于作为BeanUtils.copyProperties的最后一个参数,不拷贝这些空的属性。
优点
方便快捷。
相关网址
Spring--BeanUtils忽略空值拷贝--方法/实例_IT利刃出鞘的博客-CSDN博客_bean拷贝忽略空值
代码
package com.example.util;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyDescriptor;
import java.util.HashSet;
import java.util.Set;
public class PropertyUtil {
public static String[] getNullPropertyNames(Object source) {
BeanWrapper src = new BeanWrapperImpl(source);
PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set emptyNames = new HashSet<>();
for (PropertyDescriptor pd : pds) {
//check if value of this property is null then add it to the collection
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null){
emptyNames.add(pd.getName());
}
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
}
用法
package com.example.controller;
import com.example.entity.Blog;
import com.example.entity.User;
import com.example.util.PropertyUtil;
import com.example.vo.BlogRequest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.Arrays;
@RestController
public class HelloController {
@Autowired
private ObjectMapper objectMapper;
@GetMapping("/test")
public String test() {
BlogRequest blogRequest = new BlogRequest();
blogRequest.setId(10L);
blogRequest.setTitle("Java实战");
// blogRequest.setContent("本文介绍获取null的字段名的方法");
blogRequest.setUser(new User());
blogRequest.setCreateTime(LocalDateTime.now());
// blogRequest.setCreateTime(LocalDateTime.now());
blogRequest.setDeletedFlag(0L);
User user = new User();
user.setId(15L);
user.setUserName("Tony");
// user.setNickName("Iron Man");
// user.setStatus(1);
String[] nullPropertyNames = PropertyUtil.getNullPropertyNames(blogRequest);
System.out.println(Arrays.toString(nullPropertyNames));
System.out.println("------------------------------");
Blog blog = new Blog();
BeanUtils.copyProperties(blogRequest, blog, nullPropertyNames);
try {
System.out.println(objectMapper.writeValueAsString(blog));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return "test success";
}
}
说明
本工具类可以打印详细的异常堆栈的信息。
比如:在抛出NullPointException时,message是这样的:java.lang.NullPointException。用本工具可以获得方法的调用流程,方便排查问题。
优点
异常信息很详细
代码
package com.knife.common.util;
/**
* 异常工具类
*/
public class ThrowableUtil {
/**
* 获取以指定包名为前缀的堆栈信息
*
* @param e 异常
* @return 堆栈信息
*/
public static String getStackTrace(Throwable e) {
StringBuilder s = new StringBuilder().append(e);
for (StackTraceElement traceElement : e.getStackTrace()) {
s.append(" at ").append(traceElement);
}
return s.toString();
}
/**
* 获取以指定包名为前缀的堆栈信息
*
* @param e 异常
* @param packagePrefix 包前缀
* @return 堆栈信息
*/
public static String getStackTraceByPackage(Throwable e, String packagePrefix) {
StringBuilder s = new StringBuilder().append(e);
for (StackTraceElement traceElement : e.getStackTrace()) {
if (!traceElement.getClassName().startsWith(packagePrefix)) {
break;
}
s.append(" at ").append(traceElement);
}
return s.toString();
}
/**
* 获取最后n条堆栈信息
* @param e 异常对象
* @param n 最后n条
* @return 错误信息
*/
public static String getLastStackTrace(Throwable e, Integer n) {
Integer lineNumber = n;
if (lineNumber == null) {
lineNumber = 10;
}
StringBuilder s = new StringBuilder().append(e);
int i = 0;
for (StackTraceElement traceElement : e.getStackTrace()) {
s.append(" at ").append(traceElement);
if (i >= lineNumber) {
break;
}
i++;
}
return s.toString();
}
}
用法
try{
...
} catch(Exception e) {
log.error(ThrowableUtil.getLastStackTrace(e, 10));
}
说明
本工具可以手动对@NotBlank、@NotNull等字段进行校验。
使用场景:controller接口的入参很多,需要他人提供,但他人提供的类的字段很多,字段都没有加@NotNull等注解;而且这个类以后很可能再变动。
解决方案:写一个中间类,将入参转换为中间类,在中间类的字段上加@NotBlank等注解,然后用本工具手动校验它。
优点
利用@NotBlank等校验,方便快捷
相关网址
SpringBoot--用hibernate validator手动校验--方法/实例_IT利刃出鞘的博客-CSDN博客_springboot 手动校验
代码
package com.knife.common.util;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import java.util.Set;
/**
* hibernate validator的校验工具
*/
public class ValidateUtil {
private static final Validator validator =
Validation.buildDefaultValidatorFactory().getValidator();
/**
* 校验实体类
*/
public static void validate(T t) {
Set> constraintViolations = validator.validate(t);
if (constraintViolations.size() > 0) {
StringBuilder validateError = new StringBuilder();
for (ConstraintViolation constraintViolation : constraintViolations) {
validateError.append(constraintViolation.getMessage()).append(";");
}
throw new ValidationException(validateError.toString());
}
}
/**
* 通过组来校验实体类
*/
public static void validate(T t, Class>... groups) {
Set> constraintViolations = validator.validate(t, groups);
if (constraintViolations.size() > 0) {
StringBuilder validateError = new StringBuilder();
for (ConstraintViolation constraintViolation : constraintViolations) {
validateError.append(constraintViolation.getMessage()).append(";");
}
throw new ValidationException(validateError.toString());
}
}
}
用法
User user = new User();
//对user字段赋值
ValidateUtil.validate(user);