Fork me on GitHub
23 July 2019

Chaos Server 是基于 Spring Boot 的 Java Web Server 框架, 简化开发, 封装了常见的企业级项目开发框架, 如 Mybaits, Spring Security 等。

在开发中会有很多模版式代码以及重复逻辑处理等,为了提高开发效率,把这些重复元素抽象提取封装,经过旧项目的多次迭代,最后封装为Chaos Server,代码已上传到 Github,地址为 https://github.com/cofcool/chaos-server,示例代码地址为 demo

1. 模块说明

1.1 common

该模块定义了基本接口和类等。

1.2 core

核心实现,包括拦截器, 国际化,Json 解析等

1.3 data-jpa

JPA相关的基础Service和工具类等

1.4 data-mybatis

Mybatis相关的基础Service和工具类等

1.5 data-redis

提供Redis所需依赖。

1.6 security-shiro

封装了Shiro,简化开发流程。

1.7 security-spring

封装了Spring Security,简化开发流程。

1.8 actuator

提供监控所需依赖。

1.9 component-processor

编译时扫描BaseComponent注解,该注解可标识基础组件, 避免组件调用混乱。

1.10 boot-starter

根据Spring Boot规范进行自动化配置。

2. 配置

# 项目运行模式
chaos.development.mode=dev
# 项目版本
chaos.development.version=100
# 是否开启验证码
chaos.auth.using-captcha=false
# 定义扫描 Scanned 注解的路径
chaos.development.annotation-path=net.cofcool.chaos.server.demo
# shiro授权路径配置
chaos.auth.urls=/auth/**\=anon,/error\=anon,/**\=authc
# 登陆路径
chaos.auth.login-url=/auth/login
# 注入数据key配置, 多个时以","分隔
chaos.auth.checked-keys=id

3. 使用

业务相关Service可继承DataAccess接口, 实现类可继承SimpleService抽象类。

使用Page类封装分页的相关数据, ORM模块的Paging继承并扩展。

  • Mybatis: 通过PageHelper分页。
  • Jpa: 通过Pageable分页。

异常处理时, 自定义业务相关异常需继承ServiceException。如需设定异常级别, 实现ExceptionLevel接口即可, 该级别影响异常的打印。ServiceException已实现该接口, 默认为最高级别。

3.1 授权处理

封装了Apache ShiroSpring Security, 应用可依赖security-shiro模块或security-spring模块来实现授权管理。

登录:

image

AuthService类定义了登录等操作, 应用不需要实现该类, 只需引用该组件即可, Shiro模块需要通过调用该类的login来实现登录,Spring Security的登录由”filter”完成,因此不需要调用该方法。

UserAuthorizationService定义应用操作, 应用需实现该类。

PasswordProcessor定义密码处理操作, 应用需实现该类。

User存储用户信息。

3.2 Service 层

DataAccess定义”Service”常用的方法。

Result封装运行结果,提供两个子接口,QueryResult封装查询结果,其它情况由ExecuteResult处理。

抽象类SimpleService实现DataAccess类,实现query方法,简化分页操作,定义queryWithPage方法,用于分页查询。通过ExceptionCodeManager描述执行状态错误码等。JPA 应用的”Service”可继承SimpleJpaService

3.3 Dao 层

3.4 Controller 层

默认提供三种”Controller(使用Scanned注解)”代理类:

  • 注入用户数据到请求参数中, 即数据隔离,实现类为ApiProcessingInterceptor
  • 请求日志打印,实现类为LoggingInterceptor
  • 参数校验,实现类为ValidateInterceptor
3.4.1 Json解析

ResponseBodyMessageConverter支持把Result, Number, String, Result.ResultState等对象转为Message对象,即可保证接口返回的数据统一为Message规定的格式(), 应用可调用Message.of()方法创建实例。

3.5 异常处理

3.5.1 默认处理异常类型

GlobalHandlerExceptionResolver处理在请求中发生的异常,包括如下异常:

  • ServiceException
  • NullPointerException, IndexOutOfBoundsException, NoSuchElementException
  • HttpMessageNotReadableException
  • UnsupportedOperationException
  • MethodArgumentNotValidException
  • DataAccessException

除以上异常外,其它异常由 Spring 的DefaultHandlerExceptionResolver处理。

把异常信息包装为Message对象,保证发生异常时的响应格式符合接口规范。

注意:当运行在Debug模式时,会优先调用DefaultHandlerExceptionResolver处理异常。

3.5.2 描述信息

应用中的描述信息统一由 ExceptionCodeManager 处理。ExceptionCodeDescriptor 封装了描述信息,默认提供了两种类型:

  • SimpleExceptionCodeDescriptor
  • ResourceExceptionCodeDescriptor

SimpleExceptionCodeDescriptor为默认配置,包含了常见的描述代码和描述信息,例如操作成功,操作失败等。

ResourceExceptionCodeDescriptor 从”messages”文件中读取配置的描述信息。

4. 常见问题

4.1 跨域等导致的登录失败

配置文件:

# 关闭 CSRF 验证
chaos.auth.csrf-enabled=false

# 跨域配置,允许跨域
chaos.auth.cors-enabled=true

创建 CorsConfigurationSource 使 CorsFilter 生效,如未使用 Spring Security,则通过 WebMvcConfigurer 配置跨域即可。

@Bean
public CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.applyPermitDefaultValues();
    // 通过 header 携带 session id 时的 header name
    configuration.addAllowedHeader("Authorization");
    configuration.addExposedHeader("Authorization");
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}