前言
本人前端时间受命搭建一个WEB后端小项目,再踩过一些大坑以后,遂有此文,用于记录
1.美化系统输入输出
所谓美化输入输出,其实就是对于正常返回结果以及异常结果的封装,输入的结果的校验,以增加系统的健壮性
- 异常处理
@ControllerAdvice(annotations = Web.class)
public class DecisionWebExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(DecisionWebExceptionHandler.class);
public static final String PARAMETER_VALIDATE_EXCEPTION = "参数异常!";
/**
* 自定义异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(ValidationException.class)
@ResponseBody
public Map<String, String> handleException(final ValidationException validationException) {
//todo 处理异常
return result;
}
/**
* 捕获JSR303异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public Map<String, String> handleException(final MethodArgumentNotValidException validException) {
final Map<String, String> result = new HashMap<>(2);
String message = validException.getBindingResult().getFieldErrors().
stream().findFirst().map(DefaultMessageSourceResolvable::getDefaultMessage).orElse(PARAMETER_VALIDATE_EXCEPTION);
result.put("code", HttpStatus.BAD_REQUEST.toString());
result.put("message", message);
return result;
}
}
* 强烈建议修改JSR303的返回,原生JSR303的返回真的不优雅
* @ControllerAdvice(annotations = Web.class)大家用的很多,但是如果通过annotations属性就可针对不同的情况返回不同的处理结果,美化系统
- 统一返回结果
Result 返回结果
/** * 编码 */ private String code; /** * 数据 */ private T data; /** * 信息 */ private String message;
ResultBuilder 通过建造者模式返回Result
public ResultBuilder<T> success() { result.setCode(SUCCESS_CODE); return this; } public ResultBuilder<T> addData(T data) { result.setData(data); return this; }
- JSON转换器
Jackson 号称最快的JSON转换器,但是API真的很难用,对于习惯Fastjson的我来说, 简直是灾难,一定要切换成FastjsonConverter,这个代码很多,不予展示!
2.基于AOP埋点
操作日志、动态数据源、事务管理等都需要通过切面进行埋点,方面不侵入业务代码的情况下进行操作
- 操作日志
/**
* 用户操作日志注解
*/
//注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperateLog {
String value() default "";
}
//切面
public class OperateLogAspect {
@Pointcut("@annotation(OperateLog)")
public void pointcut() {
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
}
}
- 动态数据源
@Component
@Order(value = -100)
@Aspect
public class DataSourceSwitchAspect {
@Pointcut("@within(EsaService)")
public void esaPointCut() {
}
@Before("esaPointCut()")
public void switchToEsa() {
}
}
还有很多功能可以基于AOP埋点实现,希望大家能够活学活用,发挥能动性
- 总结
Spirng Boot 极大的简化了项目搭建的成本以及复杂度,但是如果再项目搭建初期没有对项目进行一定的美化,后期如果想要再进行美化 ,那酸爽,大家应该都有体验!