mirror of
https://gitee.com/orangeform/orange-admin.git
synced 2026-01-17 18:46:36 +08:00
commit:集成knife4j
This commit is contained in:
@@ -12,7 +12,7 @@ import java.util.Date;
|
||||
* Controller的环绕拦截类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class MyControllerAdvice {
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.concurrent.TimeoutException;
|
||||
* 用不同的函数,处理不同类型的异常。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice("com.orange.demo")
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 主要用于标记逻辑删除字段。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 主要用于标记更新字段。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 主要用于标记Service所依赖的数据源类型。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.lang.annotation.Target;
|
||||
* 标记Controller中的方法参数,参数解析器会根据该注解将请求中的JSON数据,映射到参数中的绑定字段。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 主要用于标记无需Token验证的接口
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 标识Model和常量字典之间的关联关系。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 标识Model之间的字典关联关系。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -4,9 +4,11 @@ import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 标注多对多的Model关系。
|
||||
* 重要提示:由于多对多关联表数据,很多时候都不需要跟随主表数据返回,所以该注解不会在
|
||||
* 生成的时候自动添加到实体类字段上,需要的时候,用户可自行手动添加。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 主要用于多对多的Model关系。标注通过从表关联字段或者关联表关联字段计算主表聚合计算字段的规则。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 主要用于一对多的Model关系。标注通过从表关联字段计算主表聚合计算字段的规则。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.lang.annotation.*;
|
||||
* 标识Model之间的一对一关联关系。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD, ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.lang.annotation.*;
|
||||
* 用于标记支持数据上传和下载的字段。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
* 记录接口的链路traceId、请求参数、应答数据、错误信息和调用时长。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.Map;
|
||||
*
|
||||
* @param <M> 主Model实体对象。
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@RegisterMapper
|
||||
public interface BaseDaoMapper<M> extends Mapper<M>, InsertListMapper<M> {
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.stream.Collectors;
|
||||
* @param <D> Domain域对象类型。
|
||||
* @param <M> Model实体对象类型。
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public interface BaseModelMapper<D, M> {
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
*
|
||||
* @param <M> 数据类型。
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class DummyModelMapper<M> implements BaseModelMapper<M, M> {
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.List;
|
||||
* @param <M> Model实体对象的类型。
|
||||
* @param <K> Model对象主键的类型。
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseDictService<M, K> extends BaseService<M, K> {
|
||||
|
||||
@@ -34,7 +34,7 @@ import static java.util.stream.Collectors.*;
|
||||
* @param <M> Model对象的类型。
|
||||
* @param <K> Model对象主键的类型。
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseService<M, K> {
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* 使用Caffeine作为本地缓存库
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.Set;
|
||||
* @param <K> 字典表主键类型。
|
||||
* @param <V> 字典表对象类型。
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public interface DictionaryCache<K, V> {
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.function.Function;
|
||||
* @param <K> 字典表主键类型。
|
||||
* @param <V> 字典表对象类型。
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class MapDictionaryCache<K, V> implements DictionaryCache<K, V> {
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.function.Function;
|
||||
* @param <K> 字典表主键类型。
|
||||
* @param <V> 字典表对象类型。
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class MapTreeDictionaryCache<K, V> extends MapDictionaryCache<K, V> {
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.Set;
|
||||
* Session数据缓存辅助类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Component
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.List;
|
||||
* 所有的项目拦截器、参数解析器、消息对象转换器都在这里集中配置。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
public class CommonWebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
* 目前用于用户密码加密,UAA接入应用客户端的client_secret加密。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
public class EncryptConfig {
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
* RestTemplate连接池配置对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
public class RestTemplateConfig {
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
* tomcat配置对象。当前配置禁用了PUT和DELETE方法,防止渗透攻击。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Configuration
|
||||
public class TomcatConfig {
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.Map;
|
||||
* 聚合计算的常量类型对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public final class AggregationType {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.constant;
|
||||
* 应用程序的常量声明对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public final class ApplicationConstant {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.constant;
|
||||
* 返回应答中的错误代码和错误信息。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public enum ErrorCodeEnum {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.constant;
|
||||
* 数据记录逻辑删除标记常量。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public final class GlobalDeletedFlag {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.exception;
|
||||
* 数据验证失败的自定义异常。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class DataValidationException extends RuntimeException {
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
|
||||
* 无效的类对象字段的自定义异常。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
|
||||
* 无效的实体对象字段的自定义异常。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
|
||||
* 无效的实体对象的自定义异常。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
|
||||
@@ -5,7 +5,7 @@ package com.orange.demo.common.core.exception;
|
||||
* NOTE:主要是为了避免SonarQube进行代码质量扫描时,给出警告。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class MyRuntimeException extends RuntimeException {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.exception;
|
||||
* 没有数据被修改的自定义异常。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class NoDataAffectException extends RuntimeException {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.exception;
|
||||
* 没有数据访问权限的自定义异常。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class NoDataPermException extends RuntimeException {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.exception;
|
||||
* Redis缓存访问失败。比如:获取分布式数据锁超时、等待线程中断等。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class RedisCacheAccessException extends RuntimeException {
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.*;
|
||||
* 2、多个对象需要封装到一个对象里才可以用@RequestBody接收。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class MyRequestArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.Map;
|
||||
* 应用程序启动后的事件监听对象。主要负责加载Model之间的字典关联和一对一关联所对应的Service结构关系。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Component
|
||||
public class LoadCachedDataListener implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.Map;
|
||||
* 应用程序启动后的事件监听对象。主要负责加载Model之间的字典关联和一对一关联所对应的Service结构关系。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Component
|
||||
public class LoadServiceRelationListener implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
* 同时为了提升效率,减少查询次数,可以根据具体的需求,将部分验证关联对象存入data字段,以供Controller使用。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
public class CallResult {
|
||||
|
||||
@@ -7,7 +7,7 @@ import lombok.Data;
|
||||
* Mybatis Mapper.xml中所需的分组条件对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.List;
|
||||
* 查询分组参数请求对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Slf4j
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.*;
|
||||
* Controller参数中的排序请求对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Slf4j
|
||||
@@ -44,6 +44,9 @@ public class MyOrderParam extends ArrayList<MyOrderParam.OrderInfo> {
|
||||
int i = 0;
|
||||
StringBuilder orderBy = new StringBuilder(128);
|
||||
for (OrderInfo orderInfo : orderParam) {
|
||||
if (StringUtils.isBlank(orderInfo.getFieldName())) {
|
||||
continue;
|
||||
}
|
||||
OrderBaseData orderBaseData = parseOrderBaseData(orderInfo, modelClazz);
|
||||
if (StringUtils.isBlank(orderBaseData.tableName)) {
|
||||
throw new InvalidDataModelException(orderBaseData.modelName);
|
||||
@@ -83,9 +86,6 @@ public class MyOrderParam extends ArrayList<MyOrderParam.OrderInfo> {
|
||||
|
||||
private static OrderBaseData parseOrderBaseData(OrderInfo orderInfo, Class<?> modelClazz) {
|
||||
OrderBaseData orderBaseData = new OrderBaseData();
|
||||
if (StringUtils.isBlank(orderInfo.getFieldName())) {
|
||||
return orderBaseData;
|
||||
}
|
||||
orderBaseData.fieldName = StringUtils.substringBefore(orderInfo.fieldName, DICT_MAP);
|
||||
String[] stringArray = StringUtils.split(orderBaseData.fieldName, '.');
|
||||
if (stringArray.length == 1) {
|
||||
@@ -230,7 +230,7 @@ public class MyOrderParam extends ArrayList<MyOrderParam.OrderInfo> {
|
||||
@Data
|
||||
public static class OrderInfo {
|
||||
/**
|
||||
* Java对象的字段名。目前主要包含三种格式:
|
||||
* Java对象的字段名。如果fieldName为空,则忽略跳过。目前主要包含三种格式:
|
||||
* 1. 简单的属性名称,如userId,将会直接映射到与其关联的数据库字段。表名为当前ModelClazz所对应的表名。
|
||||
* 映射结果或为 my_main_table.user_id
|
||||
* 2. 字典属性名称,如userIdDictMap.id,由于仅仅支持字典中Id数据的排序,所以直接截取DictMap之前的字符串userId作为排序属性。
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.orange.demo.common.core.object;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页数据的应答返回对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
public class MyPageData<T> {
|
||||
/**
|
||||
* 数据列表。
|
||||
*/
|
||||
private List<T> dataList;
|
||||
/**
|
||||
* 数据总数量。
|
||||
*/
|
||||
private Long totalCount;
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import lombok.Getter;
|
||||
* Controller参数中的分页请求对象
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Getter
|
||||
public class MyPageParam {
|
||||
|
||||
@@ -8,7 +8,7 @@ import lombok.Data;
|
||||
* BaseService中的实体对象数据组装函数,会根据该参数对象进行数据组装。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.List;
|
||||
* Where中的条件语句。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
@Data
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.io.PrintWriter;
|
||||
* 接口返回对象
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
public class ResponseResult<T> {
|
||||
|
||||
@@ -10,7 +10,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||
* 基于Jwt,用于前后端传递的令牌对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@ToString
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.object;
|
||||
* 二元组对象。主要用于可以一次返回多个结果的场景,同时还能避免强制转换。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class Tuple2<T1, T2> {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import java.util.List;
|
||||
* 包含存储本地文件的功能,以及上传和下载所需的通用方法。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseUpDownloader {
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.Objects;
|
||||
* 存储本地文件的上传下载实现类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -75,7 +75,7 @@ public class LocalUpDownloader extends BaseUpDownloader {
|
||||
i = bis.read(buff);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to call UpDownloadUtil.doDownload", e);
|
||||
log.error("Failed to call LocalUpDownloader.doDownload", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.Map;
|
||||
* 业务对象根据上传下载存储类型,获取上传下载对象的工厂类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Component
|
||||
public class UpDownloaderFactory {
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.Data;
|
||||
* 数据上传操作的应答信息对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
public class UploadResponseInfo {
|
||||
|
||||
@@ -6,7 +6,7 @@ import lombok.Data;
|
||||
* 上传数据存储信息对象。这里之所以使用对象,主要是便于今后扩展。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
public class UploadStoreInfo {
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.upload;
|
||||
* 上传数据存储介质类型枚举。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public enum UploadStoreTypeEnum {
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.lang.reflect.Field;
|
||||
* 获取JDK动态代理/CGLIB代理对象代理的目标对象的工具类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class AopTargetUtil {
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
|
||||
* Spring 系统启动应用感知对象,主要用于获取Spring Bean的上下文对象,后续的代码中可以直接查找系统中加载的Bean对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Component
|
||||
public class ApplicationContextHolder implements ApplicationContextAware {
|
||||
|
||||
@@ -10,7 +10,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
* 获取Servlet HttpRequest和HttpResponse的工具类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class ContextUtil {
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import java.util.*;
|
||||
* 导出工具类,目前支持xlsx和csv两种类型。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class ExportUtil {
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.stream.Collectors;
|
||||
* 导入工具类,目前支持xlsx和csv两种类型。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class ImportUtil {
|
||||
@@ -122,7 +122,7 @@ public class ImportUtil {
|
||||
* @param rowIndex 当前行号。
|
||||
* @param row 当前行数据列表对象。
|
||||
*/
|
||||
public void doImport(int rowIndex, List<Object> row) {
|
||||
public void doImport(long rowIndex, List<Object> row) {
|
||||
if (row == null) {
|
||||
doProcess(batchRowList);
|
||||
doFinish();
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.List;
|
||||
* Ip工具类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class IpUtil {
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Map;
|
||||
* 基于JWT的Token生成工具类
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class JwtUtil {
|
||||
|
||||
@@ -6,7 +6,7 @@ package com.orange.demo.common.core.util;
|
||||
* 提高代码的规范度和可维护性。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class LogMessageUtil {
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.UUID;
|
||||
* 脚手架中常用的基本工具方法集合,一般而言工程内部使用的方法。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class MyCommonUtil {
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import static org.joda.time.PeriodType.days;
|
||||
* 日期工具类,主要封装了部分joda-time中的方法,让很多代码一行完成,同时统一了日期到字符串的pattern格式。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class MyDateUtil {
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.stream.Collectors;
|
||||
* 负责Model数据操作、类型转换和关系关联等行为的工具类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class MyModelUtil {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.orange.demo.common.core.util;
|
||||
import cn.jimmyshi.beanquery.BeanQuery;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.orange.demo.common.core.object.MyPageData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -10,7 +11,7 @@ import java.util.List;
|
||||
* 生成带有分页信息的数据列表
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class MyPageUtil {
|
||||
|
||||
@@ -37,13 +38,13 @@ public class MyPageUtil {
|
||||
* 用户构建带有分页信息的数据列表。
|
||||
*
|
||||
* @param dataList 数据列表,该参数必须是调用PageMethod.startPage之后,立即执行mybatis查询操作的结果集。
|
||||
* @return 返回结果集和TotalCount。
|
||||
* @return 返回分页数据对象。
|
||||
*/
|
||||
public static <T> JSONObject makeResponseData(List<T> dataList) {
|
||||
JSONObject pageData = new JSONObject();
|
||||
pageData.put(DATA_LIST_LITERAL, dataList);
|
||||
public static <T> MyPageData<T> makeResponseData(List<T> dataList) {
|
||||
MyPageData<T> pageData = new MyPageData<>();
|
||||
pageData.setDataList(dataList);
|
||||
if (dataList instanceof Page) {
|
||||
pageData.put(TOTAL_COUNT_LITERAL, ((Page<?>)dataList).getTotal());
|
||||
pageData.setTotalCount(((Page<?>)dataList).getTotal());
|
||||
}
|
||||
return pageData;
|
||||
}
|
||||
@@ -53,13 +54,13 @@ public class MyPageUtil {
|
||||
*
|
||||
* @param dataList 数据列表,该参数必须是调用PageMethod.startPage之后,立即执行mybatis查询操作的结果集。
|
||||
* @param totalCount 总数量。
|
||||
* @return 返回结果集和TotalCount。
|
||||
* @return 返回分页数据对象。
|
||||
*/
|
||||
public static <T> JSONObject makeResponseData(List<T> dataList, Long totalCount) {
|
||||
JSONObject pageData = new JSONObject();
|
||||
pageData.put(DATA_LIST_LITERAL, dataList);
|
||||
public static <T> MyPageData<T> makeResponseData(List<T> dataList, Long totalCount) {
|
||||
MyPageData<T> pageData = new MyPageData<>();
|
||||
pageData.setDataList(dataList);
|
||||
if (totalCount != null) {
|
||||
pageData.put(TOTAL_COUNT_LITERAL, totalCount);
|
||||
pageData.setTotalCount(totalCount);
|
||||
}
|
||||
return pageData;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.Map;
|
||||
* Java RSA 加密工具类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class RsaUtil {
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.function.Function;
|
||||
* @param <K> 节点之间关联键的类型。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
public class TreeNode<T, K> {
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.validator;
|
||||
* 数据增加的验证分组。通常用于数据新增场景。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public interface AddGroup {
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.lang.annotation.Target;
|
||||
* 定义在Model对象中,标注字段值引用自指定的常量字典,和ConstDictRefValidator对象配合完成数据验证。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.lang.reflect.Method;
|
||||
* 数据字段自定义验证,用于验证Model中字符串字段的最大长度和最小长度。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class ConstDictValidator implements ConstraintValidator<ConstDictRef, Object> {
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.lang.annotation.Target;
|
||||
* 定义在Model或Dto对象中,UTF-8编码的字符串字段长度的上限和下限,和TextLengthValidator对象配合完成数据验证。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
|
||||
@@ -9,7 +9,7 @@ import javax.validation.ConstraintValidatorContext;
|
||||
* 数据字段自定义验证,用于验证Model中UTF-8编码的字符串字段的最大长度和最小长度。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class TextLengthValidator implements ConstraintValidator<TextLength, String> {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.core.validator;
|
||||
* 数据修改的验证分组。通常用于数据更新的场景。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public interface UpdateGroup {
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
* common-sequence模块的自动配置引导类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@EnableConfigurationProperties({IdGeneratorProperties.class})
|
||||
public class IdGeneratorAutoConfigure {
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
* common-sequence模块的配置类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "sequence")
|
||||
|
||||
@@ -9,7 +9,7 @@ import cn.hutool.core.util.IdUtil;
|
||||
* WorkNodeId是通过配置文件静态指定的。而SnowflakeIdGenerator的WorkNodeId是由zk生成的。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public class BasicIdGenerator implements MyIdGenerator {
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ package com.orange.demo.common.sequence.generator;
|
||||
* 分布式Id生成器的统一接口。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
public interface MyIdGenerator {
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import javax.annotation.PostConstruct;
|
||||
* 分布式Id生成器的封装类。该对象可根据配置选择不同的生成器实现类。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-10-19
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Component
|
||||
public class IdGeneratorWrapper {
|
||||
|
||||
29
orange-demo-single-service/common/common-swagger/pom.xml
Normal file
29
orange-demo-single-service/common/common-swagger/pom.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>common</artifactId>
|
||||
<groupId>com.orange.demo</groupId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>common-swagger</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>common-swagger</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>${knife4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.orange.demo</groupId>
|
||||
<artifactId>common-core</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.orange.demo.common.swagger.config;
|
||||
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
/**
|
||||
* 自动加载bean的配置对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@EnableSwagger2
|
||||
@EnableKnife4j
|
||||
@EnableConfigurationProperties(SwaggerProperties.class)
|
||||
@ConditionalOnProperty(prefix = "swagger", name = "enabled")
|
||||
public class SwaggerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public Docket upmsDocket(SwaggerProperties properties) {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.groupName("1. 用户权限分组接口")
|
||||
.ignoredParameterTypes(MyRequestBody.class)
|
||||
.apiInfo(apiInfo(properties))
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage(properties.getBasePackage() + ".upms.controller"))
|
||||
.paths(PathSelectors.any()).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket bizDocket(SwaggerProperties properties) {
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.groupName("2. 业务应用分组接口")
|
||||
.ignoredParameterTypes(MyRequestBody.class)
|
||||
.apiInfo(apiInfo(properties))
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage(properties.getBasePackage() + ".app.controller"))
|
||||
.paths(PathSelectors.any()).build();
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo(SwaggerProperties properties) {
|
||||
return new ApiInfoBuilder()
|
||||
.title(properties.getTitle())
|
||||
.description(properties.getDescription())
|
||||
.version(properties.getVersion()).build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.orange.demo.common.swagger.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 配置参数对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties("swagger")
|
||||
public class SwaggerProperties {
|
||||
|
||||
/**
|
||||
* 是否开启Swagger。
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* Swagger解析的基础包路径。
|
||||
**/
|
||||
private String basePackage = "";
|
||||
|
||||
/**
|
||||
* ApiInfo中的标题。
|
||||
**/
|
||||
private String title = "";
|
||||
|
||||
/**
|
||||
* ApiInfo中的描述信息。
|
||||
**/
|
||||
private String description = "";
|
||||
|
||||
/**
|
||||
* ApiInfo中的版本信息。
|
||||
**/
|
||||
private String version = "";
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.orange.demo.common.swagger.plugin;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.github.xiaoymin.knife4j.core.conf.Consts;
|
||||
import javassist.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import springfox.documentation.service.ResolvedMethodParameter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通过字节码方式动态创建接口参数封装对象。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Slf4j
|
||||
public class ByteBodyUtils {
|
||||
private static final ClassPool CLASS_POOL = ClassPool.getDefault();
|
||||
|
||||
public static Class<?> createDynamicModelClass(String name, List<ResolvedMethodParameter> parameters) {
|
||||
String clazzName = Consts.BASE_PACKAGE_PREFIX + name;
|
||||
try {
|
||||
CtClass tmp = CLASS_POOL.getCtClass(clazzName);
|
||||
if (tmp != null) {
|
||||
tmp.detach();
|
||||
}
|
||||
} catch (NotFoundException e) {
|
||||
// 需要吃掉这个异常。
|
||||
}
|
||||
CtClass ctClass = CLASS_POOL.makeClass(clazzName);
|
||||
try {
|
||||
int fieldCount = 0;
|
||||
for (ResolvedMethodParameter dynamicParameter : parameters) {
|
||||
// 因为在调用这个方法之前,这些参数都包含MyRequestBody注解。
|
||||
MyRequestBody myRequestBody =
|
||||
dynamicParameter.findAnnotation(MyRequestBody.class).orNull();
|
||||
Assert.notNull(myRequestBody);
|
||||
String fieldName = dynamicParameter.defaultName().isPresent()
|
||||
? dynamicParameter.defaultName().get() : "parameter";
|
||||
if (StringUtils.isNotBlank(myRequestBody.value())) {
|
||||
fieldName = myRequestBody.value();
|
||||
}
|
||||
ctClass.addField(createField(dynamicParameter, fieldName, ctClass));
|
||||
fieldCount++;
|
||||
}
|
||||
if (fieldCount > 0) {
|
||||
return ctClass.toClass();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static CtField createField(ResolvedMethodParameter parameter, String parameterName, CtClass ctClass)
|
||||
throws NotFoundException, CannotCompileException {
|
||||
CtField field = new CtField(getFieldType(parameter.getParameterType().getErasedType()), parameterName, ctClass);
|
||||
field.setModifiers(Modifier.PUBLIC);
|
||||
return field;
|
||||
}
|
||||
|
||||
private static CtClass getFieldType(Class<?> propetyType) {
|
||||
CtClass fieldType = null;
|
||||
try {
|
||||
if (!propetyType.isAssignableFrom(Void.class)) {
|
||||
fieldType = CLASS_POOL.get(propetyType.getName());
|
||||
} else {
|
||||
fieldType = CLASS_POOL.get(String.class.getName());
|
||||
}
|
||||
} catch (NotFoundException e) {
|
||||
//抛异常
|
||||
ClassClassPath path = new ClassClassPath(propetyType);
|
||||
CLASS_POOL.insertClassPath(path);
|
||||
try {
|
||||
fieldType = CLASS_POOL.get(propetyType.getName());
|
||||
} catch (NotFoundException e1) {
|
||||
log.error(e1.getMessage(), e1);
|
||||
}
|
||||
}
|
||||
return fieldType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.orange.demo.common.swagger.plugin;
|
||||
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.fasterxml.classmate.TypeResolver;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import springfox.documentation.service.ResolvedMethodParameter;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.OperationModelsProviderPlugin;
|
||||
import springfox.documentation.spi.service.contexts.RequestMappingContext;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 生成参数包装类的插件。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Component
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 200)
|
||||
@ConditionalOnProperty(prefix = "swagger", name = "enabled")
|
||||
public class DynamicBodyModelPlugin implements OperationModelsProviderPlugin {
|
||||
|
||||
private final TypeResolver typeResolver;
|
||||
|
||||
public DynamicBodyModelPlugin(TypeResolver typeResolver) {
|
||||
this.typeResolver = typeResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(RequestMappingContext context) {
|
||||
List<ResolvedMethodParameter> parameterTypes = context.getParameters();
|
||||
if (CollectionUtils.isEmpty(parameterTypes)) {
|
||||
return;
|
||||
}
|
||||
List<ResolvedMethodParameter> bodyParameter = parameterTypes.stream()
|
||||
.filter(p -> p.hasParameterAnnotation(MyRequestBody.class)).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(bodyParameter)) {
|
||||
return;
|
||||
}
|
||||
String groupName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, context.getGroupName());
|
||||
String clazzName = groupName + StringUtils.capitalize(context.getName());
|
||||
Class<?> clazz = ByteBodyUtils.createDynamicModelClass(clazzName, bodyParameter);
|
||||
if (clazz != null) {
|
||||
context.operationModelsBuilder().addInputParam(typeResolver.resolve(clazz));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(DocumentationType delimiter) {
|
||||
//支持2.0版本
|
||||
return delimiter == DocumentationType.SWAGGER_2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.orange.demo.common.swagger.plugin;
|
||||
|
||||
import com.orange.demo.common.core.annotation.MyRequestBody;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
import springfox.documentation.builders.ParameterBuilder;
|
||||
import springfox.documentation.schema.ModelRef;
|
||||
import springfox.documentation.service.Parameter;
|
||||
import springfox.documentation.service.ResolvedMethodParameter;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.OperationBuilderPlugin;
|
||||
import springfox.documentation.spi.service.contexts.OperationContext;
|
||||
import springfox.documentation.spi.service.contexts.ParameterContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 构建操作接口参数对象的插件。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-09-24
|
||||
*/
|
||||
@Component
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE + 102)
|
||||
@ConditionalOnProperty(prefix = "swagger", name = "enabled")
|
||||
public class DynamicBodyParameterBuilder implements OperationBuilderPlugin {
|
||||
|
||||
@Override
|
||||
public void apply(OperationContext context) {
|
||||
List<ResolvedMethodParameter> methodParameters = context.getParameters();
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(methodParameters)) {
|
||||
List<ResolvedMethodParameter> bodyParameter = methodParameters.stream()
|
||||
.filter(p -> p.hasParameterAnnotation(MyRequestBody.class)).collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(bodyParameter)) {
|
||||
//构造model
|
||||
String groupName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, context.getGroupName());
|
||||
String clazzName = groupName + StringUtils.capitalize(context.getName());
|
||||
ResolvedMethodParameter methodParameter = bodyParameter.get(0);
|
||||
ParameterContext parameterContext = new ParameterContext(methodParameter,
|
||||
new ParameterBuilder(),
|
||||
context.getDocumentationContext(),
|
||||
context.getGenericsNamingStrategy(),
|
||||
context);
|
||||
Parameter parameter = parameterContext.parameterBuilder()
|
||||
.parameterType("body").modelRef(new ModelRef(clazzName)).name(clazzName).build();
|
||||
parameters.add(parameter);
|
||||
}
|
||||
}
|
||||
context.operationBuilder().parameters(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(DocumentationType delimiter) {
|
||||
return delimiter == DocumentationType.SWAGGER_2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.orange.demo.common.swagger.config.SwaggerAutoConfiguration
|
||||
@@ -14,5 +14,6 @@
|
||||
<modules>
|
||||
<module>common-core</module>
|
||||
<module>common-sequence</module>
|
||||
<module>common-swagger</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
||||
Reference in New Issue
Block a user