| | |
| | | <redisson.version>3.16.3</redisson.version> |
| | | <lock4j.version>2.2.1</lock4j.version> |
| | | <dynamic-ds.version>3.4.1</dynamic-ds.version> |
| | | <tlog.version>1.3.2</tlog.version> |
| | | <tlog.version>1.3.3</tlog.version> |
| | | <xxl-job.version>2.3.0</xxl-job.version> |
| | | |
| | | <!-- jdk11 缺失依赖 jaxb--> |
| | |
| | | package com.ruoyi.common.annotation; |
| | | |
| | | import java.lang.annotation.Documented; |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 数据权限过滤注解 |
| | |
| | | @Target(ElementType.METHOD) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface DataScope |
| | | { |
| | | public @interface DataScope { |
| | | /** |
| | | * 部门表的别名 |
| | | */ |
| | | public String deptAlias() default ""; |
| | | String deptAlias() default ""; |
| | | |
| | | /** |
| | | * 用户表的别名 |
| | | */ |
| | | public String userAlias() default ""; |
| | | String userAlias() default ""; |
| | | |
| | | /** |
| | | * 是否过滤用户权限 |
| | | */ |
| | | public boolean isUser() default false; |
| | | /** |
| | | * 是否过滤用户权限 |
| | | */ |
| | | boolean isUser() default false; |
| | | } |
| | |
| | | package com.ruoyi.common.annotation; |
| | | |
| | | import java.lang.annotation.Documented; |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Inherited; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | import com.ruoyi.common.enums.DataSourceType; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 自定义多数据源切换注解 |
| | | * |
| | | * <p> |
| | | * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Target({ ElementType.METHOD, ElementType.TYPE }) |
| | | @Target({ElementType.METHOD, ElementType.TYPE}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | @Inherited |
| | | public @interface DataSource |
| | | { |
| | | public @interface DataSource { |
| | | /** |
| | | * 切换数据源名称 |
| | | */ |
| | | public DataSourceType value() default DataSourceType.MASTER; |
| | | DataSourceType value() default DataSourceType.MASTER; |
| | | } |
| | |
| | | @Inherited |
| | | public @interface ExcelDictFormat { |
| | | |
| | | /** |
| | | * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) |
| | | */ |
| | | String dictType() default ""; |
| | | /** |
| | | * 如果是字典类型,请设置字典的type值 (如: sys_user_sex) |
| | | */ |
| | | String dictType() default ""; |
| | | |
| | | /** |
| | | * 读取内容转表达式 (如: 0=男,1=女,2=未知) |
| | | */ |
| | | String readConverterExp() default ""; |
| | | /** |
| | | * 读取内容转表达式 (如: 0=男,1=女,2=未知) |
| | | */ |
| | | String readConverterExp() default ""; |
| | | |
| | | /** |
| | | * 分隔符,读取字符串组内容 |
| | | */ |
| | | String separator() default ","; |
| | | /** |
| | | * 分隔符,读取字符串组内容 |
| | | */ |
| | | String separator() default ","; |
| | | |
| | | } |
| | |
| | | package com.ruoyi.common.annotation; |
| | | |
| | | import java.lang.annotation.Documented; |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | import com.ruoyi.common.enums.BusinessType; |
| | | import com.ruoyi.common.enums.OperatorType; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | /** |
| | | * 自定义操作日志记录注解 |
| | | * |
| | | * @author ruoyi |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Target({ ElementType.PARAMETER, ElementType.METHOD }) |
| | | @Target({ElementType.PARAMETER, ElementType.METHOD}) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface Log |
| | | { |
| | | public @interface Log { |
| | | /** |
| | | * 模块 |
| | | * 模块 |
| | | */ |
| | | public String title() default ""; |
| | | String title() default ""; |
| | | |
| | | /** |
| | | * 功能 |
| | | */ |
| | | public BusinessType businessType() default BusinessType.OTHER; |
| | | BusinessType businessType() default BusinessType.OTHER; |
| | | |
| | | /** |
| | | * 操作人类别 |
| | | */ |
| | | public OperatorType operatorType() default OperatorType.MANAGE; |
| | | OperatorType operatorType() default OperatorType.MANAGE; |
| | | |
| | | /** |
| | | * 是否保存请求的参数 |
| | | */ |
| | | public boolean isSaveRequestData() default true; |
| | | boolean isSaveRequestData() default true; |
| | | |
| | | /** |
| | | * 是否保存响应的参数 |
| | | */ |
| | | public boolean isSaveResponseData() default true; |
| | | boolean isSaveResponseData() default true; |
| | | } |
| | |
| | | package com.ruoyi.common.annotation;
|
| | |
|
| | | import java.lang.annotation.Documented;
|
| | | import java.lang.annotation.ElementType;
|
| | | import java.lang.annotation.Retention;
|
| | | import java.lang.annotation.RetentionPolicy;
|
| | | import java.lang.annotation.Target;
|
| | | import com.ruoyi.common.constant.Constants;
|
| | | import com.ruoyi.common.enums.LimitType;
|
| | |
|
| | | import java.lang.annotation.*;
|
| | |
|
| | | /**
|
| | | * 限流注解
|
| | | * |
| | | * @author ruoyi
|
| | | *
|
| | | * @author Lion Li
|
| | | */
|
| | | @Target(ElementType.METHOD)
|
| | | @Retention(RetentionPolicy.RUNTIME)
|
| | | @Documented
|
| | | public @interface RateLimiter
|
| | | {
|
| | | public @interface RateLimiter {
|
| | | /**
|
| | | * 限流key
|
| | | */
|
| | | public String key() default Constants.RATE_LIMIT_KEY;
|
| | | String key() default Constants.RATE_LIMIT_KEY;
|
| | |
|
| | | /**
|
| | | * 限流时间,单位秒
|
| | | */
|
| | | public int time() default 60;
|
| | | int time() default 60;
|
| | |
|
| | | /**
|
| | | * 限流次数
|
| | | */
|
| | | public int count() default 100;
|
| | | int count() default 100;
|
| | |
|
| | | /**
|
| | | * 限流类型
|
| | | */
|
| | | public LimitType limitType() default LimitType.DEFAULT;
|
| | | LimitType limitType() default LimitType.DEFAULT;
|
| | | }
|
| | |
| | | package com.ruoyi.common.annotation; |
| | | |
| | | import java.lang.annotation.Documented; |
| | | import java.lang.annotation.ElementType; |
| | | import java.lang.annotation.Inherited; |
| | | import java.lang.annotation.Retention; |
| | | import java.lang.annotation.RetentionPolicy; |
| | | import java.lang.annotation.Target; |
| | | import java.lang.annotation.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | |
| | | @Documented |
| | | public @interface RepeatSubmit { |
| | | |
| | | /** |
| | | * 间隔时间(ms),小于此时间视为重复提交 |
| | | */ |
| | | int interval() default 5000; |
| | | /** |
| | | * 间隔时间(ms),小于此时间视为重复提交 |
| | | */ |
| | | int interval() default 5000; |
| | | |
| | | TimeUnit timeUnit() default TimeUnit.MILLISECONDS; |
| | | TimeUnit timeUnit() default TimeUnit.MILLISECONDS; |
| | | |
| | | /** |
| | | * 提示消息 |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class Constants |
| | | { |
| | | public class Constants { |
| | | /** |
| | | * UTF-8 字符集 |
| | | */ |
| | |
| | | */ |
| | | public static final String SYS_DICT_KEY = "sys_dict:"; |
| | | |
| | | /** |
| | | * RMI 远程方法调用 |
| | | */ |
| | | public static final String LOOKUP_RMI = "rmi://"; |
| | | /** |
| | | * RMI 远程方法调用 |
| | | */ |
| | | public static final String LOOKUP_RMI = "rmi://"; |
| | | |
| | | /** |
| | | * LDAP 远程方法调用 |
| | | */ |
| | | public static final String LOOKUP_LDAP = "ldap://"; |
| | | /** |
| | | * LDAP 远程方法调用 |
| | | */ |
| | | public static final String LOOKUP_LDAP = "ldap://"; |
| | | } |
| | |
| | | |
| | | /** |
| | | * 代码生成通用常量 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class GenConstants |
| | | { |
| | | /** 单表(增删改查) */ |
| | | public class GenConstants { |
| | | /** |
| | | * 单表(增删改查) |
| | | */ |
| | | public static final String TPL_CRUD = "crud"; |
| | | |
| | | /** 树表(增删改查) */ |
| | | /** |
| | | * 树表(增删改查) |
| | | */ |
| | | public static final String TPL_TREE = "tree"; |
| | | |
| | | /** 主子表(增删改查) */ |
| | | /** |
| | | * 主子表(增删改查) |
| | | */ |
| | | public static final String TPL_SUB = "sub"; |
| | | |
| | | /** 树编码字段 */ |
| | | /** |
| | | * 树编码字段 |
| | | */ |
| | | public static final String TREE_CODE = "treeCode"; |
| | | |
| | | /** 树父编码字段 */ |
| | | /** |
| | | * 树父编码字段 |
| | | */ |
| | | public static final String TREE_PARENT_CODE = "treeParentCode"; |
| | | |
| | | /** 树名称字段 */ |
| | | /** |
| | | * 树名称字段 |
| | | */ |
| | | public static final String TREE_NAME = "treeName"; |
| | | |
| | | /** 上级菜单ID字段 */ |
| | | /** |
| | | * 上级菜单ID字段 |
| | | */ |
| | | public static final String PARENT_MENU_ID = "parentMenuId"; |
| | | |
| | | /** 上级菜单名称字段 */ |
| | | /** |
| | | * 上级菜单名称字段 |
| | | */ |
| | | public static final String PARENT_MENU_NAME = "parentMenuName"; |
| | | |
| | | /** 数据库字符串类型 */ |
| | | public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" }; |
| | | /** |
| | | * 数据库字符串类型 |
| | | */ |
| | | public static final String[] COLUMNTYPE_STR = {"char", "varchar", "nvarchar", "varchar2"}; |
| | | |
| | | /** 数据库文本类型 */ |
| | | public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" }; |
| | | /** |
| | | * 数据库文本类型 |
| | | */ |
| | | public static final String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext"}; |
| | | |
| | | /** 数据库时间类型 */ |
| | | public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; |
| | | /** |
| | | * 数据库时间类型 |
| | | */ |
| | | public static final String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp"}; |
| | | |
| | | /** 数据库数字类型 */ |
| | | public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", |
| | | "bit", "bigint", "float", "double", "decimal" }; |
| | | /** |
| | | * 数据库数字类型 |
| | | */ |
| | | public static final String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer", |
| | | "bit", "bigint", "float", "double", "decimal"}; |
| | | |
| | | /** BO对象 不需要添加字段 */ |
| | | public static final String[] COLUMNNAME_NOT_ADD = { "create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version" }; |
| | | /** |
| | | * BO对象 不需要添加字段 |
| | | */ |
| | | public static final String[] COLUMNNAME_NOT_ADD = {"create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version"}; |
| | | |
| | | /** BO对象 不需要编辑字段 */ |
| | | public static final String[] COLUMNNAME_NOT_EDIT = { "create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version" }; |
| | | /** |
| | | * BO对象 不需要编辑字段 |
| | | */ |
| | | public static final String[] COLUMNNAME_NOT_EDIT = {"create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version"}; |
| | | |
| | | /** VO对象 不需要返回字段 */ |
| | | public static final String[] COLUMNNAME_NOT_LIST = { "create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version" }; |
| | | /** |
| | | * VO对象 不需要返回字段 |
| | | */ |
| | | public static final String[] COLUMNNAME_NOT_LIST = {"create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "version"}; |
| | | |
| | | /** BO对象 不需要查询字段 */ |
| | | public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "remark", "version" }; |
| | | /** |
| | | * BO对象 不需要查询字段 |
| | | */ |
| | | public static final String[] COLUMNNAME_NOT_QUERY = {"id", "create_by", "create_time", "del_flag", "update_by", |
| | | "update_time", "remark", "version"}; |
| | | |
| | | /** Entity基类字段 */ |
| | | public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime" }; |
| | | /** |
| | | * Entity基类字段 |
| | | */ |
| | | public static final String[] BASE_ENTITY = {"createBy", "createTime", "updateBy", "updateTime"}; |
| | | |
| | | /** Tree基类字段 */ |
| | | public static final String[] TREE_ENTITY = { "parentName", "parentId", "children" }; |
| | | /** |
| | | * Tree基类字段 |
| | | */ |
| | | public static final String[] TREE_ENTITY = {"parentName", "parentId", "children"}; |
| | | |
| | | /** 文本框 */ |
| | | /** |
| | | * 文本框 |
| | | */ |
| | | public static final String HTML_INPUT = "input"; |
| | | |
| | | /** 文本域 */ |
| | | /** |
| | | * 文本域 |
| | | */ |
| | | public static final String HTML_TEXTAREA = "textarea"; |
| | | |
| | | /** 下拉框 */ |
| | | /** |
| | | * 下拉框 |
| | | */ |
| | | public static final String HTML_SELECT = "select"; |
| | | |
| | | /** 单选框 */ |
| | | /** |
| | | * 单选框 |
| | | */ |
| | | public static final String HTML_RADIO = "radio"; |
| | | |
| | | /** 复选框 */ |
| | | /** |
| | | * 复选框 |
| | | */ |
| | | public static final String HTML_CHECKBOX = "checkbox"; |
| | | |
| | | /** 日期控件 */ |
| | | /** |
| | | * 日期控件 |
| | | */ |
| | | public static final String HTML_DATETIME = "datetime"; |
| | | |
| | | /** 图片上传控件 */ |
| | | /** |
| | | * 图片上传控件 |
| | | */ |
| | | public static final String HTML_IMAGE_UPLOAD = "imageUpload"; |
| | | |
| | | /** 文件上传控件 */ |
| | | /** |
| | | * 文件上传控件 |
| | | */ |
| | | public static final String HTML_FILE_UPLOAD = "fileUpload"; |
| | | |
| | | /** 富文本控件 */ |
| | | /** |
| | | * 富文本控件 |
| | | */ |
| | | public static final String HTML_EDITOR = "editor"; |
| | | |
| | | /** 字符串类型 */ |
| | | /** |
| | | * 字符串类型 |
| | | */ |
| | | public static final String TYPE_STRING = "String"; |
| | | |
| | | /** 整型 */ |
| | | /** |
| | | * 整型 |
| | | */ |
| | | public static final String TYPE_INTEGER = "Integer"; |
| | | |
| | | /** 长整型 */ |
| | | /** |
| | | * 长整型 |
| | | */ |
| | | public static final String TYPE_LONG = "Long"; |
| | | |
| | | /** 浮点型 */ |
| | | /** |
| | | * 浮点型 |
| | | */ |
| | | public static final String TYPE_DOUBLE = "Double"; |
| | | |
| | | /** 高精度计算类型 */ |
| | | /** |
| | | * 高精度计算类型 |
| | | */ |
| | | public static final String TYPE_BIGDECIMAL = "BigDecimal"; |
| | | |
| | | /** 时间类型 */ |
| | | /** |
| | | * 时间类型 |
| | | */ |
| | | public static final String TYPE_DATE = "Date"; |
| | | |
| | | /** 模糊查询 */ |
| | | /** |
| | | * 模糊查询 |
| | | */ |
| | | public static final String QUERY_LIKE = "LIKE"; |
| | | |
| | | /** 需要 */ |
| | | /** |
| | | * 需要 |
| | | */ |
| | | public static final String REQUIRE = "1"; |
| | | } |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class UserConstants |
| | | { |
| | | public class UserConstants { |
| | | |
| | | /** |
| | | * 平台内系统用户的唯一标志 |
| | | */ |
| | | public static final String SYS_USER = "SYS_USER"; |
| | | |
| | | /** 正常状态 */ |
| | | /** |
| | | * 正常状态 |
| | | */ |
| | | public static final String NORMAL = "0"; |
| | | |
| | | /** 异常状态 */ |
| | | /** |
| | | * 异常状态 |
| | | */ |
| | | public static final String EXCEPTION = "1"; |
| | | |
| | | /** 用户封禁状态 */ |
| | | /** |
| | | * 用户封禁状态 |
| | | */ |
| | | public static final String USER_DISABLE = "1"; |
| | | |
| | | /** 角色封禁状态 */ |
| | | /** |
| | | * 角色封禁状态 |
| | | */ |
| | | public static final String ROLE_DISABLE = "1"; |
| | | |
| | | /** 部门正常状态 */ |
| | | /** |
| | | * 部门正常状态 |
| | | */ |
| | | public static final String DEPT_NORMAL = "0"; |
| | | |
| | | /** 部门停用状态 */ |
| | | /** |
| | | * 部门停用状态 |
| | | */ |
| | | public static final String DEPT_DISABLE = "1"; |
| | | |
| | | /** 字典正常状态 */ |
| | | /** |
| | | * 字典正常状态 |
| | | */ |
| | | public static final String DICT_NORMAL = "0"; |
| | | |
| | | /** 是否为系统默认(是) */ |
| | | /** |
| | | * 是否为系统默认(是) |
| | | */ |
| | | public static final String YES = "Y"; |
| | | |
| | | /** 是否菜单外链(是) */ |
| | | /** |
| | | * 是否菜单外链(是) |
| | | */ |
| | | public static final String YES_FRAME = "0"; |
| | | |
| | | /** 是否菜单外链(否) */ |
| | | /** |
| | | * 是否菜单外链(否) |
| | | */ |
| | | public static final String NO_FRAME = "1"; |
| | | |
| | | /** 菜单类型(目录) */ |
| | | /** |
| | | * 菜单类型(目录) |
| | | */ |
| | | public static final String TYPE_DIR = "M"; |
| | | |
| | | /** 菜单类型(菜单) */ |
| | | /** |
| | | * 菜单类型(菜单) |
| | | */ |
| | | public static final String TYPE_MENU = "C"; |
| | | |
| | | /** 菜单类型(按钮) */ |
| | | /** |
| | | * 菜单类型(按钮) |
| | | */ |
| | | public static final String TYPE_BUTTON = "F"; |
| | | |
| | | /** Layout组件标识 */ |
| | | /** |
| | | * Layout组件标识 |
| | | */ |
| | | public final static String LAYOUT = "Layout"; |
| | | |
| | | /** ParentView组件标识 */ |
| | | /** |
| | | * ParentView组件标识 |
| | | */ |
| | | public final static String PARENT_VIEW = "ParentView"; |
| | | |
| | | /** InnerLink组件标识 */ |
| | | /** |
| | | * InnerLink组件标识 |
| | | */ |
| | | public final static String INNER_LINK = "InnerLink"; |
| | | |
| | | /** 校验返回结果码 */ |
| | | /** |
| | | * 校验返回结果码 |
| | | */ |
| | | public final static String UNIQUE = "0"; |
| | | public final static String NOT_UNIQUE = "1"; |
| | | |
| | |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | /** |
| | | * web层通用数据处理 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class BaseController |
| | | { |
| | | protected final Logger logger = LoggerFactory.getLogger(this.getClass()); |
| | | public class BaseController { |
| | | |
| | | /** |
| | | * 返回成功 |
| | | */ |
| | | public AjaxResult<Void> success() |
| | | { |
| | | public AjaxResult<Void> success() { |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | /** |
| | | * 返回失败消息 |
| | | */ |
| | | public AjaxResult<Void> error() |
| | | { |
| | | public AjaxResult<Void> error() { |
| | | return AjaxResult.error(); |
| | | } |
| | | |
| | | /** |
| | | * 返回成功消息 |
| | | */ |
| | | public AjaxResult<Void> success(String message) |
| | | { |
| | | public AjaxResult<Void> success(String message) { |
| | | return AjaxResult.success(message); |
| | | } |
| | | |
| | | /** |
| | | * 返回失败消息 |
| | | */ |
| | | public AjaxResult<Void> error(String message) |
| | | { |
| | | public AjaxResult<Void> error(String message) { |
| | | return AjaxResult.error(message); |
| | | } |
| | | |
| | | /** |
| | | * 响应返回结果 |
| | | * |
| | | * |
| | | * @param rows 影响行数 |
| | | * @return 操作结果 |
| | | */ |
| | | protected AjaxResult<Void> toAjax(int rows) |
| | | { |
| | | protected AjaxResult<Void> toAjax(int rows) { |
| | | return rows > 0 ? AjaxResult.success() : AjaxResult.error(); |
| | | } |
| | | |
| | |
| | | * @param result 结果 |
| | | * @return 操作结果 |
| | | */ |
| | | protected AjaxResult<Void> toAjax(boolean result) |
| | | { |
| | | protected AjaxResult<Void> toAjax(boolean result) { |
| | | return result ? success() : error(); |
| | | } |
| | | |
| | | /** |
| | | * 页面跳转 |
| | | */ |
| | | public String redirect(String url) |
| | | { |
| | | public String redirect(String url) { |
| | | return StringUtils.format("redirect:{}", url); |
| | | } |
| | | |
| | | /** |
| | | * 获取用户缓存信息 |
| | | */ |
| | | public LoginUser getLoginUser() |
| | | { |
| | | public LoginUser getLoginUser() { |
| | | return SecurityUtils.getLoginUser(); |
| | | } |
| | | |
| | | /** |
| | | * 获取登录用户id |
| | | */ |
| | | public Long getUserId() |
| | | { |
| | | public Long getUserId() { |
| | | return getLoginUser().getUserId(); |
| | | } |
| | | |
| | | /** |
| | | * 获取登录部门id |
| | | */ |
| | | public Long getDeptId() |
| | | { |
| | | public Long getDeptId() { |
| | | return getLoginUser().getDeptId(); |
| | | } |
| | | |
| | | /** |
| | | * 获取登录用户名 |
| | | */ |
| | | public String getUsername() |
| | | { |
| | | public String getUsername() { |
| | | return getLoginUser().getUsername(); |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 操作状态 |
| | | * |
| | | * @author ruoyi |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum BusinessStatus |
| | | { |
| | | public enum BusinessStatus { |
| | | /** |
| | | * 成功 |
| | | */ |
| | |
| | | |
| | | /** |
| | | * 业务操作类型 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum BusinessType |
| | | { |
| | | public enum BusinessType { |
| | | /** |
| | | * 其它 |
| | | */ |
| | |
| | | * 生成代码 |
| | | */ |
| | | GENCODE, |
| | | |
| | | |
| | | /** |
| | | * 清空数据 |
| | | */ |
| | |
| | | */ |
| | | @AllArgsConstructor |
| | | public enum DataSourceType { |
| | | /** |
| | | * 主库 |
| | | */ |
| | | MASTER("master"), |
| | | /** |
| | | * 主库 |
| | | */ |
| | | MASTER("master"), |
| | | |
| | | /** |
| | | * 从库 |
| | | */ |
| | | SLAVE("slave"); |
| | | /** |
| | | * 从库 |
| | | */ |
| | | SLAVE("slave"); |
| | | |
| | | @Getter |
| | | private final String source; |
| | | @Getter |
| | | private final String source; |
| | | } |
| | |
| | | package com.ruoyi.common.enums; |
| | | |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | import org.springframework.lang.Nullable; |
| | | |
| | | /** |
| | | * 请求方式 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum HttpMethod |
| | | { |
| | | public enum HttpMethod { |
| | | GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; |
| | | |
| | | private static final Map<String, HttpMethod> mappings = new HashMap<>(16); |
| | | |
| | | static |
| | | { |
| | | for (HttpMethod httpMethod : values()) |
| | | { |
| | | static { |
| | | for (HttpMethod httpMethod : values()) { |
| | | mappings.put(httpMethod.name(), httpMethod); |
| | | } |
| | | } |
| | | |
| | | @Nullable |
| | | public static HttpMethod resolve(@Nullable String method) |
| | | { |
| | | public static HttpMethod resolve(@Nullable String method) { |
| | | return (method != null ? mappings.get(method) : null); |
| | | } |
| | | |
| | | public boolean matches(String method) |
| | | { |
| | | public boolean matches(String method) { |
| | | return (this == resolve(method)); |
| | | } |
| | | } |
| | |
| | | * @author ruoyi
|
| | | */
|
| | |
|
| | | public enum LimitType
|
| | | {
|
| | | public enum LimitType {
|
| | | /**
|
| | | * 默认策略全局限流
|
| | | */
|
| | |
| | | |
| | | /** |
| | | * 操作人类别 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum OperatorType |
| | | { |
| | | public enum OperatorType { |
| | | /** |
| | | * 其它 |
| | | */ |
| | |
| | | |
| | | /** |
| | | * 用户状态 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public enum UserStatus |
| | | { |
| | | public enum UserStatus { |
| | | OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除"); |
| | | |
| | | private final String code; |
| | | private final String info; |
| | | |
| | | UserStatus(String code, String info) |
| | | { |
| | | UserStatus(String code, String info) { |
| | | this.code = code; |
| | | this.info = info; |
| | | } |
| | | |
| | | public String getCode() |
| | | { |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public String getInfo() |
| | | { |
| | | public String getInfo() { |
| | | return info; |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 演示模式异常 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class DemoModeException extends RuntimeException |
| | | { |
| | | public class DemoModeException extends RuntimeException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public DemoModeException() |
| | | { |
| | | public DemoModeException() { |
| | | } |
| | | } |
| | |
| | |
|
| | | /**
|
| | | * 全局异常
|
| | | * |
| | | *
|
| | | * @author ruoyi
|
| | | */
|
| | | public class GlobalException extends RuntimeException
|
| | | {
|
| | | public class GlobalException extends RuntimeException {
|
| | |
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | |
| | |
|
| | | /**
|
| | | * 错误明细,内部调试错误
|
| | | *
|
| | | * <p>
|
| | | * 和 {@link CommonResult#getDetailMessage()} 一致的设计
|
| | | */
|
| | | private String detailMessage;
|
| | |
| | | /**
|
| | | * 空构造方法,避免反序列化问题
|
| | | */
|
| | | public GlobalException()
|
| | | {
|
| | | public GlobalException() {
|
| | | }
|
| | |
|
| | | public GlobalException(String message)
|
| | | {
|
| | | public GlobalException(String message) {
|
| | | this.message = message;
|
| | | }
|
| | |
|
| | | public String getDetailMessage()
|
| | | {
|
| | | public String getDetailMessage() {
|
| | | return detailMessage;
|
| | | }
|
| | |
|
| | | public GlobalException setDetailMessage(String detailMessage)
|
| | | {
|
| | | public GlobalException setDetailMessage(String detailMessage) {
|
| | | this.detailMessage = detailMessage;
|
| | | return this;
|
| | | }
|
| | |
|
| | | public String getMessage()
|
| | | {
|
| | | @Override
|
| | | public String getMessage() {
|
| | | return message;
|
| | | }
|
| | |
|
| | | public GlobalException setMessage(String message)
|
| | | {
|
| | | public GlobalException setMessage(String message) {
|
| | | this.message = message;
|
| | | return this;
|
| | | }
|
| | |
| | |
|
| | | /**
|
| | | * 业务异常
|
| | | * |
| | | *
|
| | | * @author ruoyi
|
| | | */
|
| | | public final class ServiceException extends RuntimeException
|
| | | {
|
| | | public final class ServiceException extends RuntimeException {
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | | /**
|
| | |
| | |
|
| | | /**
|
| | | * 错误明细,内部调试错误
|
| | | *
|
| | | * <p>
|
| | | * 和 {@link CommonResult#getDetailMessage()} 一致的设计
|
| | | */
|
| | | private String detailMessage;
|
| | |
| | | /**
|
| | | * 空构造方法,避免反序列化问题
|
| | | */
|
| | | public ServiceException()
|
| | | {
|
| | | public ServiceException() {
|
| | | }
|
| | |
|
| | | public ServiceException(String message)
|
| | | {
|
| | | public ServiceException(String message) {
|
| | | this.message = message;
|
| | | }
|
| | |
|
| | | public ServiceException(String message, Integer code)
|
| | | {
|
| | | public ServiceException(String message, Integer code) {
|
| | | this.message = message;
|
| | | this.code = code;
|
| | | }
|
| | |
|
| | | public String getDetailMessage()
|
| | | {
|
| | | public String getDetailMessage() {
|
| | | return detailMessage;
|
| | | }
|
| | |
|
| | | public String getMessage()
|
| | | {
|
| | | @Override
|
| | | public String getMessage() {
|
| | | return message;
|
| | | }
|
| | |
|
| | | public Integer getCode()
|
| | | {
|
| | | public Integer getCode() {
|
| | | return code;
|
| | | }
|
| | |
|
| | | public ServiceException setMessage(String message)
|
| | | {
|
| | | public ServiceException setMessage(String message) {
|
| | | this.message = message;
|
| | | return this;
|
| | | }
|
| | |
|
| | | public ServiceException setDetailMessage(String detailMessage)
|
| | | {
|
| | | public ServiceException setDetailMessage(String detailMessage) {
|
| | | this.detailMessage = detailMessage;
|
| | | return this;
|
| | | }
|
| | |
| | | |
| | | /** |
| | | * 工具类异常 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class UtilException extends RuntimeException |
| | | { |
| | | public class UtilException extends RuntimeException { |
| | | private static final long serialVersionUID = 8247610319171014183L; |
| | | |
| | | public UtilException(Throwable e) |
| | | { |
| | | public UtilException(Throwable e) { |
| | | super(e.getMessage(), e); |
| | | } |
| | | |
| | | public UtilException(String message) |
| | | { |
| | | public UtilException(String message) { |
| | | super(message); |
| | | } |
| | | |
| | | public UtilException(String message, Throwable throwable) |
| | | { |
| | | public UtilException(String message, Throwable throwable) { |
| | | super(message, throwable); |
| | | } |
| | | } |
| | |
| | | |
| | | import com.ruoyi.common.utils.MessageUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import lombok.*; |
| | | |
| | | /** |
| | | * 基础异常 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class BaseException extends RuntimeException |
| | | { |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @NoArgsConstructor |
| | | public class BaseException extends RuntimeException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | /** |
| | |
| | | */ |
| | | private String defaultMessage; |
| | | |
| | | public BaseException(String module, String code, Object[] args, String defaultMessage) |
| | | { |
| | | public BaseException(String module, String code, Object[] args, String defaultMessage) { |
| | | this.module = module; |
| | | this.code = code; |
| | | this.args = args; |
| | | this.defaultMessage = defaultMessage; |
| | | } |
| | | |
| | | public BaseException(String module, String code, Object[] args) |
| | | { |
| | | public BaseException(String module, String code, Object[] args) { |
| | | this(module, code, args, null); |
| | | } |
| | | |
| | | public BaseException(String module, String defaultMessage) |
| | | { |
| | | public BaseException(String module, String defaultMessage) { |
| | | this(module, null, null, defaultMessage); |
| | | } |
| | | |
| | | public BaseException(String code, Object[] args) |
| | | { |
| | | public BaseException(String code, Object[] args) { |
| | | this(null, code, args, null); |
| | | } |
| | | |
| | | public BaseException(String defaultMessage) |
| | | { |
| | | public BaseException(String defaultMessage) { |
| | | this(null, null, null, defaultMessage); |
| | | } |
| | | |
| | | @Override |
| | | public String getMessage() |
| | | { |
| | | public String getMessage() { |
| | | String message = null; |
| | | if (!StringUtils.isEmpty(code)) |
| | | { |
| | | if (!StringUtils.isEmpty(code)) { |
| | | message = MessageUtils.message(code, args); |
| | | } |
| | | if (message == null) |
| | | { |
| | | if (message == null) { |
| | | message = defaultMessage; |
| | | } |
| | | return message; |
| | | } |
| | | |
| | | public String getModule() |
| | | { |
| | | return module; |
| | | } |
| | | |
| | | public String getCode() |
| | | { |
| | | return code; |
| | | } |
| | | |
| | | public Object[] getArgs() |
| | | { |
| | | return args; |
| | | } |
| | | |
| | | public String getDefaultMessage() |
| | | { |
| | | return defaultMessage; |
| | | } |
| | | } |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class FileException extends BaseException |
| | | { |
| | | public class FileException extends BaseException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public FileException(String code, Object[] args) |
| | | { |
| | | public FileException(String code, Object[] args) { |
| | | super("file", code, args, null); |
| | | } |
| | | |
| | |
| | | |
| | | /** |
| | | * 文件名称超长限制异常类 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class FileNameLengthLimitExceededException extends FileException |
| | | { |
| | | public class FileNameLengthLimitExceededException extends FileException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public FileNameLengthLimitExceededException(int defaultFileNameLength) |
| | | { |
| | | super("upload.filename.exceed.length", new Object[] { defaultFileNameLength }); |
| | | public FileNameLengthLimitExceededException(int defaultFileNameLength) { |
| | | super("upload.filename.exceed.length", new Object[]{defaultFileNameLength}); |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 文件名大小限制异常类 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class FileSizeLimitExceededException extends FileException |
| | | { |
| | | public class FileSizeLimitExceededException extends FileException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public FileSizeLimitExceededException(long defaultMaxSize) |
| | | { |
| | | super("upload.exceed.maxSize", new Object[] { defaultMaxSize }); |
| | | public FileSizeLimitExceededException(long defaultMaxSize) { |
| | | super("upload.exceed.maxSize", new Object[]{defaultMaxSize}); |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.common.exception.file; |
| | | |
| | | import java.util.Arrays; |
| | | import lombok.*; |
| | | import org.apache.commons.fileupload.FileUploadException; |
| | | |
| | | import java.util.Arrays; |
| | | |
| | | /** |
| | | * 文件上传 误异常类 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class InvalidExtensionException extends FileUploadException |
| | | { |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @NoArgsConstructor |
| | | public class InvalidExtensionException extends FileUploadException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | private String[] allowedExtension; |
| | | private String extension; |
| | | private String filename; |
| | | |
| | | public InvalidExtensionException(String[] allowedExtension, String extension, String filename) |
| | | { |
| | | public InvalidExtensionException(String[] allowedExtension, String extension, String filename) { |
| | | super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]"); |
| | | this.allowedExtension = allowedExtension; |
| | | this.extension = extension; |
| | | this.filename = filename; |
| | | } |
| | | |
| | | public String[] getAllowedExtension() |
| | | { |
| | | return allowedExtension; |
| | | } |
| | | |
| | | public String getExtension() |
| | | { |
| | | return extension; |
| | | } |
| | | |
| | | public String getFilename() |
| | | { |
| | | return filename; |
| | | } |
| | | |
| | | public static class InvalidImageExtensionException extends InvalidExtensionException |
| | | { |
| | | public static class InvalidImageExtensionException extends InvalidExtensionException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) |
| | | { |
| | | public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) { |
| | | super(allowedExtension, extension, filename); |
| | | } |
| | | } |
| | | |
| | | public static class InvalidFlashExtensionException extends InvalidExtensionException |
| | | { |
| | | public static class InvalidFlashExtensionException extends InvalidExtensionException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) |
| | | { |
| | | public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) { |
| | | super(allowedExtension, extension, filename); |
| | | } |
| | | } |
| | | |
| | | public static class InvalidMediaExtensionException extends InvalidExtensionException |
| | | { |
| | | public static class InvalidMediaExtensionException extends InvalidExtensionException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) |
| | | { |
| | | public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) { |
| | | super(allowedExtension, extension, filename); |
| | | } |
| | | } |
| | | |
| | | public static class InvalidVideoExtensionException extends InvalidExtensionException |
| | | { |
| | | public static class InvalidVideoExtensionException extends InvalidExtensionException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) |
| | | { |
| | | public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename) { |
| | | super(allowedExtension, extension, filename); |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 验证码错误异常类 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class CaptchaException extends UserException |
| | | { |
| | | public class CaptchaException extends UserException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public CaptchaException() |
| | | { |
| | | public CaptchaException() { |
| | | super("user.jcaptcha.error", null); |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 验证码失效异常类 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class CaptchaExpireException extends UserException |
| | | { |
| | | public class CaptchaExpireException extends UserException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public CaptchaExpireException() |
| | | { |
| | | public CaptchaExpireException() { |
| | | super("user.jcaptcha.expire", null); |
| | | } |
| | | } |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class UserException extends BaseException |
| | | { |
| | | public class UserException extends BaseException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public UserException(String code, Object[] args) |
| | | { |
| | | public UserException(String code, Object[] args) { |
| | | super("user", code, args, null); |
| | | } |
| | | } |
| | |
| | | |
| | | /** |
| | | * 用户密码不正确或不符合规范异常类 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class UserPasswordNotMatchException extends UserException |
| | | { |
| | | public class UserPasswordNotMatchException extends UserException { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | public UserPasswordNotMatchException() |
| | | { |
| | | public UserPasswordNotMatchException() { |
| | | super("user.password.not.match", null); |
| | | } |
| | | } |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class RepeatableFilter implements Filter |
| | | { |
| | | public class RepeatableFilter implements Filter { |
| | | @Override |
| | | public void init(FilterConfig filterConfig) throws ServletException |
| | | { |
| | | public void init(FilterConfig filterConfig) throws ServletException { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
| | | throws IOException, ServletException |
| | | { |
| | | throws IOException, ServletException { |
| | | ServletRequest requestWrapper = null; |
| | | if (request instanceof HttpServletRequest |
| | | && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) |
| | | { |
| | | && StringUtils.startsWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE)) { |
| | | requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response); |
| | | } |
| | | if (null == requestWrapper) |
| | | { |
| | | if (null == requestWrapper) { |
| | | chain.doFilter(request, response); |
| | | } |
| | | else |
| | | { |
| | | } else { |
| | | chain.doFilter(requestWrapper, response); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() |
| | | { |
| | | public void destroy() { |
| | | |
| | | } |
| | | } |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper |
| | | { |
| | | public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper { |
| | | private final byte[] body; |
| | | |
| | | public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException |
| | | { |
| | | public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException { |
| | | super(request); |
| | | request.setCharacterEncoding("UTF-8"); |
| | | response.setCharacterEncoding("UTF-8"); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public BufferedReader getReader() throws IOException |
| | | { |
| | | public BufferedReader getReader() throws IOException { |
| | | return new BufferedReader(new InputStreamReader(getInputStream())); |
| | | } |
| | | |
| | | @Override |
| | | public ServletInputStream getInputStream() throws IOException |
| | | { |
| | | public ServletInputStream getInputStream() throws IOException { |
| | | final ByteArrayInputStream bais = new ByteArrayInputStream(body); |
| | | return new ServletInputStream() |
| | | { |
| | | return new ServletInputStream() { |
| | | @Override |
| | | public int read() throws IOException |
| | | { |
| | | public int read() throws IOException { |
| | | return bais.read(); |
| | | } |
| | | |
| | | @Override |
| | | public int available() throws IOException |
| | | { |
| | | public int available() throws IOException { |
| | | return body.length; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isFinished() |
| | | { |
| | | public boolean isFinished() { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isReady() |
| | | { |
| | | public boolean isReady() { |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | public void setReadListener(ReadListener readListener) |
| | | { |
| | | public void setReadListener(ReadListener readListener) { |
| | | |
| | | } |
| | | }; |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class XssFilter implements Filter |
| | | { |
| | | public class XssFilter implements Filter { |
| | | /** |
| | | * 排除链接 |
| | | */ |
| | | public List<String> excludes = new ArrayList<>(); |
| | | |
| | | @Override |
| | | public void init(FilterConfig filterConfig) throws ServletException |
| | | { |
| | | public void init(FilterConfig filterConfig) throws ServletException { |
| | | String tempExcludes = filterConfig.getInitParameter("excludes"); |
| | | if (StringUtils.isNotEmpty(tempExcludes)) |
| | | { |
| | | if (StringUtils.isNotEmpty(tempExcludes)) { |
| | | String[] url = tempExcludes.split(","); |
| | | for (int i = 0; url != null && i < url.length; i++) |
| | | { |
| | | for (int i = 0; url != null && i < url.length; i++) { |
| | | excludes.add(url[i]); |
| | | } |
| | | } |
| | |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
| | | throws IOException, ServletException |
| | | { |
| | | throws IOException, ServletException { |
| | | HttpServletRequest req = (HttpServletRequest) request; |
| | | HttpServletResponse resp = (HttpServletResponse) response; |
| | | if (handleExcludeURL(req, resp)) |
| | | { |
| | | if (handleExcludeURL(req, resp)) { |
| | | chain.doFilter(request, response); |
| | | return; |
| | | } |
| | |
| | | chain.doFilter(xssRequest, response); |
| | | } |
| | | |
| | | private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) |
| | | { |
| | | private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) { |
| | | String url = request.getServletPath(); |
| | | String method = request.getMethod(); |
| | | // GET DELETE 不过滤 |
| | | if (method == null || method.matches("GET") || method.matches("DELETE")) |
| | | { |
| | | if (method == null || method.matches("GET") || method.matches("DELETE")) { |
| | | return true; |
| | | } |
| | | return StringUtils.matches(url, excludes); |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() |
| | | { |
| | | public void destroy() { |
| | | |
| | | } |
| | | } |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper |
| | | { |
| | | public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { |
| | | /** |
| | | * @param request |
| | | */ |
| | | public XssHttpServletRequestWrapper(HttpServletRequest request) |
| | | { |
| | | public XssHttpServletRequestWrapper(HttpServletRequest request) { |
| | | super(request); |
| | | } |
| | | |
| | | @Override |
| | | public String[] getParameterValues(String name) |
| | | { |
| | | public String[] getParameterValues(String name) { |
| | | String[] values = super.getParameterValues(name); |
| | | if (values != null) |
| | | { |
| | | if (values != null) { |
| | | int length = values.length; |
| | | String[] escapseValues = new String[length]; |
| | | for (int i = 0; i < length; i++) |
| | | { |
| | | for (int i = 0; i < length; i++) { |
| | | // 防xss攻击和过滤前后空格 |
| | | escapseValues[i] = HtmlUtil.cleanHtmlTag(values[i]).trim(); |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | public ServletInputStream getInputStream() throws IOException |
| | | { |
| | | public ServletInputStream getInputStream() throws IOException { |
| | | // 非json类型,直接返回 |
| | | if (!isJsonRequest()) |
| | | { |
| | | if (!isJsonRequest()) { |
| | | return super.getInputStream(); |
| | | } |
| | | |
| | | // 为空,直接返回 |
| | | String json = IoUtil.read(super.getInputStream(), StandardCharsets.UTF_8); |
| | | if (StringUtils.isEmpty(json)) |
| | | { |
| | | if (StringUtils.isEmpty(json)) { |
| | | return super.getInputStream(); |
| | | } |
| | | |
| | |
| | | json = HtmlUtil.cleanHtmlTag(json).trim(); |
| | | byte[] jsonBytes = json.getBytes(StandardCharsets.UTF_8); |
| | | final ByteArrayInputStream bis = IoUtil.toStream(jsonBytes); |
| | | return new ServletInputStream() |
| | | { |
| | | return new ServletInputStream() { |
| | | @Override |
| | | public boolean isFinished() |
| | | { |
| | | public boolean isFinished() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public boolean isReady() |
| | | { |
| | | public boolean isReady() { |
| | | return true; |
| | | } |
| | | |
| | | @Override |
| | | public int available() throws IOException |
| | | { |
| | | public int available() throws IOException { |
| | | return jsonBytes.length; |
| | | } |
| | | |
| | | @Override |
| | | public void setReadListener(ReadListener readListener) |
| | | { |
| | | public void setReadListener(ReadListener readListener) { |
| | | } |
| | | |
| | | @Override |
| | | public int read() throws IOException |
| | | { |
| | | public int read() throws IOException { |
| | | return bis.read(); |
| | | } |
| | | }; |
| | |
| | | * |
| | | * @param request |
| | | */ |
| | | public boolean isJsonRequest() |
| | | { |
| | | public boolean isJsonRequest() { |
| | | String header = super.getHeader(HttpHeaders.CONTENT_TYPE); |
| | | return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE); |
| | | } |
| | |
| | | */ |
| | | public class BeanCopyUtils { |
| | | |
| | | /** |
| | | * 单对象基于class创建拷贝 |
| | | * |
| | | * @param source 数据来源实体 |
| | | * @param copyOptions copy条件 |
| | | * @param desc 描述对象 转换后的对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V oneCopy(T source, CopyOptions copyOptions, Class<V> desc) { |
| | | V v = ReflectUtil.newInstanceIfPossible(desc); |
| | | return oneCopy(source, copyOptions, v); |
| | | } |
| | | /** |
| | | * 单对象基于class创建拷贝 |
| | | * |
| | | * @param source 数据来源实体 |
| | | * @param copyOptions copy条件 |
| | | * @param desc 描述对象 转换后的对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V oneCopy(T source, CopyOptions copyOptions, Class<V> desc) { |
| | | V v = ReflectUtil.newInstanceIfPossible(desc); |
| | | return oneCopy(source, copyOptions, v); |
| | | } |
| | | |
| | | /** |
| | | * 单对象基于对象创建拷贝 |
| | | * |
| | | * @param source 数据来源实体 |
| | | * @param copyOptions copy条件 |
| | | * @param desc 转换后的对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V oneCopy(T source, CopyOptions copyOptions, V desc) { |
| | | if (ObjectUtil.isNull(source)) { |
| | | return null; |
| | | } |
| | | return BeanCopier.create(source, desc, copyOptions).copy(); |
| | | } |
| | | /** |
| | | * 单对象基于对象创建拷贝 |
| | | * |
| | | * @param source 数据来源实体 |
| | | * @param copyOptions copy条件 |
| | | * @param desc 转换后的对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> V oneCopy(T source, CopyOptions copyOptions, V desc) { |
| | | if (ObjectUtil.isNull(source)) { |
| | | return null; |
| | | } |
| | | return BeanCopier.create(source, desc, copyOptions).copy(); |
| | | } |
| | | |
| | | /** |
| | | * 列表对象基于class创建拷贝 |
| | | * |
| | | * @param sourceList 数据来源实体列表 |
| | | * @param copyOptions copy条件 |
| | | * @param desc 描述对象 转换后的对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> List<V> listCopy(List<T> sourceList, CopyOptions copyOptions, Class<V> desc) { |
| | | if (ObjectUtil.isNull(sourceList)) { |
| | | return null; |
| | | } |
| | | if (CollUtil.isEmpty(sourceList)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return sourceList.stream() |
| | | .map(source -> oneCopy(source, copyOptions, desc)) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | /** |
| | | * 列表对象基于class创建拷贝 |
| | | * |
| | | * @param sourceList 数据来源实体列表 |
| | | * @param copyOptions copy条件 |
| | | * @param desc 描述对象 转换后的对象 |
| | | * @return desc |
| | | */ |
| | | public static <T, V> List<V> listCopy(List<T> sourceList, CopyOptions copyOptions, Class<V> desc) { |
| | | if (ObjectUtil.isNull(sourceList)) { |
| | | return null; |
| | | } |
| | | if (CollUtil.isEmpty(sourceList)) { |
| | | return CollUtil.newArrayList(); |
| | | } |
| | | return sourceList.stream() |
| | | .map(source -> oneCopy(source, copyOptions, desc)) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.common.utils; |
| | | |
| | | import org.apache.commons.lang3.time.DateFormatUtils; |
| | | |
| | | import java.lang.management.ManagementFactory; |
| | | import java.text.ParseException; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import org.apache.commons.lang3.time.DateFormatUtils; |
| | | |
| | | /** |
| | | * 时间工具类 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class DateUtils extends org.apache.commons.lang3.time.DateUtils |
| | | { |
| | | public class DateUtils extends org.apache.commons.lang3.time.DateUtils { |
| | | |
| | | public static String YYYY = "yyyy"; |
| | | |
| | | public static String YYYY_MM = "yyyy-MM"; |
| | |
| | | public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; |
| | | |
| | | public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; |
| | | |
| | | |
| | | private static String[] parsePatterns = { |
| | | "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", |
| | | "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", |
| | | "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", |
| | | "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; |
| | | |
| | | /** |
| | | * 获取当前Date型日期 |
| | | * |
| | | * |
| | | * @return Date() 当前日期 |
| | | */ |
| | | public static Date getNowDate() |
| | | { |
| | | public static Date getNowDate() { |
| | | return new Date(); |
| | | } |
| | | |
| | | /** |
| | | * 获取当前日期, 默认格式为yyyy-MM-dd |
| | | * |
| | | * |
| | | * @return String |
| | | */ |
| | | public static String getDate() |
| | | { |
| | | public static String getDate() { |
| | | return dateTimeNow(YYYY_MM_DD); |
| | | } |
| | | |
| | | public static final String getTime() |
| | | { |
| | | public static final String getTime() { |
| | | return dateTimeNow(YYYY_MM_DD_HH_MM_SS); |
| | | } |
| | | |
| | | public static final String dateTimeNow() |
| | | { |
| | | public static final String dateTimeNow() { |
| | | return dateTimeNow(YYYYMMDDHHMMSS); |
| | | } |
| | | |
| | | public static final String dateTimeNow(final String format) |
| | | { |
| | | public static final String dateTimeNow(final String format) { |
| | | return parseDateToStr(format, new Date()); |
| | | } |
| | | |
| | | public static final String dateTime(final Date date) |
| | | { |
| | | public static final String dateTime(final Date date) { |
| | | return parseDateToStr(YYYY_MM_DD, date); |
| | | } |
| | | |
| | | public static final String parseDateToStr(final String format, final Date date) |
| | | { |
| | | public static final String parseDateToStr(final String format, final Date date) { |
| | | return new SimpleDateFormat(format).format(date); |
| | | } |
| | | |
| | | public static final Date dateTime(final String format, final String ts) |
| | | { |
| | | try |
| | | { |
| | | public static final Date dateTime(final String format, final String ts) { |
| | | try { |
| | | return new SimpleDateFormat(format).parse(ts); |
| | | } |
| | | catch (ParseException e) |
| | | { |
| | | } catch (ParseException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 日期路径 即年/月/日 如2018/08/08 |
| | | */ |
| | | public static final String datePath() |
| | | { |
| | | public static final String datePath() { |
| | | Date now = new Date(); |
| | | return DateFormatUtils.format(now, "yyyy/MM/dd"); |
| | | } |
| | |
| | | /** |
| | | * 日期路径 即年/月/日 如20180808 |
| | | */ |
| | | public static final String dateTime() |
| | | { |
| | | public static final String dateTime() { |
| | | Date now = new Date(); |
| | | return DateFormatUtils.format(now, "yyyyMMdd"); |
| | | } |
| | |
| | | /** |
| | | * 日期型字符串转化为日期 格式 |
| | | */ |
| | | public static Date parseDate(Object str) |
| | | { |
| | | if (str == null) |
| | | { |
| | | public static Date parseDate(Object str) { |
| | | if (str == null) { |
| | | return null; |
| | | } |
| | | try |
| | | { |
| | | try { |
| | | return parseDate(str.toString(), parsePatterns); |
| | | } |
| | | catch (ParseException e) |
| | | { |
| | | } catch (ParseException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取服务器启动时间 |
| | | */ |
| | | public static Date getServerStartDate() |
| | | { |
| | | public static Date getServerStartDate() { |
| | | long time = ManagementFactory.getRuntimeMXBean().getStartTime(); |
| | | return new Date(time); |
| | | } |
| | |
| | | /** |
| | | * 计算两个时间差 |
| | | */ |
| | | public static String getDatePoor(Date endDate, Date nowDate) |
| | | { |
| | | public static String getDatePoor(Date endDate, Date nowDate) { |
| | | long nd = 1000 * 24 * 60 * 60; |
| | | long nh = 1000 * 60 * 60; |
| | | long nm = 1000 * 60; |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class DictUtils |
| | | { |
| | | public class DictUtils { |
| | | |
| | | /** |
| | | * 分隔符 |
| | | */ |
| | |
| | | /** |
| | | * 设置字典缓存 |
| | | * |
| | | * @param key 参数键 |
| | | * @param key 参数键 |
| | | * @param dictDatas 字典数据列表 |
| | | */ |
| | | public static void setDictCache(String key, List<SysDictData> dictDatas) |
| | | { |
| | | public static void setDictCache(String key, List<SysDictData> dictDatas) { |
| | | RedisUtils.setCacheObject(getCacheKey(key), dictDatas); |
| | | } |
| | | |
| | |
| | | * @param key 参数键 |
| | | * @return dictDatas 字典数据列表 |
| | | */ |
| | | public static List<SysDictData> getDictCache(String key) |
| | | { |
| | | public static List<SysDictData> getDictCache(String key) { |
| | | Object cacheObj = RedisUtils.getCacheObject(getCacheKey(key)); |
| | | if (StringUtils.isNotNull(cacheObj)) |
| | | { |
| | | List<SysDictData> dictDatas = (List<SysDictData>)cacheObj; |
| | | if (StringUtils.isNotNull(cacheObj)) { |
| | | List<SysDictData> dictDatas = (List<SysDictData>) cacheObj; |
| | | return dictDatas; |
| | | } |
| | | return null; |
| | |
| | | /** |
| | | * 根据字典类型和字典值获取字典标签 |
| | | * |
| | | * @param dictType 字典类型 |
| | | * @param dictType 字典类型 |
| | | * @param dictValue 字典值 |
| | | * @return 字典标签 |
| | | */ |
| | | public static String getDictLabel(String dictType, String dictValue) |
| | | { |
| | | public static String getDictLabel(String dictType, String dictValue) { |
| | | return getDictLabel(dictType, dictValue, SEPARATOR); |
| | | } |
| | | |
| | | /** |
| | | * 根据字典类型和字典标签获取字典值 |
| | | * |
| | | * @param dictType 字典类型 |
| | | * @param dictType 字典类型 |
| | | * @param dictLabel 字典标签 |
| | | * @return 字典值 |
| | | */ |
| | | public static String getDictValue(String dictType, String dictLabel) |
| | | { |
| | | public static String getDictValue(String dictType, String dictLabel) { |
| | | return getDictValue(dictType, dictLabel, SEPARATOR); |
| | | } |
| | | |
| | | /** |
| | | * 根据字典类型和字典值获取字典标签 |
| | | * |
| | | * @param dictType 字典类型 |
| | | * @param dictType 字典类型 |
| | | * @param dictValue 字典值 |
| | | * @param separator 分隔符 |
| | | * @return 字典标签 |
| | | */ |
| | | public static String getDictLabel(String dictType, String dictValue, String separator) |
| | | { |
| | | public static String getDictLabel(String dictType, String dictValue, String separator) { |
| | | StringBuilder propertyString = new StringBuilder(); |
| | | List<SysDictData> datas = getDictCache(dictType); |
| | | |
| | | if (StringUtils.containsAny(dictValue, separator) && CollUtil.isNotEmpty(datas)) |
| | | { |
| | | for (SysDictData dict : datas) |
| | | { |
| | | for (String value : dictValue.split(separator)) |
| | | { |
| | | if (value.equals(dict.getDictValue())) |
| | | { |
| | | if (StringUtils.containsAny(dictValue, separator) && CollUtil.isNotEmpty(datas)) { |
| | | for (SysDictData dict : datas) { |
| | | for (String value : dictValue.split(separator)) { |
| | | if (value.equals(dict.getDictValue())) { |
| | | propertyString.append(dict.getDictLabel() + separator); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | for (SysDictData dict : datas) |
| | | { |
| | | if (dictValue.equals(dict.getDictValue())) |
| | | { |
| | | } else { |
| | | for (SysDictData dict : datas) { |
| | | if (dictValue.equals(dict.getDictValue())) { |
| | | return dict.getDictLabel(); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 根据字典类型和字典标签获取字典值 |
| | | * |
| | | * @param dictType 字典类型 |
| | | * @param dictType 字典类型 |
| | | * @param dictLabel 字典标签 |
| | | * @param separator 分隔符 |
| | | * @return 字典值 |
| | | */ |
| | | public static String getDictValue(String dictType, String dictLabel, String separator) |
| | | { |
| | | public static String getDictValue(String dictType, String dictLabel, String separator) { |
| | | StringBuilder propertyString = new StringBuilder(); |
| | | List<SysDictData> datas = getDictCache(dictType); |
| | | |
| | | if (StringUtils.containsAny(dictLabel, separator) && CollUtil.isNotEmpty(datas)) |
| | | { |
| | | for (SysDictData dict : datas) |
| | | { |
| | | for (String label : dictLabel.split(separator)) |
| | | { |
| | | if (label.equals(dict.getDictLabel())) |
| | | { |
| | | if (StringUtils.containsAny(dictLabel, separator) && CollUtil.isNotEmpty(datas)) { |
| | | for (SysDictData dict : datas) { |
| | | for (String label : dictLabel.split(separator)) { |
| | | if (label.equals(dict.getDictLabel())) { |
| | | propertyString.append(dict.getDictValue() + separator); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | for (SysDictData dict : datas) |
| | | { |
| | | if (dictLabel.equals(dict.getDictLabel())) |
| | | { |
| | | } else { |
| | | for (SysDictData dict : datas) { |
| | | if (dictLabel.equals(dict.getDictLabel())) { |
| | | return dict.getDictValue(); |
| | | } |
| | | } |
| | |
| | | * |
| | | * @param key 字典键 |
| | | */ |
| | | public static void removeDictCache(String key) |
| | | { |
| | | public static void removeDictCache(String key) { |
| | | RedisUtils.deleteObject(getCacheKey(key)); |
| | | } |
| | | |
| | | /** |
| | | * 清空字典缓存 |
| | | */ |
| | | public static void clearDictCache() |
| | | { |
| | | public static void clearDictCache() { |
| | | Collection<String> keys = RedisUtils.keys(Constants.SYS_DICT_KEY + "*"); |
| | | RedisUtils.deleteObject(keys); |
| | | } |
| | |
| | | * @param configKey 参数键 |
| | | * @return 缓存键key |
| | | */ |
| | | public static String getCacheKey(String configKey) |
| | | { |
| | | public static String getCacheKey(String configKey) { |
| | | return Constants.SYS_DICT_KEY + configKey; |
| | | } |
| | | } |
| | |
| | | private static ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class); |
| | | |
| | | public static String toJsonString(Object object) { |
| | | if (StringUtils.isNull(object)) { |
| | | return null; |
| | | } |
| | | if (StringUtils.isNull(object)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return objectMapper.writeValueAsString(object); |
| | | } catch (JsonProcessingException e) { |
| | |
| | | } |
| | | |
| | | public static <T> T parseObject(String text, TypeReference<T> typeReference) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return objectMapper.readValue(text, typeReference); |
| | | } catch (IOException e) { |
| | |
| | | } |
| | | } |
| | | |
| | | public static <T> Map<String, T> parseMap(String text) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return objectMapper.readValue(text, new TypeReference<Map<String, T>>() {}); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | public static <T> Map<String, T> parseMap(String text) { |
| | | if (StringUtils.isBlank(text)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return objectMapper.readValue(text, new TypeReference<Map<String, T>>() { |
| | | }); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | public static <T> List<T> parseArray(String text, Class<T> clazz) { |
| | | if (StringUtils.isEmpty(text)) { |
| | |
| | | package com.ruoyi.common.utils; |
| | | |
| | | import com.ruoyi.common.utils.spring.SpringUtils; |
| | | import org.springframework.context.MessageSource; |
| | | import org.springframework.context.i18n.LocaleContextHolder; |
| | | import com.ruoyi.common.utils.spring.SpringUtils; |
| | | |
| | | /** |
| | | * 获取i18n资源文件 |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class MessageUtils |
| | | { |
| | | public class MessageUtils { |
| | | /** |
| | | * 根据消息键和参数 获取消息 委托给spring messageSource |
| | | * |
| | |
| | | * @param args 参数 |
| | | * @return 获取国际化翻译值 |
| | | */ |
| | | public static String message(String code, Object... args) |
| | | { |
| | | public static String message(String code, Object... args) { |
| | | MessageSource messageSource = SpringUtils.getBean(MessageSource.class); |
| | | return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); |
| | | } |
| | |
| | | |
| | | /** |
| | | * 构建 plus 分页对象 |
| | | * |
| | | * @param <T> domain 实体 |
| | | * @param <K> vo 实体 |
| | | * @return 分页对象 |
| | |
| | | return page; |
| | | } |
| | | |
| | | public static <T> Page<T> buildPage() { |
| | | return buildPage(null, null); |
| | | } |
| | | public static <T> Page<T> buildPage() { |
| | | return buildPage(null, null); |
| | | } |
| | | |
| | | /** |
| | | * 构建 MP 普通分页对象 |
| | | * |
| | | * @param <T> domain 实体 |
| | | * @return 分页对象 |
| | | */ |
| | |
| | | } |
| | | if (StringUtils.isNotBlank(orderByColumn)) { |
| | | String orderBy = SqlUtil.escapeOrderBySql(orderByColumn); |
| | | orderBy = StringUtils.toUnderScoreCase(orderBy); |
| | | if ("asc".equals(isAsc)) { |
| | | orderBy = StringUtils.toUnderScoreCase(orderBy); |
| | | if ("asc".equals(isAsc)) { |
| | | return OrderItem.asc(orderBy); |
| | | } else if ("desc".equals(isAsc)) { |
| | | return OrderItem.desc(orderBy); |
| | |
| | | package com.ruoyi.common.utils; |
| | | |
| | | import cn.hutool.http.HttpStatus; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
| | | import com.ruoyi.common.core.domain.model.LoginUser; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | |
| | | /** |
| | | * 安全服务工具类 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class SecurityUtils |
| | | { |
| | | public class SecurityUtils { |
| | | |
| | | /** |
| | | * 用户ID |
| | | **/ |
| | | public static Long getUserId() |
| | | { |
| | | try |
| | | { |
| | | public static Long getUserId() { |
| | | try { |
| | | return getLoginUser().getUserId(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } catch (Exception e) { |
| | | throw new ServiceException("获取用户ID异常", HttpStatus.HTTP_UNAUTHORIZED); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 获取部门ID |
| | | **/ |
| | | public static Long getDeptId() |
| | | { |
| | | try |
| | | { |
| | | public static Long getDeptId() { |
| | | try { |
| | | return getLoginUser().getDeptId(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } catch (Exception e) { |
| | | throw new ServiceException("获取部门ID异常", HttpStatus.HTTP_UNAUTHORIZED); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 获取用户账户 |
| | | **/ |
| | | public static String getUsername() |
| | | { |
| | | try |
| | | { |
| | | public static String getUsername() { |
| | | try { |
| | | return getLoginUser().getUsername(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } catch (Exception e) { |
| | | throw new ServiceException("获取用户账户异常", HttpStatus.HTTP_UNAUTHORIZED); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 获取用户 |
| | | **/ |
| | | public static LoginUser getLoginUser() |
| | | { |
| | | try |
| | | { |
| | | public static LoginUser getLoginUser() { |
| | | try { |
| | | return (LoginUser) getAuthentication().getPrincipal(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } catch (Exception e) { |
| | | throw new ServiceException("获取用户信息异常", HttpStatus.HTTP_UNAUTHORIZED); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 获取Authentication |
| | | */ |
| | | public static Authentication getAuthentication() |
| | | { |
| | | public static Authentication getAuthentication() { |
| | | return SecurityContextHolder.getContext().getAuthentication(); |
| | | } |
| | | |
| | |
| | | * @param password 密码 |
| | | * @return 加密字符串 |
| | | */ |
| | | public static String encryptPassword(String password) |
| | | { |
| | | public static String encryptPassword(String password) { |
| | | BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); |
| | | return passwordEncoder.encode(password); |
| | | } |
| | |
| | | /** |
| | | * 判断密码是否相同 |
| | | * |
| | | * @param rawPassword 真实密码 |
| | | * @param rawPassword 真实密码 |
| | | * @param encodedPassword 加密后字符 |
| | | * @return 结果 |
| | | */ |
| | | public static boolean matchesPassword(String rawPassword, String encodedPassword) |
| | | { |
| | | public static boolean matchesPassword(String rawPassword, String encodedPassword) { |
| | | BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); |
| | | return passwordEncoder.matches(rawPassword, encodedPassword); |
| | | } |
| | |
| | | * @param userId 用户ID |
| | | * @return 结果 |
| | | */ |
| | | public static boolean isAdmin(Long userId) |
| | | { |
| | | public static boolean isAdmin(Long userId) { |
| | | return userId != null && 1L == userId; |
| | | } |
| | | } |
| | |
| | | * @author ruoyi |
| | | */ |
| | | public class ServletUtils extends ServletUtil { |
| | | /** |
| | | * 获取String参数 |
| | | */ |
| | | public static String getParameter(String name) { |
| | | return getRequest().getParameter(name); |
| | | } |
| | | |
| | | /** |
| | | * 获取String参数 |
| | | */ |
| | | public static String getParameter(String name, String defaultValue) { |
| | | return Convert.toStr(getRequest().getParameter(name), defaultValue); |
| | | } |
| | | /** |
| | | * 获取String参数 |
| | | */ |
| | | public static String getParameter(String name) { |
| | | return getRequest().getParameter(name); |
| | | } |
| | | |
| | | /** |
| | | * 获取Integer参数 |
| | | */ |
| | | public static Integer getParameterToInt(String name) { |
| | | return Convert.toInt(getRequest().getParameter(name)); |
| | | } |
| | | /** |
| | | * 获取String参数 |
| | | */ |
| | | public static String getParameter(String name, String defaultValue) { |
| | | return Convert.toStr(getRequest().getParameter(name), defaultValue); |
| | | } |
| | | |
| | | /** |
| | | * 获取Integer参数 |
| | | */ |
| | | public static Integer getParameterToInt(String name, Integer defaultValue) { |
| | | return Convert.toInt(getRequest().getParameter(name), defaultValue); |
| | | } |
| | | /** |
| | | * 获取Integer参数 |
| | | */ |
| | | public static Integer getParameterToInt(String name) { |
| | | return Convert.toInt(getRequest().getParameter(name)); |
| | | } |
| | | |
| | | /** |
| | | * 获取Integer参数 |
| | | */ |
| | | public static Integer getParameterToInt(String name, Integer defaultValue) { |
| | | return Convert.toInt(getRequest().getParameter(name), defaultValue); |
| | | } |
| | | |
| | | /** |
| | | * 获取Boolean参数 |
| | |
| | | return getRequestAttributes().getRequest(); |
| | | } |
| | | |
| | | /** |
| | | * 获取response |
| | | */ |
| | | public static HttpServletResponse getResponse() { |
| | | return getRequestAttributes().getResponse(); |
| | | } |
| | | /** |
| | | * 获取response |
| | | */ |
| | | public static HttpServletResponse getResponse() { |
| | | return getRequestAttributes().getResponse(); |
| | | } |
| | | |
| | | /** |
| | | * 获取session |
| | | */ |
| | | public static HttpSession getSession() { |
| | | return getRequest().getSession(); |
| | | } |
| | | /** |
| | | * 获取session |
| | | */ |
| | | public static HttpSession getSession() { |
| | | return getRequest().getSession(); |
| | | } |
| | | |
| | | public static ServletRequestAttributes getRequestAttributes() { |
| | | RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); |
| | | return (ServletRequestAttributes) attributes; |
| | | } |
| | | public static ServletRequestAttributes getRequestAttributes() { |
| | | RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); |
| | | return (ServletRequestAttributes) attributes; |
| | | } |
| | | |
| | | /** |
| | | * 将字符串渲染到客户端 |
| | | * |
| | | * @param response 渲染对象 |
| | | * @param string 待渲染的字符串 |
| | | * @return null |
| | | */ |
| | | public static String renderString(HttpServletResponse response, String string) { |
| | | try { |
| | | response.setStatus(HttpStatus.HTTP_OK); |
| | | response.setContentType(MediaType.APPLICATION_JSON_VALUE); |
| | | response.setCharacterEncoding(StandardCharsets.UTF_8.toString()); |
| | | response.getWriter().print(string); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | /** |
| | | * 将字符串渲染到客户端 |
| | | * |
| | | * @param response 渲染对象 |
| | | * @param string 待渲染的字符串 |
| | | * @return null |
| | | */ |
| | | public static String renderString(HttpServletResponse response, String string) { |
| | | try { |
| | | response.setStatus(HttpStatus.HTTP_OK); |
| | | response.setContentType(MediaType.APPLICATION_JSON_VALUE); |
| | | response.setCharacterEncoding(StandardCharsets.UTF_8.toString()); |
| | | response.getWriter().print(string); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 是否是Ajax异步请求 |
| | | * |
| | | * @param request |
| | | */ |
| | | public static boolean isAjaxRequest(HttpServletRequest request) { |
| | | /** |
| | | * 是否是Ajax异步请求 |
| | | * |
| | | * @param request |
| | | */ |
| | | public static boolean isAjaxRequest(HttpServletRequest request) { |
| | | |
| | | String accept = request.getHeader("accept"); |
| | | if (accept != null && accept.indexOf("application/json") != -1) { |
| | | return true; |
| | | } |
| | | String accept = request.getHeader("accept"); |
| | | if (accept != null && accept.indexOf("application/json") != -1) { |
| | | return true; |
| | | } |
| | | |
| | | String xRequestedWith = request.getHeader("X-Requested-With"); |
| | | if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) { |
| | | return true; |
| | | } |
| | | String xRequestedWith = request.getHeader("X-Requested-With"); |
| | | if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) { |
| | | return true; |
| | | } |
| | | |
| | | String uri = request.getRequestURI(); |
| | | if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) { |
| | | return true; |
| | | } |
| | | String uri = request.getRequestURI(); |
| | | if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) { |
| | | return true; |
| | | } |
| | | |
| | | String ajax = request.getParameter("__ajax"); |
| | | if (StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml")) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | String ajax = request.getParameter("__ajax"); |
| | | if (StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml")) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | public static String getClientIP() { |
| | | return getClientIP(getRequest()); |
| | | } |
| | | public static String getClientIP() { |
| | | return getClientIP(getRequest()); |
| | | } |
| | | |
| | | } |
| | |
| | | /** |
| | | * 字符串工具类 |
| | | * |
| | | * @author ruoyi |
| | | * @author Lion Li |
| | | */ |
| | | public class StringUtils extends org.apache.commons.lang3.StringUtils { |
| | | |
| | |
| | | package com.ruoyi.common.utils; |
| | | |
| | | import java.util.concurrent.CancellationException; |
| | | import java.util.concurrent.ExecutionException; |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.Future; |
| | | import java.util.concurrent.TimeUnit; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | |
| | | import java.util.concurrent.*; |
| | | |
| | | /** |
| | | * 线程相关工具类. |
| | | * |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class Threads |
| | | { |
| | | public class Threads { |
| | | private static final Logger logger = LoggerFactory.getLogger(Threads.class); |
| | | |
| | | /** |
| | | * sleep等待,单位为毫秒 |
| | | */ |
| | | public static void sleep(long milliseconds) |
| | | { |
| | | try |
| | | { |
| | | public static void sleep(long milliseconds) { |
| | | try { |
| | | Thread.sleep(milliseconds); |
| | | } |
| | | catch (InterruptedException e) |
| | | { |
| | | } catch (InterruptedException e) { |
| | | return; |
| | | } |
| | | } |
| | |
| | | * 如果仍人超時,則強制退出. |
| | | * 另对在shutdown时线程本身被调用中断做了处理. |
| | | */ |
| | | public static void shutdownAndAwaitTermination(ExecutorService pool) |
| | | { |
| | | if (pool != null && !pool.isShutdown()) |
| | | { |
| | | public static void shutdownAndAwaitTermination(ExecutorService pool) { |
| | | if (pool != null && !pool.isShutdown()) { |
| | | pool.shutdown(); |
| | | try |
| | | { |
| | | if (!pool.awaitTermination(120, TimeUnit.SECONDS)) |
| | | { |
| | | try { |
| | | if (!pool.awaitTermination(120, TimeUnit.SECONDS)) { |
| | | pool.shutdownNow(); |
| | | if (!pool.awaitTermination(120, TimeUnit.SECONDS)) |
| | | { |
| | | if (!pool.awaitTermination(120, TimeUnit.SECONDS)) { |
| | | logger.info("Pool did not terminate"); |
| | | } |
| | | } |
| | | } |
| | | catch (InterruptedException ie) |
| | | { |
| | | } catch (InterruptedException ie) { |
| | | pool.shutdownNow(); |
| | | Thread.currentThread().interrupt(); |
| | | } |
| | |
| | | /** |
| | | * 打印线程异常信息 |
| | | */ |
| | | public static void printException(Runnable r, Throwable t) |
| | | { |
| | | if (t == null && r instanceof Future<?>) |
| | | { |
| | | try |
| | | { |
| | | public static void printException(Runnable r, Throwable t) { |
| | | if (t == null && r instanceof Future<?>) { |
| | | try { |
| | | Future<?> future = (Future<?>) r; |
| | | if (future.isDone()) |
| | | { |
| | | if (future.isDone()) { |
| | | future.get(); |
| | | } |
| | | } |
| | | catch (CancellationException ce) |
| | | { |
| | | } catch (CancellationException ce) { |
| | | t = ce; |
| | | } |
| | | catch (ExecutionException ee) |
| | | { |
| | | } catch (ExecutionException ee) { |
| | | t = ee.getCause(); |
| | | } |
| | | catch (InterruptedException ie) |
| | | { |
| | | } catch (InterruptedException ie) { |
| | | Thread.currentThread().interrupt(); |
| | | } |
| | | } |
| | | if (t != null) |
| | | { |
| | | if (t != null) { |
| | | logger.error(t.getMessage(), t); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * 文件处理工具类 |
| | | * |
| | | * @author ruoyi |
| | | * @author Lion Li |
| | | */ |
| | | public class FileUtils extends FileUtil |
| | | { |
| | | public class FileUtils extends FileUtil { |
| | | |
| | | /** |
| | | * 下载文件名重新编码 |
| | | * |
| | | * @param response 响应对象 |
| | | * @param response 响应对象 |
| | | * @param realFileName 真实文件名 |
| | | * @return |
| | | */ |
| | | public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException |
| | | { |
| | | public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException { |
| | | String percentEncodedFileName = percentEncode(realFileName); |
| | | |
| | | StringBuilder contentDispositionValue = new StringBuilder(); |
| | |
| | | * @param s 需要百分号编码的字符串 |
| | | * @return 百分号编码后的字符串 |
| | | */ |
| | | public static String percentEncode(String s) throws UnsupportedEncodingException |
| | | { |
| | | public static String percentEncode(String s) throws UnsupportedEncodingException { |
| | | String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString()); |
| | | return encode.replaceAll("\\+", "%20"); |
| | | } |
| | |
| | | /** |
| | | * 获取地址类 |
| | | * |
| | | * @author ruoyi |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | public class AddressUtils { |
| | | |
| | | // IP地址查询 |
| | | public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; |
| | | // IP地址查询 |
| | | public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; |
| | | |
| | | // 未知地址 |
| | | public static final String UNKNOWN = "XX XX"; |
| | | // 未知地址 |
| | | public static final String UNKNOWN = "XX XX"; |
| | | |
| | | public static String getRealAddressByIP(String ip) { |
| | | String address = UNKNOWN; |
| | | if (StringUtils.isBlank(ip)){ |
| | | return address; |
| | | } |
| | | // 内网不查询 |
| | | ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip); |
| | | if (NetUtil.isInnerIP(ip)) { |
| | | return "内网IP"; |
| | | } |
| | | if (RuoYiConfig.isAddressEnabled()) { |
| | | try { |
| | | String rspStr = HttpUtil.createGet(IP_URL) |
| | | .body("ip=" + ip + "&json=true", Constants.GBK) |
| | | .execute() |
| | | .body(); |
| | | if (StringUtils.isEmpty(rspStr)) { |
| | | log.error("获取地理位置异常 {}", ip); |
| | | return UNKNOWN; |
| | | } |
| | | Map<String, String> obj = JsonUtils.parseMap(rspStr); |
| | | String region = obj.get("pro"); |
| | | String city = obj.get("city"); |
| | | return String.format("%s %s", region, city); |
| | | } catch (Exception e) { |
| | | log.error("获取地理位置异常 {}", ip); |
| | | } |
| | | } |
| | | return address; |
| | | } |
| | | public static String getRealAddressByIP(String ip) { |
| | | String address = UNKNOWN; |
| | | if (StringUtils.isBlank(ip)) { |
| | | return address; |
| | | } |
| | | // 内网不查询 |
| | | ip = "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : HtmlUtil.cleanHtmlTag(ip); |
| | | if (NetUtil.isInnerIP(ip)) { |
| | | return "内网IP"; |
| | | } |
| | | if (RuoYiConfig.isAddressEnabled()) { |
| | | try { |
| | | String rspStr = HttpUtil.createGet(IP_URL) |
| | | .body("ip=" + ip + "&json=true", Constants.GBK) |
| | | .execute() |
| | | .body(); |
| | | if (StringUtils.isEmpty(rspStr)) { |
| | | log.error("获取地理位置异常 {}", ip); |
| | | return UNKNOWN; |
| | | } |
| | | Map<String, String> obj = JsonUtils.parseMap(rspStr); |
| | | String region = obj.get("pro"); |
| | | String city = obj.get("city"); |
| | | return String.format("%s %s", region, city); |
| | | } catch (Exception e) { |
| | | log.error("获取地理位置异常 {}", ip); |
| | | } |
| | | } |
| | | return address; |
| | | } |
| | | } |
| | |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.net.URLEncoder; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * Excel相关处理 |
| | | * |
| | | * @author ruoyi |
| | | * @author Lion Li |
| | | */ |
| | | public class ExcelUtil { |
| | | |
| | |
| | | @SuppressWarnings("rawtypes") |
| | | public class ReflectUtils extends ReflectUtil { |
| | | |
| | | private static final String SETTER_PREFIX = "set"; |
| | | private static final String SETTER_PREFIX = "set"; |
| | | |
| | | private static final String GETTER_PREFIX = "get"; |
| | | private static final String GETTER_PREFIX = "get"; |
| | | |
| | | /** |
| | | * 调用Getter方法. |
| | | * 支持多级,如:对象名.对象名.方法 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <E> E invokeGetter(Object obj, String propertyName) { |
| | | Object object = obj; |
| | | for (String name : StringUtils.split(propertyName, ".")) { |
| | | String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); |
| | | object = invoke(object, getterMethodName); |
| | | } |
| | | return (E) object; |
| | | } |
| | | /** |
| | | * 调用Getter方法. |
| | | * 支持多级,如:对象名.对象名.方法 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <E> E invokeGetter(Object obj, String propertyName) { |
| | | Object object = obj; |
| | | for (String name : StringUtils.split(propertyName, ".")) { |
| | | String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); |
| | | object = invoke(object, getterMethodName); |
| | | } |
| | | return (E) object; |
| | | } |
| | | |
| | | /** |
| | | * 调用Setter方法, 仅匹配方法名。 |
| | | * 支持多级,如:对象名.对象名.方法 |
| | | */ |
| | | public static <E> void invokeSetter(Object obj, String propertyName, E value) { |
| | | Object object = obj; |
| | | String[] names = StringUtils.split(propertyName, "."); |
| | | for (int i = 0; i < names.length; i++) { |
| | | if (i < names.length - 1) { |
| | | String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); |
| | | object = invoke(object, getterMethodName); |
| | | } else { |
| | | String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); |
| | | Method method = getMethodByName(object.getClass(), setterMethodName); |
| | | invoke(object, method, value); |
| | | } |
| | | } |
| | | } |
| | | /** |
| | | * 调用Setter方法, 仅匹配方法名。 |
| | | * 支持多级,如:对象名.对象名.方法 |
| | | */ |
| | | public static <E> void invokeSetter(Object obj, String propertyName, E value) { |
| | | Object object = obj; |
| | | String[] names = StringUtils.split(propertyName, "."); |
| | | for (int i = 0; i < names.length; i++) { |
| | | if (i < names.length - 1) { |
| | | String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); |
| | | object = invoke(object, getterMethodName); |
| | | } else { |
| | | String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); |
| | | Method method = getMethodByName(object.getClass(), setterMethodName); |
| | | invoke(object, method, value); |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | @Component |
| | | public final class SpringUtils extends SpringUtil { |
| | | |
| | | /** |
| | | * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true |
| | | * |
| | | * @param name |
| | | * @return boolean |
| | | */ |
| | | public static boolean containsBean(String name) { |
| | | return getBeanFactory().containsBean(name); |
| | | } |
| | | /** |
| | | * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true |
| | | * |
| | | * @param name |
| | | * @return boolean |
| | | */ |
| | | public static boolean containsBean(String name) { |
| | | return getBeanFactory().containsBean(name); |
| | | } |
| | | |
| | | /** |
| | | * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 |
| | | * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) |
| | | * |
| | | * @param name |
| | | * @return boolean |
| | | */ |
| | | public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().isSingleton(name); |
| | | } |
| | | /** |
| | | * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 |
| | | * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) |
| | | * |
| | | * @param name |
| | | * @return boolean |
| | | */ |
| | | public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().isSingleton(name); |
| | | } |
| | | |
| | | /** |
| | | * @param name |
| | | * @return Class 注册对象的类型 |
| | | */ |
| | | public static Class<?> getType(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().getType(name); |
| | | } |
| | | /** |
| | | * @param name |
| | | * @return Class 注册对象的类型 |
| | | */ |
| | | public static Class<?> getType(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().getType(name); |
| | | } |
| | | |
| | | /** |
| | | * 如果给定的bean名字在bean定义中有别名,则返回这些别名 |
| | | * |
| | | * @param name |
| | | */ |
| | | public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().getAliases(name); |
| | | } |
| | | /** |
| | | * 如果给定的bean名字在bean定义中有别名,则返回这些别名 |
| | | * |
| | | * @param name |
| | | */ |
| | | public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { |
| | | return getBeanFactory().getAliases(name); |
| | | } |
| | | |
| | | /** |
| | | * 获取aop代理对象 |
| | | * |
| | | * @param invoker |
| | | * @return |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> T getAopProxy(T invoker) { |
| | | return (T) AopContext.currentProxy(); |
| | | } |
| | | /** |
| | | * 获取aop代理对象 |
| | | * |
| | | * @param invoker |
| | | * @return |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> T getAopProxy(T invoker) { |
| | | return (T) AopContext.currentProxy(); |
| | | } |
| | | |
| | | } |
| | |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | public class SqlUtil |
| | | { |
| | | public class SqlUtil { |
| | | /** |
| | | * 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序) |
| | | */ |
| | |
| | | /** |
| | | * 检查字符,防止注入绕过 |
| | | */ |
| | | public static String escapeOrderBySql(String value) |
| | | { |
| | | if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) |
| | | { |
| | | public static String escapeOrderBySql(String value) { |
| | | if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) { |
| | | throw new UtilException("参数不符合规范,不能进行查询"); |
| | | } |
| | | return value; |
| | |
| | | /** |
| | | * 验证 order by 语法是否符合规范 |
| | | */ |
| | | public static boolean isValidOrderBySql(String value) |
| | | { |
| | | public static boolean isValidOrderBySql(String value) { |
| | | return value.matches(SQL_PATTERN); |
| | | } |
| | | } |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class JwtAuthenticationTokenFilter extends OncePerRequestFilter |
| | | { |
| | | public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { |
| | | |
| | | @Autowired |
| | | private TokenService tokenService; |
| | | |
| | | @Override |
| | | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) |
| | | throws ServletException, IOException |
| | | { |
| | | throws ServletException, IOException { |
| | | LoginUser loginUser = tokenService.getLoginUser(request); |
| | | if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) { |
| | | tokenService.verifyToken(loginUser); |
| | |
| | | package com.ruoyi.framework.security.handle; |
| | | |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import cn.hutool.http.HttpStatus; |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.common.utils.JsonUtils; |
| | | import com.ruoyi.common.utils.ServletUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import org.springframework.security.core.AuthenticationException; |
| | | import org.springframework.security.web.AuthenticationEntryPoint; |
| | | import org.springframework.stereotype.Component; |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Component |
| | | public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable |
| | | { |
| | | public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable { |
| | | private static final long serialVersionUID = -8970718410437077606L; |
| | | |
| | | @Override |
| | | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) |
| | | throws IOException |
| | | { |
| | | throws IOException { |
| | | int code = HttpStatus.HTTP_UNAUTHORIZED; |
| | | String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); |
| | | ServletUtils.renderString(response, JsonUtils.toJsonString(AjaxResult.error(code, msg))); |
| | |
| | | import com.ruoyi.common.exception.DemoModeException; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.security.access.AccessDeniedException; |
| | | import org.springframework.validation.BindException; |
| | | import org.springframework.web.HttpRequestMethodNotSupportedException; |
| | |
| | | /** |
| | | * 全局异常处理器 |
| | | * |
| | | * @author ruoyi |
| | | * @author Lion Li |
| | | */ |
| | | @Slf4j |
| | | @RestControllerAdvice |
| | | public class GlobalExceptionHandler |
| | | { |
| | | private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class); |
| | | public class GlobalExceptionHandler { |
| | | |
| | | /** |
| | | * 权限校验异常 |
| | | */ |
| | | @ExceptionHandler(AccessDeniedException.class) |
| | | public AjaxResult handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) |
| | | { |
| | | public AjaxResult<Void> handleAccessDeniedException(AccessDeniedException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage()); |
| | | return AjaxResult.error(HttpStatus.HTTP_FORBIDDEN, "没有权限,请联系管理员授权"); |
| | |
| | | * 请求方式不支持 |
| | | */ |
| | | @ExceptionHandler(HttpRequestMethodNotSupportedException.class) |
| | | public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, |
| | | HttpServletRequest request) |
| | | { |
| | | public AjaxResult<Void> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, |
| | | HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); |
| | | return AjaxResult.error(e.getMessage()); |
| | |
| | | * 业务异常 |
| | | */ |
| | | @ExceptionHandler(ServiceException.class) |
| | | public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request) |
| | | { |
| | | public AjaxResult<Void> handleServiceException(ServiceException e, HttpServletRequest request) { |
| | | log.error(e.getMessage(), e); |
| | | Integer code = e.getCode(); |
| | | return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); |
| | |
| | | * 拦截未知的运行时异常 |
| | | */ |
| | | @ExceptionHandler(RuntimeException.class) |
| | | public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request) |
| | | { |
| | | public AjaxResult<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请求地址'{}',发生未知异常.", requestURI, e); |
| | | return AjaxResult.error(e.getMessage()); |
| | |
| | | * 系统异常 |
| | | */ |
| | | @ExceptionHandler(Exception.class) |
| | | public AjaxResult handleException(Exception e, HttpServletRequest request) |
| | | { |
| | | public AjaxResult<Void> handleException(Exception e, HttpServletRequest request) { |
| | | String requestURI = request.getRequestURI(); |
| | | log.error("请求地址'{}',发生系统异常.", requestURI, e); |
| | | return AjaxResult.error(e.getMessage()); |
| | |
| | | * 自定义验证异常 |
| | | */ |
| | | @ExceptionHandler(BindException.class) |
| | | public AjaxResult handleBindException(BindException e) |
| | | { |
| | | public AjaxResult<Void> handleBindException(BindException e) { |
| | | log.error(e.getMessage(), e); |
| | | String message = e.getAllErrors().get(0).getDefaultMessage(); |
| | | return AjaxResult.error(message); |
| | |
| | | * 自定义验证异常 |
| | | */ |
| | | @ExceptionHandler(ConstraintViolationException.class) |
| | | public AjaxResult constraintViolationException(ConstraintViolationException e) { |
| | | public AjaxResult<Void> constraintViolationException(ConstraintViolationException e) { |
| | | log.error(e.getMessage(), e); |
| | | String message = e.getConstraintViolations().iterator().next().getMessage(); |
| | | return AjaxResult.error(message); |
| | |
| | | * 自定义验证异常 |
| | | */ |
| | | @ExceptionHandler(MethodArgumentNotValidException.class) |
| | | public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) |
| | | { |
| | | public AjaxResult<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { |
| | | log.error(e.getMessage(), e); |
| | | String message = e.getBindingResult().getFieldError().getDefaultMessage(); |
| | | return AjaxResult.error(message); |
| | |
| | | * 演示模式异常 |
| | | */ |
| | | @ExceptionHandler(DemoModeException.class) |
| | | public AjaxResult handleDemoModeException(DemoModeException e) |
| | | { |
| | | public AjaxResult<Void> handleDemoModeException(DemoModeException e) { |
| | | return AjaxResult.error("演示模式,不允许操作"); |
| | | } |
| | | } |