全局日期(或者其他)格式化成相应的数据类型
简介
这个操作是建立在Spring Framwork
的Converter<T,S>接口
上的,?以日期为例说明转化器的使用。
使用场景:前端传递的Date,可能是long,int ,String 类型的,后台的Controller接口只需要一个Date类型,此时,怎么整了??,
- 1️⃣ 先获取基本数据类型的日期属性,然后在service 层对其进行处理,这种方式每一个接口都需要处理,缺点不言而喻
- 2️⃣ 配置全局数据转化器,这个正式我要介绍的,look down
注:其他类型也可以通过此方式进行进行参数转换
使用案例
以springboot 项目为例,只需要将一个Converter的实现类
加入到容器中:
/**
* 描述:全局日期统一处理
* User liupenghao
* Date 2018/10/31 16:41
**/
@Component
public class DateConverterConfig implements Converter<String, Date> {
private static final List<String> formarts = new ArrayList<>(4);
static {
formarts.add("yyyy-MM");
formarts.add("yyyy-MM-dd");
formarts.add("yyyy-MM-dd hh:mm");
formarts.add("yyyy-MM-dd hh:mm:ss");
}
@Override
public Date convert(String source) {
String value = source.trim();
if ("".equals(value)) {
return null;
}
if (source.matches("^\\d{4}-\\d{1,2}$")) {
return parseDate(source, formarts.get(0));
} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$")) {
return parseDate(source, formarts.get(1));
} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}$")) {
return parseDate(source, formarts.get(2));
} else if (source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$")) {
return parseDate(source, formarts.get(3));
} else {
throw new IllegalArgumentException("Invalid boolean value '" + source + "'");
}
}
/**
* 格式化日期
*
* @param dateStr String 字符型日期
* @param format String 格式
* @return Date 日期
*/
public Date parseDate(String dateStr, String format) {
Date date = null;
try {
DateFormat dateFormat = new SimpleDateFormat(format);
date = dateFormat.parse(dateStr);
} catch (Exception e) {
}
return date;
}
}
全局异常处理
介绍
Controller 层的异常,如果采用普通的try catch 处理,则每一个接口的处理,都需要在外层包裹一个☝️
。这种方式很不友好。现在?我们可以通ExceptionController
进行全局异常统一处理
。
案例
@Slf4j
@RestControllerAdvice
public class ExceptionController {
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(ShiroException.class)
public Result handle(ShiroException e) {
return new Result(401, e.getMessage());
}
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ExceptionHandler(UnauthorizedException.class)
public Result handle(UnauthorizedException e) {
return new Result(401, e.getMessage());
}
@ExceptionHandler(ServiceException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public Result handle(ServiceException e) {
return new Result(e.getErrcode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Result globalException(HttpServletRequest request, Throwable ex) {
return new Result(getStatus(request).value(), ex.getMessage());
}
private HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
return HttpStatus.valueOf(statusCode);
}
}
BeanUtil.copy()的非空复制
简介
Spring Framework Beans 包中提供了BeanUtil.copyProperties(resource,targer);
方法,用于属性的复制,但操蛋的是这个方法不管神马东西都复制
,于是乎,为了方便操作,我查看了它的源码,在源码的基础上加上了判断,null值不复制
案例
为了使用方便,我就把帮助类给大家贴出来,记得给我点个赞哦?
/**
* 描述:
* User liupenghao
* Date 2018/10/31 19:56
**/
public class BeanUtil {
/**
* bean 拷贝方法
* @param source
* @param target
* @throws BeansException
*/
public static void copyProperties(Object source, Object target) throws BeansException {
copyProperties(source, target, null, (String[]) null);
}
/**
* bean 拷贝方法,去除null属性
* @param source
* @param target
* @param editable
* @param ignoreProperties
* @throws BeansException
*/
public static void copyProperties(Object source, Object target, @Nullable Class<?> editable,
@Nullable String... ignoreProperties) throws BeansException {
Assert.notNull(source, "Source must not be null");
Assert.notNull(target, "Target must not be null");
Class<?> actualEditable = target.getClass();
if (editable != null) {
if (!editable.isInstance(target)) {
throw new IllegalArgumentException("Target class [" + target.getClass().getName() +
"] not assignable to Editable class [" + editable.getName() + "]");
}
actualEditable = editable;
}
PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable);
List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
for (PropertyDescriptor targetPd : targetPds) {
Method writeMethod = targetPd.getWriteMethod();
if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
if (sourcePd != null) {
Method readMethod = sourcePd.getReadMethod();
if (readMethod != null &&
ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
try {
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source);
// 新增空值判断,若源属性为null,不复制这个属性
if(value == null){
continue;
}
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, value);
}
catch (Throwable ex) {
throw new FatalBeanException(
"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
}
}
}
}
}
}
}