若依 3.0
This commit is contained in:
@ -0,0 +1,23 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 数据权限过滤注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DataScope
|
||||
{
|
||||
/**
|
||||
* 表的别名
|
||||
*/
|
||||
String tableAlias() default "";
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
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.DataSourceType;
|
||||
|
||||
/**
|
||||
* 自定义多数据源切换注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DataSource
|
||||
{
|
||||
/**
|
||||
* 切换数据源名称
|
||||
*/
|
||||
public DataSourceType value() default DataSourceType.MASTER;
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 自定义导出Excel数据注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Excel
|
||||
{
|
||||
/**
|
||||
* 导出到Excel中的名字.
|
||||
*/
|
||||
public abstract String name();
|
||||
|
||||
/**
|
||||
* 提示信息
|
||||
*/
|
||||
public abstract String prompt() default "";
|
||||
|
||||
/**
|
||||
* 设置只能选择不能输入的列内容.
|
||||
*/
|
||||
public abstract String[] combo() default {};
|
||||
|
||||
/**
|
||||
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
|
||||
*/
|
||||
public abstract boolean isExport() default true;
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 自定义操作日志记录注解
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target({ ElementType.PARAMETER, ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface Log
|
||||
{
|
||||
/**
|
||||
* 模块
|
||||
*/
|
||||
String title() default "";
|
||||
|
||||
/**
|
||||
* 功能
|
||||
*/
|
||||
BusinessType businessType() default BusinessType.OTHER;
|
||||
|
||||
/**
|
||||
* 操作人类别
|
||||
*/
|
||||
OperatorType operatorType() default OperatorType.MANAGE;
|
||||
|
||||
/**
|
||||
* 是否保存请求的参数
|
||||
*/
|
||||
boolean isSaveRequestData() default true;
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
package com.ruoyi.common.base;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 操作消息提醒
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class AjaxResult extends HashMap<String, Object>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 初始化一个新创建的 Message 对象
|
||||
*/
|
||||
public AjaxResult()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error()
|
||||
{
|
||||
return error(1, "操作失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param msg 内容
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error(String msg)
|
||||
{
|
||||
return error(500, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回错误消息
|
||||
*
|
||||
* @param code 错误码
|
||||
* @param msg 内容
|
||||
* @return 错误消息
|
||||
*/
|
||||
public static AjaxResult error(int code, String msg)
|
||||
{
|
||||
AjaxResult json = new AjaxResult();
|
||||
json.put("code", code);
|
||||
json.put("msg", msg);
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @param msg 内容
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success(String msg)
|
||||
{
|
||||
AjaxResult json = new AjaxResult();
|
||||
json.put("msg", msg);
|
||||
json.put("code", 0);
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @return 成功消息
|
||||
*/
|
||||
public static AjaxResult success()
|
||||
{
|
||||
return AjaxResult.success("操作成功");
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回成功消息
|
||||
*
|
||||
* @param key 键值
|
||||
* @param value 内容
|
||||
* @return 成功消息
|
||||
*/
|
||||
@Override
|
||||
public AjaxResult put(String key, Object value)
|
||||
{
|
||||
super.put(key, value);
|
||||
return this;
|
||||
}
|
||||
}
|
114
ruoyi-common/src/main/java/com/ruoyi/common/base/BaseEntity.java
Normal file
114
ruoyi-common/src/main/java/com/ruoyi/common/base/BaseEntity.java
Normal file
@ -0,0 +1,114 @@
|
||||
package com.ruoyi.common.base;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
/**
|
||||
* Entity基类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class BaseEntity implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 搜索值 */
|
||||
private String searchValue;
|
||||
|
||||
/** 创建者 */
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/** 更新者 */
|
||||
private String updateBy;
|
||||
|
||||
/** 更新时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 请求参数 */
|
||||
private Map<String, Object> params;
|
||||
|
||||
public String getSearchValue()
|
||||
{
|
||||
return searchValue;
|
||||
}
|
||||
|
||||
public void setSearchValue(String searchValue)
|
||||
{
|
||||
this.searchValue = searchValue;
|
||||
}
|
||||
|
||||
public String getCreateBy()
|
||||
{
|
||||
return createBy;
|
||||
}
|
||||
|
||||
public void setCreateBy(String createBy)
|
||||
{
|
||||
this.createBy = createBy;
|
||||
}
|
||||
|
||||
public Date getCreateTime()
|
||||
{
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime)
|
||||
{
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getUpdateBy()
|
||||
{
|
||||
return updateBy;
|
||||
}
|
||||
|
||||
public void setUpdateBy(String updateBy)
|
||||
{
|
||||
this.updateBy = updateBy;
|
||||
}
|
||||
|
||||
public Date getUpdateTime()
|
||||
{
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime)
|
||||
{
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public String getRemark()
|
||||
{
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark)
|
||||
{
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams()
|
||||
{
|
||||
if (params == null)
|
||||
{
|
||||
params = new HashMap<>();
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, Object> params)
|
||||
{
|
||||
this.params = params;
|
||||
}
|
||||
}
|
164
ruoyi-common/src/main/java/com/ruoyi/common/config/Global.java
Normal file
164
ruoyi-common/src/main/java/com/ruoyi/common/config/Global.java
Normal file
@ -0,0 +1,164 @@
|
||||
package com.ruoyi.common.config;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.YamlUtil;
|
||||
|
||||
/**
|
||||
* 全局配置类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class Global
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(Global.class);
|
||||
|
||||
private static String NAME = "application.yml";
|
||||
|
||||
/**
|
||||
* 当前对象实例
|
||||
*/
|
||||
private static Global global = null;
|
||||
|
||||
/**
|
||||
* 保存全局属性值
|
||||
*/
|
||||
private static Map<String, String> map = new HashMap<String, String>();
|
||||
|
||||
private Global()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态工厂方法 获取当前对象实例 多线程安全单例模式(使用双重同步锁)
|
||||
*/
|
||||
|
||||
public static synchronized Global getInstance()
|
||||
{
|
||||
if (global == null)
|
||||
{
|
||||
synchronized (Global.class)
|
||||
{
|
||||
if (global == null)
|
||||
global = new Global();
|
||||
}
|
||||
}
|
||||
return global;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*/
|
||||
public static String getConfig(String key)
|
||||
{
|
||||
String value = map.get(key);
|
||||
if (value == null)
|
||||
{
|
||||
Map<?, ?> yamlMap = null;
|
||||
try
|
||||
{
|
||||
yamlMap = YamlUtil.loadYaml(NAME);
|
||||
value = String.valueOf(YamlUtil.getProperty(yamlMap, key));
|
||||
map.put(key, value != null ? value : StringUtils.EMPTY);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
log.error("获取全局配置异常 {}", key);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目名称
|
||||
*/
|
||||
public static String getName()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("ruoyi.name"), "RuoYi");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取项目版本
|
||||
*/
|
||||
public static String getVersion()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("ruoyi.version"), "3.0.0");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取版权年份
|
||||
*/
|
||||
public static String getCopyrightYear()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("ruoyi.copyrightYear"), "2018");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip地址开关
|
||||
*/
|
||||
public static Boolean isAddressEnabled()
|
||||
{
|
||||
String value = getConfig("ruoyi.addressEnabled");
|
||||
return Boolean.TRUE.equals(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件上传路径
|
||||
*/
|
||||
public static String getProfile()
|
||||
{
|
||||
return getConfig("ruoyi.profile");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取头像上传路径
|
||||
*/
|
||||
public static String getAvatarPath()
|
||||
{
|
||||
return getConfig("ruoyi.profile") + "avatar/";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载上传路径
|
||||
*/
|
||||
public static String getDownloadPath()
|
||||
{
|
||||
return getConfig("ruoyi.profile") + "download/";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取作者
|
||||
*/
|
||||
public static String getAuthor()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("gen.author"), "ruoyi");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成包路径
|
||||
*/
|
||||
public static String getPackageName()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("gen.packageName"), "com.ruoyi.project.module");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否自动去除表前缀
|
||||
*/
|
||||
public static String getAutoRemovePre()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("gen.autoRemovePre"), "true");
|
||||
}
|
||||
|
||||
/**
|
||||
* 表前缀(类名不会包含表前缀)
|
||||
*/
|
||||
public static String getTablePrefix()
|
||||
{
|
||||
return StringUtils.nvl(getConfig("gen.tablePrefix"), "sys_");
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 通用常量信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class Constants
|
||||
{
|
||||
/**
|
||||
* UTF-8 字符集
|
||||
*/
|
||||
public static final String UTF8 = "UTF-8";
|
||||
|
||||
/**
|
||||
* 通用成功标识
|
||||
*/
|
||||
public static final String SUCCESS = "0";
|
||||
|
||||
/**
|
||||
* 通用失败标识
|
||||
*/
|
||||
public static final String FAIL = "1";
|
||||
|
||||
/**
|
||||
* 登录成功
|
||||
*/
|
||||
public static final String LOGIN_SUCCESS = "Success";
|
||||
|
||||
/**
|
||||
* 注销
|
||||
*/
|
||||
public static final String LOGOUT = "Logout";
|
||||
|
||||
/**
|
||||
* 登录失败
|
||||
*/
|
||||
public static final String LOGIN_FAIL = "Error";
|
||||
|
||||
/**
|
||||
* 自动去除表前缀
|
||||
*/
|
||||
public static String AUTO_REOMVE_PRE = "true";
|
||||
|
||||
/**
|
||||
* 当前记录起始索引
|
||||
*/
|
||||
public static String PAGE_NUM = "pageNum";
|
||||
|
||||
/**
|
||||
* 每页显示记录数
|
||||
*/
|
||||
public static String PAGE_SIZE = "pageSize";
|
||||
|
||||
/**
|
||||
* 排序列
|
||||
*/
|
||||
public static String ORDER_BY_COLUMN = "orderByColumn";
|
||||
|
||||
/**
|
||||
* 排序的方向 "desc" 或者 "asc".
|
||||
*/
|
||||
public static String IS_ASC = "isAsc";
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 权限通用常量
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class PermissionConstants
|
||||
{
|
||||
/** 新增权限 */
|
||||
public static final String ADD_PERMISSION = "add";
|
||||
|
||||
/** 修改权限 */
|
||||
public static final String EDIT_PERMISSION = "edit";
|
||||
|
||||
/** 删除权限 */
|
||||
public static final String REMOVE_PERMISSION = "remove";
|
||||
|
||||
/** 导出权限 */
|
||||
public static final String EXPORT_PERMISSION = "export";
|
||||
|
||||
/** 显示权限 */
|
||||
public static final String VIEW_PERMISSION = "view";
|
||||
|
||||
/** 查询权限 */
|
||||
public static final String LIST_PERMISSION = "list";
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 任务调度通用常量
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ScheduleConstants
|
||||
{
|
||||
public static final String TASK_CLASS_NAME = "__TASK_CLASS_NAME__";
|
||||
|
||||
public static final String TASK_PROPERTIES = "__TASK_PROPERTIES__";
|
||||
|
||||
/** 默认 */
|
||||
public static final String MISFIRE_DEFAULT = "0";
|
||||
|
||||
/** 立即触发执行 */
|
||||
public static final String MISFIRE_IGNORE_MISFIRES = "1";
|
||||
|
||||
/** 触发一次执行 */
|
||||
public static final String MISFIRE_FIRE_AND_PROCEED = "2";
|
||||
|
||||
/** 不触发立即执行 */
|
||||
public static final String MISFIRE_DO_NOTHING = "3";
|
||||
|
||||
public enum Status
|
||||
{
|
||||
/**
|
||||
* 正常
|
||||
*/
|
||||
NORMAL("0"),
|
||||
/**
|
||||
* 暂停
|
||||
*/
|
||||
PAUSE("1");
|
||||
|
||||
private String value;
|
||||
|
||||
private Status(String value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* Shiro通用常量
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ShiroConstants
|
||||
{
|
||||
/**
|
||||
* 当前登录的用户
|
||||
*/
|
||||
public static final String CURRENT_USER = "currentUser";
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
public static final String CURRENT_USERNAME = "username";
|
||||
|
||||
/**
|
||||
* 消息key
|
||||
*/
|
||||
public static String MESSAGE = "message";
|
||||
|
||||
/**
|
||||
* 错误key
|
||||
*/
|
||||
public static String ERROR = "errorMsg";
|
||||
|
||||
/**
|
||||
* 编码格式
|
||||
*/
|
||||
public static String ENCODING = "UTF-8";
|
||||
|
||||
/**
|
||||
* 当前在线会话
|
||||
*/
|
||||
public String ONLINE_SESSION = "online_session";
|
||||
|
||||
/**
|
||||
* 验证码key
|
||||
*/
|
||||
public static final String CURRENT_CAPTCHA = "captcha";
|
||||
|
||||
/**
|
||||
* 验证码开关
|
||||
*/
|
||||
public static final String CURRENT_ENABLED = "captchaEnabled";
|
||||
|
||||
/**
|
||||
* 验证码开关
|
||||
*/
|
||||
public static final String CURRENT_TYPE = "captchaType";
|
||||
|
||||
/**
|
||||
* 验证码
|
||||
*/
|
||||
public static final String CURRENT_VALIDATECODE = "validateCode";
|
||||
|
||||
/**
|
||||
* 验证码错误
|
||||
*/
|
||||
public static final String CAPTCHA_ERROR = "captchaError";
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.ruoyi.common.constant;
|
||||
|
||||
/**
|
||||
* 用户常量信息
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class UserConstants
|
||||
{
|
||||
/** 正常状态 */
|
||||
public static final String NORMAL = "0";
|
||||
|
||||
/** 异常状态 */
|
||||
public static final String EXCEPTION = "1";
|
||||
|
||||
/** 用户封禁状态 */
|
||||
public static final String USER_BLOCKED = "1";
|
||||
|
||||
/** 角色封禁状态 */
|
||||
public static final String ROLE_BLOCKED = "1";
|
||||
|
||||
/** 部门正常状态 */
|
||||
public static final String DEPT_NORMAL = "0";
|
||||
|
||||
/**
|
||||
* 用户名长度限制
|
||||
*/
|
||||
public static final int USERNAME_MIN_LENGTH = 2;
|
||||
public static final int USERNAME_MAX_LENGTH = 20;
|
||||
|
||||
/** 登录名称是否唯一的返回结果码 */
|
||||
public final static String USER_NAME_UNIQUE = "0";
|
||||
public final static String USER_NAME_NOT_UNIQUE = "1";
|
||||
|
||||
/** 手机号码是否唯一的返回结果 */
|
||||
public final static String USER_PHONE_UNIQUE = "0";
|
||||
public final static String USER_PHONE_NOT_UNIQUE = "1";
|
||||
|
||||
/** e-mail 是否唯一的返回结果 */
|
||||
public final static String USER_EMAIL_UNIQUE = "0";
|
||||
public final static String USER_EMAIL_NOT_UNIQUE = "1";
|
||||
|
||||
/** 部门名称是否唯一的返回结果码 */
|
||||
public final static String DEPT_NAME_UNIQUE = "0";
|
||||
public final static String DEPT_NAME_NOT_UNIQUE = "1";
|
||||
|
||||
/** 角色名称是否唯一的返回结果码 */
|
||||
public final static String ROLE_NAME_UNIQUE = "0";
|
||||
public final static String ROLE_NAME_NOT_UNIQUE = "1";
|
||||
|
||||
/** 岗位名称是否唯一的返回结果码 */
|
||||
public final static String POST_NAME_UNIQUE = "0";
|
||||
public final static String POST_NAME_NOT_UNIQUE = "1";
|
||||
|
||||
/** 角色权限是否唯一的返回结果码 */
|
||||
public final static String ROLE_KEY_UNIQUE = "0";
|
||||
public final static String ROLE_KEY_NOT_UNIQUE = "1";
|
||||
|
||||
/** 岗位编码是否唯一的返回结果码 */
|
||||
public final static String POST_CODE_UNIQUE = "0";
|
||||
public final static String POST_CODE_NOT_UNIQUE = "1";
|
||||
|
||||
/** 菜单名称是否唯一的返回结果码 */
|
||||
public final static String MENU_NAME_UNIQUE = "0";
|
||||
public final static String MENU_NAME_NOT_UNIQUE = "1";
|
||||
|
||||
/** 字典类型是否唯一的返回结果码 */
|
||||
public final static String DICT_TYPE_UNIQUE = "0";
|
||||
public final static String DICT_TYPE_NOT_UNIQUE = "1";
|
||||
|
||||
/** 参数键名是否唯一的返回结果码 */
|
||||
public final static String CONFIG_KEY_UNIQUE = "0";
|
||||
public final static String CONFIG_KEY_NOT_UNIQUE = "1";
|
||||
|
||||
/**
|
||||
* 密码长度限制
|
||||
*/
|
||||
public static final int PASSWORD_MIN_LENGTH = 5;
|
||||
public static final int PASSWORD_MAX_LENGTH = 20;
|
||||
|
||||
/**
|
||||
* 手机号码格式限制
|
||||
*/
|
||||
public static final String MOBILE_PHONE_NUMBER_PATTERN = "^0{0,1}(13[0-9]|15[0-9]|14[0-9]|18[0-9])[0-9]{8}$";
|
||||
|
||||
/**
|
||||
* 邮箱格式限制
|
||||
*/
|
||||
public static final String EMAIL_PATTERN = "^((([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+(\\.([a-z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(\\\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|\\d|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.)+(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])|(([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])([a-z]|\\d|-|\\.|_|~|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])*([a-z]|[\\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF])))\\.?";
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 操作状态
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum BusinessStatus
|
||||
{
|
||||
/**
|
||||
* 成功
|
||||
*/
|
||||
SUCCESS,
|
||||
|
||||
/**
|
||||
* 失败
|
||||
*/
|
||||
FAIL,
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 业务操作类型
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum BusinessType
|
||||
{
|
||||
/**
|
||||
* 其它
|
||||
*/
|
||||
OTHER,
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
INSERT,
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
UPDATE,
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
DELETE,
|
||||
|
||||
/**
|
||||
* 授权
|
||||
*/
|
||||
GRANT,
|
||||
|
||||
/**
|
||||
* 导出
|
||||
*/
|
||||
EXPORT,
|
||||
|
||||
/**
|
||||
* 导入
|
||||
*/
|
||||
IMPORT,
|
||||
|
||||
/**
|
||||
* 强退
|
||||
*/
|
||||
FORCE,
|
||||
|
||||
/**
|
||||
* 生成代码
|
||||
*/
|
||||
GENCODE,
|
||||
|
||||
/**
|
||||
* 清空
|
||||
*/
|
||||
CLEAN,
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 数据源
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum DataSourceType
|
||||
{
|
||||
/**
|
||||
* 主库
|
||||
*/
|
||||
MASTER,
|
||||
|
||||
/**
|
||||
* 从库
|
||||
*/
|
||||
SLAVE
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 用户会话
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum OnlineStatus
|
||||
{
|
||||
/** 用户状态 */
|
||||
on_line("在线"), off_line("离线");
|
||||
|
||||
private final String info;
|
||||
|
||||
private OnlineStatus(String info)
|
||||
{
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public String getInfo()
|
||||
{
|
||||
return info;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 操作人类别
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum OperatorType
|
||||
{
|
||||
/**
|
||||
* 其它
|
||||
*/
|
||||
OTHER,
|
||||
|
||||
/**
|
||||
* 后台用户
|
||||
*/
|
||||
|
||||
MANAGE,
|
||||
|
||||
/**
|
||||
* 手机端用户
|
||||
*/
|
||||
MOBILE
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.ruoyi.common.enums;
|
||||
|
||||
/**
|
||||
* 用户状态
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public enum UserStatus
|
||||
{
|
||||
OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
|
||||
|
||||
private final String code;
|
||||
private final String info;
|
||||
|
||||
UserStatus(String code, String info)
|
||||
{
|
||||
this.code = code;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public String getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getInfo()
|
||||
{
|
||||
return info;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.ruoyi.common.exception;
|
||||
|
||||
/**
|
||||
* 演示模式异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class DemoModeException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public DemoModeException()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
|
||||
/**
|
||||
* 文件名超长 误异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileNameLengthLimitExceededException extends FileUploadException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private int length;
|
||||
private int maxLength;
|
||||
private String filename;
|
||||
|
||||
public FileNameLengthLimitExceededException(String filename, int length, int maxLength)
|
||||
{
|
||||
super("file name : [" + filename + "], length : [" + length + "], max length : [" + maxLength + "]");
|
||||
this.length = length;
|
||||
this.maxLength = maxLength;
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public String getFilename()
|
||||
{
|
||||
return filename;
|
||||
}
|
||||
|
||||
public int getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
public int getMaxLength()
|
||||
{
|
||||
return maxLength;
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package com.ruoyi.common.exception.file;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.apache.commons.fileupload.FileUploadException;
|
||||
|
||||
/**
|
||||
* 文件上传 误异常类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidFlashExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
|
||||
public static class InvalidMediaExtensionException extends InvalidExtensionException
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
|
||||
{
|
||||
super(allowedExtension, extension, filename);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.ruoyi.common.exception.job;
|
||||
|
||||
/**
|
||||
* 计划策略异常
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class TaskException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Code code;
|
||||
|
||||
public TaskException(String msg, Code code)
|
||||
{
|
||||
this(msg, code, null);
|
||||
}
|
||||
|
||||
public TaskException(String msg, Code code, Exception nestedEx)
|
||||
{
|
||||
super(msg, nestedEx);
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Code getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
public enum Code
|
||||
{
|
||||
TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE
|
||||
}
|
||||
}
|
187
ruoyi-common/src/main/java/com/ruoyi/common/json/JSON.java
Normal file
187
ruoyi-common/src/main/java/com/ruoyi/common/json/JSON.java
Normal file
@ -0,0 +1,187 @@
|
||||
package com.ruoyi.common.json;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
|
||||
/**
|
||||
* JSON解析处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class JSON
|
||||
{
|
||||
public static final String DEFAULT_FAIL = "\"Parse failed\"";
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private static final ObjectWriter objectWriter = objectMapper.writerWithDefaultPrettyPrinter();
|
||||
|
||||
public static void marshal(File file, Object value) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
objectWriter.writeValue(file, value);
|
||||
}
|
||||
catch (JsonGenerationException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void marshal(OutputStream os, Object value) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
objectWriter.writeValue(os, value);
|
||||
}
|
||||
catch (JsonGenerationException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String marshal(Object value) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
return objectWriter.writeValueAsString(value);
|
||||
}
|
||||
catch (JsonGenerationException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] marshalBytes(Object value) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
return objectWriter.writeValueAsBytes(value);
|
||||
}
|
||||
catch (JsonGenerationException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unmarshal(File file, Class<T> valueType) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
return objectMapper.readValue(file, valueType);
|
||||
}
|
||||
catch (JsonParseException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unmarshal(InputStream is, Class<T> valueType) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
return objectMapper.readValue(is, valueType);
|
||||
}
|
||||
catch (JsonParseException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unmarshal(String str, Class<T> valueType) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
return objectMapper.readValue(str, valueType);
|
||||
}
|
||||
catch (JsonParseException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T unmarshal(byte[] bytes, Class<T> valueType) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
bytes = new byte[0];
|
||||
}
|
||||
return objectMapper.readValue(bytes, 0, bytes.length, valueType);
|
||||
}
|
||||
catch (JsonParseException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (JsonMappingException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
}
|
746
ruoyi-common/src/main/java/com/ruoyi/common/json/JSONObject.java
Normal file
746
ruoyi-common/src/main/java/com/ruoyi/common/json/JSONObject.java
Normal file
@ -0,0 +1,746 @@
|
||||
package com.ruoyi.common.json;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 通用消息对象,基于Map实现的可嵌套数据结构。 支持JSON数据结构。
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class JSONObject extends LinkedHashMap<String, Object>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Pattern arrayNamePattern = Pattern.compile("(\\w+)((\\[\\d+\\])+)");
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* 数组结构。
|
||||
*/
|
||||
public static class JSONArray extends ArrayList<Object>
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public JSONArray()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public JSONArray(int size)
|
||||
{
|
||||
super(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
try
|
||||
{
|
||||
return JSON.marshal(this);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object set(int index, Object element)
|
||||
{
|
||||
return super.set(index, transfer(element));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Object element)
|
||||
{
|
||||
return super.add(transfer(element));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, Object element)
|
||||
{
|
||||
super.add(index, transfer(element));
|
||||
}
|
||||
}
|
||||
|
||||
public JSONObject()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public JSONObject(final JSONObject other)
|
||||
{
|
||||
super(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
try
|
||||
{
|
||||
return JSON.marshal(this);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为紧凑格式的字符串。
|
||||
*
|
||||
* @return 返回本对象紧凑格式字符串。
|
||||
*/
|
||||
public String toCompactString()
|
||||
{
|
||||
try
|
||||
{
|
||||
return objectMapper.writeValueAsString(this);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的整数值。如果字段不存在,或者无法转换为整数,返回null。
|
||||
*
|
||||
* @param name 字段名,支持多级。
|
||||
* @return 返回指定的整数值,或者null。
|
||||
*/
|
||||
public Integer intValue(final String name)
|
||||
{
|
||||
return valueAsInt(value(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的整数值。如果字段不存在,或者无法转换为整数,返回defaultValue。
|
||||
*
|
||||
* @param name 字段名,支持多级。
|
||||
* @param defaultValue 查询失败时,返回的值。
|
||||
* @return 返回指定的整数值,或者defaultValue。
|
||||
*/
|
||||
public Integer intValue(final String name, final Integer defaultValue)
|
||||
{
|
||||
return StringUtils.nvl(intValue(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的长整数值。如果字段不存在,或者无法转换为长整数,返回null。
|
||||
*
|
||||
* @param name 字段名,支持多级。
|
||||
* @return 返回指定的长整数值,或者null。
|
||||
*/
|
||||
public Long longValue(final String name)
|
||||
{
|
||||
return valueAsLong(value(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的长整数值。如果字段不存在,或者无法转换为长整数,返回defaultValue。
|
||||
*
|
||||
* @param name 字段名,支持多级。
|
||||
* @param defaultValue 查询失败时,返回的值。
|
||||
* @return 返回指定的长整数值,或者defaultValue。
|
||||
*/
|
||||
public Long longValue(final String name, final Long defaultValue)
|
||||
{
|
||||
return StringUtils.nvl(longValue(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的布尔值。如果字段不存在,或者无法转换为布尔型,返回null。
|
||||
*
|
||||
* @param name 字段名,支持多级。
|
||||
* @return 返回指定的布尔值,或者null。
|
||||
*/
|
||||
public Boolean boolValue(final String name)
|
||||
{
|
||||
return valueAsBool(value(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的布尔值。如果字段不存在,或者无法转换为布尔型,返回defaultValue。
|
||||
*
|
||||
* @param name 字段名,支持多级。
|
||||
* @param defaultValue 查询失败时,返回的值。
|
||||
* @return 返回指定的布尔值,或者defaultValue。
|
||||
*/
|
||||
public Boolean boolValue(final String name, final Boolean defaultValue)
|
||||
{
|
||||
return StringUtils.nvl(boolValue(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的字符串值。如果字段不存在,返回null。
|
||||
*
|
||||
* @param name 字段名,支持多级。
|
||||
* @return 返回指定的字符串值,或者null。
|
||||
*/
|
||||
public String strValue(final String name)
|
||||
{
|
||||
return valueAsStr(value(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的字符串值。如果字段不存在,返回defaultValue。
|
||||
*
|
||||
* @param name 字段名,支持多级。
|
||||
* @param defaultValue 查询失败时,返回的值。
|
||||
* @return 返回指定的字符串值,或者defaultValue。
|
||||
*/
|
||||
public String strValue(final String name, final String defaultValue)
|
||||
{
|
||||
return StringUtils.nvl(strValue(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定字段的值。
|
||||
*
|
||||
* @param name 字段名,支持多级,支持数组下标。
|
||||
* @return 返回指定字段的值。
|
||||
*/
|
||||
public Object value(final String name)
|
||||
{
|
||||
final int indexDot = name.indexOf('.');
|
||||
if (indexDot >= 0)
|
||||
{
|
||||
return obj(name.substring(0, indexDot)).value(name.substring(indexDot + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
final Matcher matcher = arrayNamePattern.matcher(name);
|
||||
if (matcher.find())
|
||||
{
|
||||
return endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<Object>()
|
||||
{
|
||||
public Object callback(JSONArray arr, int index)
|
||||
{
|
||||
return elementAt(arr, index);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
return get(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置指定字段的值。
|
||||
*
|
||||
* @param name 字段名,支持多级,支持数组下标。
|
||||
* @param value 字段值。
|
||||
* @return 返回本对象。
|
||||
*/
|
||||
public JSONObject value(final String name, final Object value)
|
||||
{
|
||||
final int indexDot = name.indexOf('.');
|
||||
if (indexDot >= 0)
|
||||
{
|
||||
obj(name.substring(0, indexDot)).value(name.substring(indexDot + 1), value);
|
||||
}
|
||||
else
|
||||
{
|
||||
final Matcher matcher = arrayNamePattern.matcher(name);
|
||||
if (matcher.find())
|
||||
{
|
||||
endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<Void>()
|
||||
{
|
||||
public Void callback(JSONArray arr, int index)
|
||||
{
|
||||
elementAt(arr, index, value);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
set(name, value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象(非标量类型)字段。返回的数据是一个结构体。当不存在指定对象时,则为指定的名字创建一个空的MessageObject对象。
|
||||
*
|
||||
* @param name 字段名。不支持多级名字,支持数组下标。
|
||||
* @return 返回指定的对象。如果对象不存在,则为指定的名字创建一个空的MessageObject对象。
|
||||
*/
|
||||
public JSONObject obj(final String name)
|
||||
{
|
||||
final Matcher matcher = arrayNamePattern.matcher(name);
|
||||
if (matcher.find())
|
||||
{
|
||||
return endArray(matcher.group(1), matcher.group(2), new EndArrayCallback<JSONObject>()
|
||||
{
|
||||
public JSONObject callback(JSONArray arr, int index)
|
||||
{
|
||||
return objAt(arr, index);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
JSONObject obj = getObj(name);
|
||||
if (obj == null)
|
||||
{
|
||||
obj = new JSONObject();
|
||||
put(name, obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数组字段。将名字对应的对象以数组对象返回,当指定的字段不存在时,创建一个空的数组。
|
||||
*
|
||||
* @param name 字段名。不支持多级名字,不支持下标。
|
||||
* @return 返回一个数组(List)。
|
||||
*/
|
||||
public JSONArray arr(final String name)
|
||||
{
|
||||
JSONArray arr = getArr(name);
|
||||
if (arr == null)
|
||||
{
|
||||
arr = new JSONArray();
|
||||
put(name, arr);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象(非标量类型)字段。返回的数据是一个结构体。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @return 返回指定的对象字段。
|
||||
*/
|
||||
public JSONObject getObj(final String name)
|
||||
{
|
||||
return (JSONObject) get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数组类型字段。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @return 返回数组类型字段。
|
||||
*/
|
||||
public JSONArray getArr(final String name)
|
||||
{
|
||||
return (JSONArray) get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回字段整数值。如果不存在,返回null。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @return 返回指定字段整数值。
|
||||
*/
|
||||
public Integer getInt(final String name)
|
||||
{
|
||||
return valueAsInt(get(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回字段整数值。如果不存在,返回defaultValue。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @param defaultValue 字段不存在时,返回的值。
|
||||
* @return 返回指定字段整数值。
|
||||
*/
|
||||
public Integer getInt(final String name, Integer defaultValue)
|
||||
{
|
||||
return StringUtils.nvl(getInt(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回字段长整数值。如果不存在,返回null。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @return 返回指定字段长整数值。
|
||||
*/
|
||||
public Long getLong(final String name)
|
||||
{
|
||||
return valueAsLong(get(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回字段长整数值。如果不存在,返回defaultValue。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @param defaultValue 字段不存在时,返回的值。
|
||||
* @return 返回指定字段长整数值。
|
||||
*/
|
||||
public Long getLong(final String name, Long defaultValue)
|
||||
{
|
||||
return StringUtils.nvl(getLong(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回字段字符串值。如果不存在,返回null。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @return 返回指定字段字符串值。
|
||||
*/
|
||||
public String getStr(final String name)
|
||||
{
|
||||
return valueAsStr(get(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回字段字符串值。如果不存在,返回defaultValue。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @param defaultValue 字段不存在时,返回的值。
|
||||
* @return 返回指定字段字符串值。
|
||||
*/
|
||||
public String getStr(final String name, final String defaultValue)
|
||||
{
|
||||
return StringUtils.nvl(getStr(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段值按照布尔类型返回。如果不存在,返回null。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @return 字段值。
|
||||
*/
|
||||
public Boolean getBool(final String name)
|
||||
{
|
||||
return valueAsBool(get(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段值按照布尔类型返回。如果不存在,返回defaultValue。
|
||||
*
|
||||
* @param name 字段名。
|
||||
* @param defaultValue 字段不存在时,返回的值。
|
||||
* @return 字段值。
|
||||
*/
|
||||
public Boolean getBool(final String name, final Boolean defaultValue)
|
||||
{
|
||||
return StringUtils.nvl(getBool(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段值
|
||||
*
|
||||
* @param name 字段名
|
||||
* @param value 字段值(标量:数字、字符串、布尔型;结构体:MessageObject)。 如果是Map类型同时非MessageObject类型,则自动转换为MessageObject类型再存入
|
||||
* (此时,再修改Map中的数据,将不会体现到本对象中)。
|
||||
* @return 返回本对象
|
||||
*/
|
||||
public JSONObject set(final String name, final Object value)
|
||||
{
|
||||
put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将本对象转换为Java Bean。
|
||||
*
|
||||
* @param beanClass Java Bean的类对象。
|
||||
* @return 返回转换后的Java Bean。
|
||||
*/
|
||||
public <T> T asBean(Class<T> beanClass)
|
||||
{
|
||||
try
|
||||
{
|
||||
return JSON.unmarshal(JSON.marshal(this), beanClass);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重载基类的方法。如果 value 是 Map 类型,但不是 MessageObject 类型,则创建一个包含内容等同于原 Map 的 MessageObject 作为 value(注意:此后再更改 Map 的内容,将不会反映到
|
||||
* MessageObject 中)。 重载此方法的目的是为了使JSON能够正确地解析为MessageObject对象。不建议直接调用此方法,请使用 set(name, value)方法设置字段值。
|
||||
*/
|
||||
@Override
|
||||
public Object put(String key, Object value)
|
||||
{
|
||||
return super.put(key, transfer(value));
|
||||
}
|
||||
|
||||
public static Integer valueAsInt(Object value)
|
||||
{
|
||||
if (value instanceof Integer)
|
||||
{
|
||||
return (Integer) value;
|
||||
}
|
||||
else if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).intValue();
|
||||
}
|
||||
else if (value instanceof String)
|
||||
{
|
||||
return Integer.valueOf((String) value);
|
||||
}
|
||||
else if (value instanceof Boolean)
|
||||
{
|
||||
return ((Boolean) value) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Long valueAsLong(Object value)
|
||||
{
|
||||
if (value instanceof Long)
|
||||
{
|
||||
return (Long) value;
|
||||
}
|
||||
else if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).longValue();
|
||||
}
|
||||
else if (value instanceof String)
|
||||
{
|
||||
return Long.valueOf((String) value);
|
||||
}
|
||||
else if (value instanceof Boolean)
|
||||
{
|
||||
return ((Boolean) value) ? 1L : 0L;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String valueAsStr(Object value)
|
||||
{
|
||||
if (value instanceof String)
|
||||
{
|
||||
return (String) value;
|
||||
}
|
||||
else if (value != null)
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Boolean valueAsBool(Object value)
|
||||
{
|
||||
if (value instanceof Boolean)
|
||||
{
|
||||
return (Boolean) value;
|
||||
}
|
||||
else if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).doubleValue() != 0.0;
|
||||
}
|
||||
else if (value instanceof String)
|
||||
{
|
||||
return Boolean.valueOf((String) value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有层次中凡是Map类型同时又不是MessageObject的类型,转换为MessageObject类型。
|
||||
*
|
||||
* @param value 值。
|
||||
* @return 返回转换后的值。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Object transfer(final Object value)
|
||||
{
|
||||
if (!(value instanceof JSONObject) && value instanceof Map)
|
||||
{
|
||||
return toObj((Map<String, Object>) value);
|
||||
}
|
||||
else if (!(value instanceof JSONArray) && value instanceof Collection)
|
||||
{
|
||||
return toArr((Collection<Object>) value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private static JSONArray toArr(final Collection<Object> list)
|
||||
{
|
||||
final JSONArray arr = new JSONArray(list.size());
|
||||
for (final Object element : list)
|
||||
{
|
||||
arr.add(element);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
private static JSONObject toObj(final Map<String, Object> map)
|
||||
{
|
||||
final JSONObject obj = new JSONObject();
|
||||
for (final Map.Entry<String, Object> ent : map.entrySet())
|
||||
{
|
||||
obj.put(ent.getKey(), transfer(ent.getValue()));
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定下标元素作为数组返回,如果不存在,则在该位置创建一个空的数组。
|
||||
*
|
||||
* @param arr 当前数组。
|
||||
* @param index 下标。
|
||||
* @return 返回当前数组指定下标的元素,该元素应该是一个数组。
|
||||
*/
|
||||
private static JSONArray arrayAt(JSONArray arr, int index)
|
||||
{
|
||||
expand(arr, index);
|
||||
if (arr.get(index) == null)
|
||||
{
|
||||
arr.set(index, new JSONArray());
|
||||
}
|
||||
return (JSONArray) arr.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定下标元素作为结构体返回,如果不存在,则在该位置创建一个空的结构体。
|
||||
*
|
||||
* @param arr 当前数组。
|
||||
* @param index 下标。
|
||||
* @return 返回当前数组指定下标元素,该元素是一个结构体。
|
||||
*/
|
||||
private static JSONObject objAt(final JSONArray arr, int index)
|
||||
{
|
||||
expand(arr, index);
|
||||
if (arr.get(index) == null)
|
||||
{
|
||||
arr.set(index, new JSONObject());
|
||||
}
|
||||
return (JSONObject) arr.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数组指定下标位置的值。
|
||||
*
|
||||
* @param arr 数组。
|
||||
* @param index 下标。
|
||||
* @param value 值。
|
||||
*/
|
||||
private static void elementAt(final JSONArray arr, final int index, final Object value)
|
||||
{
|
||||
expand(arr, index).set(index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数组指定下标元素的值。
|
||||
*
|
||||
* @param arr 数组。
|
||||
* @param index 下标。
|
||||
* @return 值。
|
||||
*/
|
||||
private static Object elementAt(final JSONArray arr, final int index)
|
||||
{
|
||||
return expand(arr, index).get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扩展数组到指定下标,以防止访问时下标越界。
|
||||
*
|
||||
* @param arr 数组
|
||||
* @param index 下标
|
||||
* @return 返回传入的数组
|
||||
*/
|
||||
private static JSONArray expand(final JSONArray arr, final int index)
|
||||
{
|
||||
while (arr.size() <= index)
|
||||
{
|
||||
arr.add(null);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 最后数组回调。
|
||||
*
|
||||
* @author Mike
|
||||
*
|
||||
* @param <T> 回调返回数据类型。
|
||||
*/
|
||||
private interface EndArrayCallback<T>
|
||||
{
|
||||
/**
|
||||
* 当定位到最后一级数组,将调用本方法。
|
||||
*
|
||||
* @param arr 最后一级数组对象。
|
||||
* @param index 最后一级索引。
|
||||
* @return 返回回调的返回值。
|
||||
*/
|
||||
T callback(JSONArray arr, int index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理多维数组的工具函数(包括一维数组)。多维数组的名字如:arrary[1][2][3], 则name=array,indexStr=[1][2][3],在callback中,endArr将是
|
||||
* array[1][2]指定的对象,indexe=3。
|
||||
*
|
||||
* @param name 不带下标的名字,不支持多级名字。
|
||||
* @param indexesStr 索引部分的字符串,如:[1][2][3]
|
||||
* @param callback 回调函数。
|
||||
* @return 返回回调函数的返回值。
|
||||
*/
|
||||
private <T> T endArray(final String name, final String indexesStr, final EndArrayCallback<T> callback)
|
||||
{
|
||||
JSONArray endArr = arr(name);
|
||||
final int[] indexes = parseIndexes(indexesStr);
|
||||
int i = 0;
|
||||
while (i < indexes.length - 1)
|
||||
{
|
||||
endArr = arrayAt(endArr, indexes[i++]);
|
||||
}
|
||||
return callback.callback(endArr, indexes[i]);
|
||||
}
|
||||
|
||||
private static int[] parseIndexes(final String s)
|
||||
{
|
||||
int[] indexes = null;
|
||||
List<Integer> list = new ArrayList<Integer>();
|
||||
|
||||
final StringTokenizer st = new StringTokenizer(s, "[]");
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
final int index = Integer.valueOf(st.nextToken());
|
||||
if (index < 0)
|
||||
{
|
||||
throw new RuntimeException(String.format("Illegal index %1$d in \"%2$s\"", index, s));
|
||||
}
|
||||
|
||||
list.add(index);
|
||||
}
|
||||
|
||||
indexes = new int[list.size()];
|
||||
int i = 0;
|
||||
for (Integer tmp : list.toArray(new Integer[list.size()]))
|
||||
{
|
||||
indexes[i++] = tmp;
|
||||
}
|
||||
|
||||
return indexes;
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.ruoyi.common.support;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 字符集工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class CharsetKit
|
||||
{
|
||||
/** ISO-8859-1 */
|
||||
public static final String ISO_8859_1 = "ISO-8859-1";
|
||||
/** UTF-8 */
|
||||
public static final String UTF_8 = "UTF-8";
|
||||
/** GBK */
|
||||
public static final String GBK = "GBK";
|
||||
|
||||
/** ISO-8859-1 */
|
||||
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
|
||||
/** UTF-8 */
|
||||
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
|
||||
/** GBK */
|
||||
public static final Charset CHARSET_GBK = Charset.forName(GBK);
|
||||
|
||||
/**
|
||||
* 转换为Charset对象
|
||||
*
|
||||
* @param charset 字符集,为空则返回默认字符集
|
||||
* @return Charset
|
||||
*/
|
||||
public static Charset charset(String charset)
|
||||
{
|
||||
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串的字符集编码
|
||||
*
|
||||
* @param source 字符串
|
||||
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||
* @param destCharset 目标字符集,默认UTF-8
|
||||
* @return 转换后的字符集
|
||||
*/
|
||||
public static String convert(String source, String srcCharset, String destCharset)
|
||||
{
|
||||
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换字符串的字符集编码
|
||||
*
|
||||
* @param source 字符串
|
||||
* @param srcCharset 源字符集,默认ISO-8859-1
|
||||
* @param destCharset 目标字符集,默认UTF-8
|
||||
* @return 转换后的字符集
|
||||
*/
|
||||
public static String convert(String source, Charset srcCharset, Charset destCharset)
|
||||
{
|
||||
if (null == srcCharset)
|
||||
{
|
||||
srcCharset = StandardCharsets.ISO_8859_1;
|
||||
}
|
||||
|
||||
if (null == destCharset)
|
||||
{
|
||||
srcCharset = StandardCharsets.UTF_8;
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
|
||||
{
|
||||
return source;
|
||||
}
|
||||
return new String(source.getBytes(srcCharset), destCharset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 系统字符集编码
|
||||
*/
|
||||
public static String systemCharset()
|
||||
{
|
||||
return Charset.defaultCharset().name();
|
||||
}
|
||||
}
|
999
ruoyi-common/src/main/java/com/ruoyi/common/support/Convert.java
Normal file
999
ruoyi-common/src/main/java/com/ruoyi/common/support/Convert.java
Normal file
@ -0,0 +1,999 @@
|
||||
package com.ruoyi.common.support;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Set;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 类型转换器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class Convert
|
||||
{
|
||||
/**
|
||||
* 转换为字符串<br>
|
||||
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static String toStr(Object value, String defaultValue)
|
||||
{
|
||||
if (null == value)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof String)
|
||||
{
|
||||
return (String) value;
|
||||
}
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为字符串<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static String toStr(Object value)
|
||||
{
|
||||
return toStr(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为字符<br>
|
||||
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Character toChar(Object value, Character defaultValue)
|
||||
{
|
||||
if (null == value)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Character)
|
||||
{
|
||||
return (Character) value;
|
||||
}
|
||||
|
||||
final String valueStr = toStr(value, null);
|
||||
return StringUtils.isEmpty(valueStr) ? defaultValue : valueStr.charAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为字符<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Character toChar(Object value)
|
||||
{
|
||||
return toChar(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为byte<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Byte toByte(Object value, Byte defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Byte)
|
||||
{
|
||||
return (Byte) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).byteValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Byte.parseByte(valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为byte<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Byte toByte(Object value)
|
||||
{
|
||||
return toByte(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Short<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Short toShort(Object value, Short defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Short)
|
||||
{
|
||||
return (Short) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).shortValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Short.parseShort(valueStr.trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Short<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Short toShort(Object value)
|
||||
{
|
||||
return toShort(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Number<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Number toNumber(Object value, Number defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return (Number) value;
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return NumberFormat.getInstance().parse(valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Number<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Number toNumber(Object value)
|
||||
{
|
||||
return toNumber(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为int<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Integer toInt(Object value, Integer defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Integer)
|
||||
{
|
||||
return (Integer) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).intValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Integer.parseInt(valueStr.trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为int<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Integer toInt(Object value)
|
||||
{
|
||||
return toInt(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Integer数组<br>
|
||||
*
|
||||
* @param split 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Integer[] toIntArray(String str)
|
||||
{
|
||||
return toIntArray(",", str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Long数组<br>
|
||||
*
|
||||
* @param split 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long[] toLongArray(String str)
|
||||
{
|
||||
return toLongArray(",", str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Integer数组<br>
|
||||
*
|
||||
* @param split 分隔符
|
||||
* @param split 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Integer[] toIntArray(String split, String str)
|
||||
{
|
||||
if (StringUtils.isEmpty(str))
|
||||
{
|
||||
return new Integer[] {};
|
||||
}
|
||||
String[] arr = str.split(split);
|
||||
final Integer[] ints = new Integer[arr.length];
|
||||
for (int i = 0; i < arr.length; i++)
|
||||
{
|
||||
final Integer v = toInt(arr[i], 0);
|
||||
ints[i] = v;
|
||||
}
|
||||
return ints;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Long数组<br>
|
||||
*
|
||||
* @param isIgnoreConvertError 是否忽略转换错误,忽略则给值null
|
||||
* @param values 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long[] toLongArray(String split, String str)
|
||||
{
|
||||
if (StringUtils.isEmpty(str))
|
||||
{
|
||||
return new Long[] {};
|
||||
}
|
||||
String[] arr = str.split(split);
|
||||
final Long[] longs = new Long[arr.length];
|
||||
for (int i = 0; i < arr.length; i++)
|
||||
{
|
||||
final Long v = toLong(arr[i], null);
|
||||
longs[i] = v;
|
||||
}
|
||||
return longs;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为String数组<br>
|
||||
*
|
||||
* @param split 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static String[] toStrArray(String str)
|
||||
{
|
||||
return toStrArray(",", str);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为String数组<br>
|
||||
*
|
||||
* @param split 分隔符
|
||||
* @param split 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static String[] toStrArray(String split, String str)
|
||||
{
|
||||
return str.split(split);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为long<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long toLong(Object value, Long defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Long)
|
||||
{
|
||||
return (Long) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).longValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
// 支持科学计数法
|
||||
return new BigDecimal(valueStr.trim()).longValue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为long<br>
|
||||
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Long toLong(Object value)
|
||||
{
|
||||
return toLong(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为double<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Double toDouble(Object value, Double defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Double)
|
||||
{
|
||||
return (Double) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).doubleValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
// 支持科学计数法
|
||||
return new BigDecimal(valueStr.trim()).doubleValue();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为double<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Double toDouble(Object value)
|
||||
{
|
||||
return toDouble(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Float<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Float toFloat(Object value, Float defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Float)
|
||||
{
|
||||
return (Float) value;
|
||||
}
|
||||
if (value instanceof Number)
|
||||
{
|
||||
return ((Number) value).floatValue();
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Float.parseFloat(valueStr.trim());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Float<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Float toFloat(Object value)
|
||||
{
|
||||
return toFloat(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为boolean<br>
|
||||
* String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Boolean toBool(Object value, Boolean defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof Boolean)
|
||||
{
|
||||
return (Boolean) value;
|
||||
}
|
||||
String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
valueStr = valueStr.trim().toLowerCase();
|
||||
switch (valueStr)
|
||||
{
|
||||
case "true":
|
||||
return true;
|
||||
case "false":
|
||||
return false;
|
||||
case "yes":
|
||||
return true;
|
||||
case "ok":
|
||||
return true;
|
||||
case "no":
|
||||
return false;
|
||||
case "1":
|
||||
return true;
|
||||
case "0":
|
||||
return false;
|
||||
default:
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为boolean<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static Boolean toBool(Object value)
|
||||
{
|
||||
return toBool(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Enum对象<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
*
|
||||
* @param clazz Enum的Class
|
||||
* @param value 值
|
||||
* @param defaultValue 默认值
|
||||
* @return Enum
|
||||
*/
|
||||
public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (clazz.isAssignableFrom(value.getClass()))
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
E myE = (E) value;
|
||||
return myE;
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return Enum.valueOf(clazz, valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为Enum对象<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
*
|
||||
* @param clazz Enum的Class
|
||||
* @param value 值
|
||||
* @return Enum
|
||||
*/
|
||||
public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value)
|
||||
{
|
||||
return toEnum(clazz, value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为BigInteger<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigInteger toBigInteger(Object value, BigInteger defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof BigInteger)
|
||||
{
|
||||
return (BigInteger) value;
|
||||
}
|
||||
if (value instanceof Long)
|
||||
{
|
||||
return BigInteger.valueOf((Long) value);
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return new BigInteger(valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为BigInteger<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigInteger toBigInteger(Object value)
|
||||
{
|
||||
return toBigInteger(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为BigDecimal<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @param defaultValue 转换错误时的默认值
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
if (value instanceof BigDecimal)
|
||||
{
|
||||
return (BigDecimal) value;
|
||||
}
|
||||
if (value instanceof Long)
|
||||
{
|
||||
return new BigDecimal((Long) value);
|
||||
}
|
||||
if (value instanceof Double)
|
||||
{
|
||||
return new BigDecimal((Double) value);
|
||||
}
|
||||
if (value instanceof Integer)
|
||||
{
|
||||
return new BigDecimal((Integer) value);
|
||||
}
|
||||
final String valueStr = toStr(value, null);
|
||||
if (StringUtils.isEmpty(valueStr))
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
try
|
||||
{
|
||||
return new BigDecimal(valueStr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为BigDecimal<br>
|
||||
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||
* 转换失败不会报错
|
||||
*
|
||||
* @param value 被转换的值
|
||||
* @return 结果
|
||||
*/
|
||||
public static BigDecimal toBigDecimal(Object value)
|
||||
{
|
||||
return toBigDecimal(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转为字符串<br>
|
||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String utf8Str(Object obj)
|
||||
{
|
||||
return str(obj, CharsetKit.CHARSET_UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转为字符串<br>
|
||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||
*
|
||||
* @param obj 对象
|
||||
* @param charsetName 字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(Object obj, String charsetName)
|
||||
{
|
||||
return str(obj, Charset.forName(charsetName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象转为字符串<br>
|
||||
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
|
||||
*
|
||||
* @param obj 对象
|
||||
* @param charset 字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(Object obj, Charset charset)
|
||||
{
|
||||
if (null == obj)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (obj instanceof String)
|
||||
{
|
||||
return (String) obj;
|
||||
}
|
||||
else if (obj instanceof byte[] || obj instanceof Byte[])
|
||||
{
|
||||
return str((Byte[]) obj, charset);
|
||||
}
|
||||
else if (obj instanceof ByteBuffer)
|
||||
{
|
||||
return str((ByteBuffer) obj, charset);
|
||||
}
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将byte数组转为字符串
|
||||
*
|
||||
* @param bytes byte数组
|
||||
* @param charset 字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(byte[] bytes, String charset)
|
||||
{
|
||||
return str(bytes, StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码字节码
|
||||
*
|
||||
* @param data 字符串
|
||||
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
|
||||
* @return 解码后的字符串
|
||||
*/
|
||||
public static String str(byte[] data, Charset charset)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (null == charset)
|
||||
{
|
||||
return new String(data);
|
||||
}
|
||||
return new String(data, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将编码的byteBuffer数据转换为字符串
|
||||
*
|
||||
* @param data 数据
|
||||
* @param charset 字符集,如果为空使用当前系统字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(ByteBuffer data, String charset)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return str(data, Charset.forName(charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将编码的byteBuffer数据转换为字符串
|
||||
*
|
||||
* @param data 数据
|
||||
* @param charset 字符集,如果为空使用当前系统字符集
|
||||
* @return 字符串
|
||||
*/
|
||||
public static String str(ByteBuffer data, Charset charset)
|
||||
{
|
||||
if (null == charset)
|
||||
{
|
||||
charset = Charset.defaultCharset();
|
||||
}
|
||||
return charset.decode(data).toString();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- 全角半角转换
|
||||
/**
|
||||
* 半角转全角
|
||||
*
|
||||
* @param input String.
|
||||
* @return 全角字符串.
|
||||
*/
|
||||
public static String toSBC(String input)
|
||||
{
|
||||
return toSBC(input, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 半角转全角
|
||||
*
|
||||
* @param input String
|
||||
* @param notConvertSet 不替换的字符集合
|
||||
* @return 全角字符串.
|
||||
*/
|
||||
public static String toSBC(String input, Set<Character> notConvertSet)
|
||||
{
|
||||
char c[] = input.toCharArray();
|
||||
for (int i = 0; i < c.length; i++)
|
||||
{
|
||||
if (null != notConvertSet && notConvertSet.contains(c[i]))
|
||||
{
|
||||
// 跳过不替换的字符
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c[i] == ' ')
|
||||
{
|
||||
c[i] = '\u3000';
|
||||
}
|
||||
else if (c[i] < '\177')
|
||||
{
|
||||
c[i] = (char) (c[i] + 65248);
|
||||
|
||||
}
|
||||
}
|
||||
return new String(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* 全角转半角
|
||||
*
|
||||
* @param input String.
|
||||
* @return 半角字符串
|
||||
*/
|
||||
public static String toDBC(String input)
|
||||
{
|
||||
return toDBC(input, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换全角为半角
|
||||
*
|
||||
* @param text 文本
|
||||
* @param notConvertSet 不替换的字符集合
|
||||
* @return 替换后的字符
|
||||
*/
|
||||
public static String toDBC(String text, Set<Character> notConvertSet)
|
||||
{
|
||||
char c[] = text.toCharArray();
|
||||
for (int i = 0; i < c.length; i++)
|
||||
{
|
||||
if (null != notConvertSet && notConvertSet.contains(c[i]))
|
||||
{
|
||||
// 跳过不替换的字符
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c[i] == '\u3000')
|
||||
{
|
||||
c[i] = ' ';
|
||||
}
|
||||
else if (c[i] > '\uFF00' && c[i] < '\uFF5F')
|
||||
{
|
||||
c[i] = (char) (c[i] - 65248);
|
||||
}
|
||||
}
|
||||
String returnString = new String(c);
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字金额大写转换 先写个完整的然后将如零拾替换成零
|
||||
*
|
||||
* @param n 数字
|
||||
* @return 中文大写数字
|
||||
*/
|
||||
public static String digitUppercase(double n)
|
||||
{
|
||||
String[] fraction = { "角", "分" };
|
||||
String[] digit = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
|
||||
String[][] unit = { { "元", "万", "亿" }, { "", "拾", "佰", "仟" } };
|
||||
|
||||
String head = n < 0 ? "负" : "";
|
||||
n = Math.abs(n);
|
||||
|
||||
String s = "";
|
||||
for (int i = 0; i < fraction.length; i++)
|
||||
{
|
||||
s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
||||
}
|
||||
if (s.length() < 1)
|
||||
{
|
||||
s = "整";
|
||||
}
|
||||
int integerPart = (int) Math.floor(n);
|
||||
|
||||
for (int i = 0; i < unit[0].length && integerPart > 0; i++)
|
||||
{
|
||||
String p = "";
|
||||
for (int j = 0; j < unit[1].length && n > 0; j++)
|
||||
{
|
||||
p = digit[integerPart % 10] + unit[1][j] + p;
|
||||
integerPart = integerPart / 10;
|
||||
}
|
||||
s = p.replaceAll("(零.)*零$", "").replaceAll("^$", "零") + unit[0][i] + s;
|
||||
}
|
||||
return head + s.replaceAll("(零.)*零元", "元").replaceFirst("(零.)+", "").replaceAll("(零.)+", "零").replaceAll("^整$", "零元整");
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package com.ruoyi.common.support;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 字符串格式化
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class StrFormatter
|
||||
{
|
||||
public static final String EMPTY_JSON = "{}";
|
||||
public static final char C_BACKSLASH = '\\';
|
||||
public static final char C_DELIM_START = '{';
|
||||
public static final char C_DELIM_END = '}';
|
||||
|
||||
/**
|
||||
* 格式化字符串<br>
|
||||
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||
* 例:<br>
|
||||
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
|
||||
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
|
||||
*
|
||||
* @param strPattern 字符串模板
|
||||
* @param argArray 参数列表
|
||||
* @return 结果
|
||||
*/
|
||||
public static String format(final String strPattern, final Object... argArray)
|
||||
{
|
||||
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
|
||||
{
|
||||
return strPattern;
|
||||
}
|
||||
final int strPatternLength = strPattern.length();
|
||||
|
||||
// 初始化定义好的长度以获得更好的性能
|
||||
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
|
||||
|
||||
int handledPosition = 0;
|
||||
int delimIndex;// 占位符所在位置
|
||||
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
|
||||
{
|
||||
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
|
||||
if (delimIndex == -1)
|
||||
{
|
||||
if (handledPosition == 0)
|
||||
{
|
||||
return strPattern;
|
||||
}
|
||||
else
|
||||
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
|
||||
sbuf.append(strPattern, handledPosition, strPatternLength);
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
|
||||
{
|
||||
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
|
||||
{
|
||||
// 转义符之前还有一个转义符,占位符依旧有效
|
||||
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||
handledPosition = delimIndex + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 占位符被转义
|
||||
argIndex--;
|
||||
sbuf.append(strPattern, handledPosition, delimIndex - 1);
|
||||
sbuf.append(C_DELIM_START);
|
||||
handledPosition = delimIndex + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常占位符
|
||||
sbuf.append(strPattern, handledPosition, delimIndex);
|
||||
sbuf.append(Convert.utf8Str(argArray[argIndex]));
|
||||
handledPosition = delimIndex + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 加入最后一个占位符后所有的字符
|
||||
sbuf.append(strPattern, handledPosition, strPattern.length());
|
||||
|
||||
return sbuf.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.ruoyi.common.config.Global;
|
||||
import com.ruoyi.common.json.JSON;
|
||||
import com.ruoyi.common.json.JSONObject;
|
||||
import com.ruoyi.common.utils.http.HttpUtils;
|
||||
|
||||
/**
|
||||
* 获取地址类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class AddressUtils
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
|
||||
|
||||
public static final String IP_URL = "http://ip.taobao.com/service/getIpInfo.php";
|
||||
|
||||
public static String getRealAddressByIP(String ip)
|
||||
{
|
||||
String address = "XX XX";
|
||||
if (Global.isAddressEnabled())
|
||||
{
|
||||
String rspStr = HttpUtils.sendPost(IP_URL, "ip=" + ip);
|
||||
if (StringUtils.isEmpty(rspStr))
|
||||
{
|
||||
log.error("获取地理位置异常 {}", ip);
|
||||
return address;
|
||||
}
|
||||
JSONObject obj;
|
||||
try
|
||||
{
|
||||
obj = JSON.unmarshal(rspStr, JSONObject.class);
|
||||
JSONObject data = obj.getObj("data");
|
||||
String region = data.getStr("region");
|
||||
String city = data.getStr("city");
|
||||
address = region + " " + city;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("获取地理位置异常 {}", ip);
|
||||
}
|
||||
}
|
||||
return address;
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
|
||||
/**
|
||||
* 时间工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class DateUtils
|
||||
{
|
||||
public static String YYYY = "yyyy";
|
||||
|
||||
public static String YYYY_MM = "yyyy-MM";
|
||||
|
||||
public static String YYYY_MM_DD = "yyyy-MM-dd";
|
||||
|
||||
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
|
||||
|
||||
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 获取当前Date型日期
|
||||
*
|
||||
* @return Date() 当前日期
|
||||
*/
|
||||
public static Date getNowDate()
|
||||
{
|
||||
return new Date();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前日期, 默认格式为yyyy-MM-dd
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getDate()
|
||||
{
|
||||
return dateTimeNow(YYYY_MM_DD);
|
||||
}
|
||||
|
||||
public static final String getTime()
|
||||
{
|
||||
return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
|
||||
}
|
||||
|
||||
public static final String dateTimeNow()
|
||||
{
|
||||
return dateTimeNow(YYYYMMDDHHMMSS);
|
||||
}
|
||||
|
||||
public static final String dateTimeNow(final String format)
|
||||
{
|
||||
return parseDateToStr(format, new 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)
|
||||
{
|
||||
return new SimpleDateFormat(format).format(date);
|
||||
}
|
||||
|
||||
public static final Date dateTime(final String format, final String ts)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new SimpleDateFormat(format).parse(ts);
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期路径 即年/月/日 如2018/08/08
|
||||
*/
|
||||
public static final String datePath()
|
||||
{
|
||||
Date now = new Date();
|
||||
return DateFormatUtils.format(now, "yyyy/MM/dd");
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期路径 即年/月/日 如20180808
|
||||
*/
|
||||
public static final String dateTime()
|
||||
{
|
||||
Date now = new Date();
|
||||
return DateFormatUtils.format(now, "yyyyMMdd");
|
||||
}
|
||||
}
|
483
ruoyi-common/src/main/java/com/ruoyi/common/utils/ExcelUtil.java
Normal file
483
ruoyi-common/src/main/java/com/ruoyi/common/utils/ExcelUtil.java
Normal file
@ -0,0 +1,483 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.apache.poi.hssf.usermodel.DVConstraint;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
|
||||
import org.apache.poi.hssf.usermodel.HSSFFont;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRow;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.HSSFColor.HSSFColorPredefined;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.ss.usermodel.FillPatternType;
|
||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.VerticalAlignment;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.base.AjaxResult;
|
||||
import com.ruoyi.common.config.Global;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* Excel相关处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class ExcelUtil<T>
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
|
||||
|
||||
public Class<T> clazz;
|
||||
|
||||
public ExcelUtil(Class<T> clazz)
|
||||
{
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对excel表单默认第一个索引名转换成list
|
||||
*
|
||||
* @param input 输入流
|
||||
* @return 转换后集合
|
||||
*/
|
||||
public List<T> importExcel(InputStream input) throws Exception
|
||||
{
|
||||
return importExcel(StringUtils.EMPTY, input);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对excel表单指定表格索引名转换成list
|
||||
*
|
||||
* @param sheetName 表格索引名
|
||||
* @param input 输入流
|
||||
* @return 转换后集合
|
||||
*/
|
||||
public List<T> importExcel(String sheetName, InputStream input) throws Exception
|
||||
{
|
||||
List<T> list = new ArrayList<T>();
|
||||
|
||||
Workbook workbook = WorkbookFactory.create(input);
|
||||
Sheet sheet = null;
|
||||
if (StringUtils.isNotEmpty(sheetName))
|
||||
{
|
||||
// 如果指定sheet名,则取指定sheet中的内容.
|
||||
sheet = workbook.getSheet(sheetName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果传入的sheet名不存在则默认指向第1个sheet.
|
||||
sheet = workbook.getSheetAt(0);
|
||||
}
|
||||
|
||||
if (sheet == null)
|
||||
{
|
||||
throw new IOException("文件sheet不存在");
|
||||
}
|
||||
|
||||
int rows = sheet.getPhysicalNumberOfRows();
|
||||
|
||||
if (rows > 0)
|
||||
{
|
||||
// 默认序号
|
||||
int serialNum = 0;
|
||||
// 有数据时才处理 得到类的所有field.
|
||||
Field[] allFields = clazz.getDeclaredFields();
|
||||
// 定义一个map用于存放列的序号和field.
|
||||
Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>();
|
||||
for (int col = 0; col < allFields.length; col++)
|
||||
{
|
||||
Field field = allFields[col];
|
||||
// 将有注解的field存放到map中.
|
||||
if (field.isAnnotationPresent(Excel.class))
|
||||
{
|
||||
// 设置类的私有字段属性可访问.
|
||||
field.setAccessible(true);
|
||||
fieldsMap.put(++serialNum, field);
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < rows; i++)
|
||||
{
|
||||
// 从第2行开始取数据,默认第一行是表头.
|
||||
Row row = sheet.getRow(i);
|
||||
int cellNum = serialNum;
|
||||
T entity = null;
|
||||
for (int j = 0; j < cellNum; j++)
|
||||
{
|
||||
Cell cell = row.getCell(j);
|
||||
if (cell == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 先设置Cell的类型,然后就可以把纯数字作为String类型读进来了
|
||||
row.getCell(j).setCellType(CellType.STRING);
|
||||
cell = row.getCell(j);
|
||||
}
|
||||
|
||||
String c = cell.getStringCellValue();
|
||||
if (StringUtils.isEmpty(c))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 如果不存在实例则新建.
|
||||
entity = (entity == null ? clazz.newInstance() : entity);
|
||||
// 从map中得到对应列的field.
|
||||
Field field = fieldsMap.get(j + 1);
|
||||
// 取得类型,并根据对象类型设置值.
|
||||
Class<?> fieldType = field.getType();
|
||||
if (String.class == fieldType)
|
||||
{
|
||||
field.set(entity, String.valueOf(c));
|
||||
}
|
||||
else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType))
|
||||
{
|
||||
field.set(entity, Integer.parseInt(c));
|
||||
}
|
||||
else if ((Long.TYPE == fieldType) || (Long.class == fieldType))
|
||||
{
|
||||
field.set(entity, Long.valueOf(c));
|
||||
}
|
||||
else if ((Float.TYPE == fieldType) || (Float.class == fieldType))
|
||||
{
|
||||
field.set(entity, Float.valueOf(c));
|
||||
}
|
||||
else if ((Short.TYPE == fieldType) || (Short.class == fieldType))
|
||||
{
|
||||
field.set(entity, Short.valueOf(c));
|
||||
}
|
||||
else if ((Double.TYPE == fieldType) || (Double.class == fieldType))
|
||||
{
|
||||
field.set(entity, Double.valueOf(c));
|
||||
}
|
||||
else if (Character.TYPE == fieldType)
|
||||
{
|
||||
if ((c != null) && (c.length() > 0))
|
||||
{
|
||||
field.set(entity, Character.valueOf(c.charAt(0)));
|
||||
}
|
||||
}
|
||||
else if (java.util.Date.class == fieldType)
|
||||
{
|
||||
if (cell.getCellTypeEnum() == CellType.NUMERIC)
|
||||
{
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
cell.setCellValue(sdf.format(cell.getNumericCellValue()));
|
||||
c = sdf.format(cell.getNumericCellValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
c = cell.getStringCellValue();
|
||||
}
|
||||
}
|
||||
else if (java.math.BigDecimal.class == fieldType)
|
||||
{
|
||||
c = cell.getStringCellValue();
|
||||
}
|
||||
}
|
||||
if (entity != null)
|
||||
{
|
||||
list.add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对list数据源将其里面的数据导入到excel表单
|
||||
*
|
||||
* @param list 导出数据集合
|
||||
* @param sheetName 工作表的名称
|
||||
* @return 结果
|
||||
*/
|
||||
public AjaxResult exportExcel(List<T> list, String sheetName)
|
||||
{
|
||||
OutputStream out = null;
|
||||
HSSFWorkbook workbook = null;
|
||||
try
|
||||
{
|
||||
// 得到所有定义字段
|
||||
Field[] allFields = clazz.getDeclaredFields();
|
||||
List<Field> fields = new ArrayList<Field>();
|
||||
// 得到所有field并存放到一个list中.
|
||||
for (Field field : allFields)
|
||||
{
|
||||
if (field.isAnnotationPresent(Excel.class))
|
||||
{
|
||||
fields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
// 产生工作薄对象
|
||||
workbook = new HSSFWorkbook();
|
||||
// excel2003中每个sheet中最多有65536行
|
||||
int sheetSize = 65536;
|
||||
// 取出一共有多少个sheet.
|
||||
double sheetNo = Math.ceil(list.size() / sheetSize);
|
||||
for (int index = 0; index <= sheetNo; index++)
|
||||
{
|
||||
// 产生工作表对象
|
||||
HSSFSheet sheet = workbook.createSheet();
|
||||
if (sheetNo == 0)
|
||||
{
|
||||
workbook.setSheetName(index, sheetName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 设置工作表的名称.
|
||||
workbook.setSheetName(index, sheetName + index);
|
||||
}
|
||||
HSSFRow row;
|
||||
HSSFCell cell; // 产生单元格
|
||||
|
||||
// 产生一行
|
||||
row = sheet.createRow(0);
|
||||
// 写入各个字段的列头名称
|
||||
for (int i = 0; i < fields.size(); i++)
|
||||
{
|
||||
Field field = fields.get(i);
|
||||
Excel attr = field.getAnnotation(Excel.class);
|
||||
// 创建列
|
||||
cell = row.createCell(i);
|
||||
// 设置列中写入内容为String类型
|
||||
cell.setCellType(CellType.STRING);
|
||||
HSSFCellStyle cellStyle = workbook.createCellStyle();
|
||||
cellStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
if (attr.name().indexOf("注:") >= 0)
|
||||
{
|
||||
HSSFFont font = workbook.createFont();
|
||||
font.setColor(HSSFFont.COLOR_RED);
|
||||
cellStyle.setFont(font);
|
||||
cellStyle.setFillForegroundColor(HSSFColorPredefined.YELLOW.getIndex());
|
||||
sheet.setColumnWidth(i, 6000);
|
||||
}
|
||||
else
|
||||
{
|
||||
HSSFFont font = workbook.createFont();
|
||||
// 粗体显示
|
||||
font.setBold(true);
|
||||
// 选择需要用到的字体格式
|
||||
cellStyle.setFont(font);
|
||||
cellStyle.setFillForegroundColor(HSSFColorPredefined.LIGHT_YELLOW.getIndex());
|
||||
// 设置列宽
|
||||
sheet.setColumnWidth(i, 3766);
|
||||
}
|
||||
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||
cellStyle.setWrapText(true);
|
||||
cell.setCellStyle(cellStyle);
|
||||
|
||||
// 写入列名
|
||||
cell.setCellValue(attr.name());
|
||||
|
||||
// 如果设置了提示信息则鼠标放上去提示.
|
||||
if (StringUtils.isNotEmpty(attr.prompt()))
|
||||
{
|
||||
// 这里默认设了2-101列提示.
|
||||
setHSSFPrompt(sheet, "", attr.prompt(), 1, 100, i, i);
|
||||
}
|
||||
// 如果设置了combo属性则本列只能选择不能输入
|
||||
if (attr.combo().length > 0)
|
||||
{
|
||||
// 这里默认设了2-101列只能选择不能输入.
|
||||
setHSSFValidation(sheet, attr.combo(), 1, 100, i, i);
|
||||
}
|
||||
}
|
||||
|
||||
int startNo = index * sheetSize;
|
||||
int endNo = Math.min(startNo + sheetSize, list.size());
|
||||
// 写入各条记录,每条记录对应excel表中的一行
|
||||
HSSFCellStyle cs = workbook.createCellStyle();
|
||||
cs.setAlignment(HorizontalAlignment.CENTER);
|
||||
cs.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
for (int i = startNo; i < endNo; i++)
|
||||
{
|
||||
row = sheet.createRow(i + 1 - startNo);
|
||||
// 得到导出对象.
|
||||
T vo = (T) list.get(i);
|
||||
for (int j = 0; j < fields.size(); j++)
|
||||
{
|
||||
// 获得field.
|
||||
Field field = fields.get(j);
|
||||
// 设置实体类私有属性可访问
|
||||
field.setAccessible(true);
|
||||
Excel attr = field.getAnnotation(Excel.class);
|
||||
try
|
||||
{
|
||||
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
|
||||
if (attr.isExport())
|
||||
{
|
||||
// 创建cell
|
||||
cell = row.createCell(j);
|
||||
cell.setCellStyle(cs);
|
||||
try
|
||||
{
|
||||
if (String.valueOf(field.get(vo)).length() > 10)
|
||||
{
|
||||
throw new Exception("长度超过10位就不用转数字了");
|
||||
}
|
||||
// 如果可以转成数字则导出为数字类型
|
||||
BigDecimal bc = new BigDecimal(String.valueOf(field.get(vo)));
|
||||
cell.setCellType(CellType.NUMERIC);
|
||||
cell.setCellValue(bc.doubleValue());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
cell.setCellType(CellType.STRING);
|
||||
if (vo == null)
|
||||
{
|
||||
// 如果数据存在就填入,不存在填入空格.
|
||||
cell.setCellValue("");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果数据存在就填入,不存在填入空格.
|
||||
cell.setCellValue(field.get(vo) == null ? "" : String.valueOf(field.get(vo)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("导出Excel失败{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String filename = encodingFilename(sheetName);
|
||||
out = new FileOutputStream(getAbsoluteFile(filename));
|
||||
workbook.write(out);
|
||||
return AjaxResult.success(filename);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("导出Excel异常{}", e.getMessage());
|
||||
return AjaxResult.error("导出Excel失败,请联系网站管理员!");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (workbook != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
workbook.close();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (out != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
out.close();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置单元格上提示
|
||||
*
|
||||
* @param sheet 要设置的sheet.
|
||||
* @param promptTitle 标题
|
||||
* @param promptContent 内容
|
||||
* @param firstRow 开始行
|
||||
* @param endRow 结束行
|
||||
* @param firstCol 开始列
|
||||
* @param endCol 结束列
|
||||
* @return 设置好的sheet.
|
||||
*/
|
||||
public static HSSFSheet setHSSFPrompt(HSSFSheet sheet, String promptTitle, String promptContent, int firstRow,
|
||||
int endRow, int firstCol, int endCol)
|
||||
{
|
||||
// 构造constraint对象
|
||||
DVConstraint constraint = DVConstraint.createCustomFormulaConstraint("DD1");
|
||||
// 四个参数分别是:起始行、终止行、起始列、终止列
|
||||
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
|
||||
// 数据有效性对象
|
||||
HSSFDataValidation dataValidationView = new HSSFDataValidation(regions, constraint);
|
||||
dataValidationView.createPromptBox(promptTitle, promptContent);
|
||||
sheet.addValidationData(dataValidationView);
|
||||
return sheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置某些列的值只能输入预制的数据,显示下拉框.
|
||||
*
|
||||
* @param sheet 要设置的sheet.
|
||||
* @param textlist 下拉框显示的内容
|
||||
* @param firstRow 开始行
|
||||
* @param endRow 结束行
|
||||
* @param firstCol 开始列
|
||||
* @param endCol 结束列
|
||||
* @return 设置好的sheet.
|
||||
*/
|
||||
public static HSSFSheet setHSSFValidation(HSSFSheet sheet, String[] textlist, int firstRow, int endRow,
|
||||
int firstCol, int endCol)
|
||||
{
|
||||
// 加载下拉列表内容
|
||||
DVConstraint constraint = DVConstraint.createExplicitListConstraint(textlist);
|
||||
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
|
||||
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
|
||||
// 数据有效性对象
|
||||
HSSFDataValidation dataValidationList = new HSSFDataValidation(regions, constraint);
|
||||
sheet.addValidationData(dataValidationList);
|
||||
return sheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码文件名
|
||||
*/
|
||||
public String encodingFilename(String filename)
|
||||
{
|
||||
filename = UUID.randomUUID().toString() + "_" + filename + ".xls";
|
||||
return filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取下载路径
|
||||
*
|
||||
* @param filename 文件名称
|
||||
*/
|
||||
public String getAbsoluteFile(String filename)
|
||||
{
|
||||
String downloadPath = Global.getDownloadPath() + filename;
|
||||
File desc = new File(downloadPath);
|
||||
if (!desc.getParentFile().exists())
|
||||
{
|
||||
desc.getParentFile().mkdirs();
|
||||
}
|
||||
return downloadPath;
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 获取IP方法
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class IpUtils
|
||||
{
|
||||
public static String getIpAddr(HttpServletRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getHeader("X-Forwarded-For");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getHeader("X-Real-IP");
|
||||
}
|
||||
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
|
||||
{
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
|
||||
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* Map通用处理方法
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class MapDataUtil
|
||||
{
|
||||
public static Map<String, Object> convertDataMap(HttpServletRequest request)
|
||||
{
|
||||
Map<String, String[]> properties = request.getParameterMap();
|
||||
Map<String, Object> returnMap = new HashMap<String, Object>();
|
||||
Iterator<?> entries = properties.entrySet().iterator();
|
||||
Map.Entry<?, ?> entry;
|
||||
String name = "";
|
||||
String value = "";
|
||||
while (entries.hasNext())
|
||||
{
|
||||
entry = (Entry<?, ?>) entries.next();
|
||||
name = (String) entry.getKey();
|
||||
Object valueObj = entry.getValue();
|
||||
if (null == valueObj)
|
||||
{
|
||||
value = "";
|
||||
}
|
||||
else if (valueObj instanceof String[])
|
||||
{
|
||||
String[] values = (String[]) valueObj;
|
||||
for (int i = 0; i < values.length; i++)
|
||||
{
|
||||
value = values[i] + ",";
|
||||
}
|
||||
value = value.substring(0, value.length() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = valueObj.toString();
|
||||
}
|
||||
returnMap.put(name, value);
|
||||
}
|
||||
return returnMap;
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Md5加密方法
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class Md5Utils
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(Md5Utils.class);
|
||||
|
||||
private static byte[] md5(String s)
|
||||
{
|
||||
MessageDigest algorithm;
|
||||
try
|
||||
{
|
||||
algorithm = MessageDigest.getInstance("MD5");
|
||||
algorithm.reset();
|
||||
algorithm.update(s.getBytes("UTF-8"));
|
||||
byte[] messageDigest = algorithm.digest();
|
||||
return messageDigest;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("MD5 Error...", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final String toHex(byte hash[])
|
||||
{
|
||||
if (hash == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
StringBuffer buf = new StringBuffer(hash.length * 2);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < hash.length; i++)
|
||||
{
|
||||
if ((hash[i] & 0xff) < 0x10)
|
||||
{
|
||||
buf.append("0");
|
||||
}
|
||||
buf.append(Long.toString(hash[i] & 0xff, 16));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String hash(String s)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("not supported charset...{}", e);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,357 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import com.ruoyi.common.support.StrFormatter;
|
||||
|
||||
/**
|
||||
* 字符串工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class StringUtils extends org.apache.commons.lang3.StringUtils
|
||||
{
|
||||
/** 空字符串 */
|
||||
private static final String NULLSTR = "";
|
||||
|
||||
/** 下划线 */
|
||||
private static final char SEPARATOR = '_';
|
||||
|
||||
/**
|
||||
* 获取参数不为空值
|
||||
*
|
||||
* @param value defaultValue 要判断的value
|
||||
* @return value 返回值
|
||||
*/
|
||||
public static <T> T nvl(T value, T defaultValue)
|
||||
{
|
||||
return value != null ? value : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个Collection是否为空, 包含List,Set,Queue
|
||||
*
|
||||
* @param coll 要判断的Collection
|
||||
* @return true:为空 false:非空
|
||||
*/
|
||||
public static boolean isEmpty(Collection<?> coll)
|
||||
{
|
||||
return isNull(coll) || coll.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个Collection是否非空,包含List,Set,Queue
|
||||
*
|
||||
* @param coll 要判断的Collection
|
||||
* @return true:非空 false:空
|
||||
*/
|
||||
public static boolean isNotEmpty(Collection<?> coll)
|
||||
{
|
||||
return !isEmpty(coll);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个对象数组是否为空
|
||||
*
|
||||
* @param objects 要判断的对象数组
|
||||
** @return true:为空 false:非空
|
||||
*/
|
||||
public static boolean isEmpty(Object[] objects)
|
||||
{
|
||||
return isNull(objects) || (objects.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个对象数组是否非空
|
||||
*
|
||||
* @param objects 要判断的对象数组
|
||||
* @return true:非空 false:空
|
||||
*/
|
||||
public static boolean isNotEmpty(Object[] objects)
|
||||
{
|
||||
return !isEmpty(objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个Map是否为空
|
||||
*
|
||||
* @param map 要判断的Map
|
||||
* @return true:为空 false:非空
|
||||
*/
|
||||
public static boolean isEmpty(Map<?, ?> map)
|
||||
{
|
||||
return isNull(map) || map.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个Map是否为空
|
||||
*
|
||||
* @param map 要判断的Map
|
||||
* @return true:非空 false:空
|
||||
*/
|
||||
public static boolean isNotEmpty(Map<?, ?> map)
|
||||
{
|
||||
return !isEmpty(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个字符串是否为空串
|
||||
*
|
||||
* @param str String
|
||||
* @return true:为空 false:非空
|
||||
*/
|
||||
public static boolean isEmpty(String str)
|
||||
{
|
||||
return isNull(str) || NULLSTR.equals(str.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个字符串是否为非空串
|
||||
*
|
||||
* @param str String
|
||||
* @return true:非空串 false:空串
|
||||
*/
|
||||
public static boolean isNotEmpty(String str)
|
||||
{
|
||||
return !isEmpty(str);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个对象是否为空
|
||||
*
|
||||
* @param object Object
|
||||
* @return true:为空 false:非空
|
||||
*/
|
||||
public static boolean isNull(Object object)
|
||||
{
|
||||
return object == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个对象是否非空
|
||||
*
|
||||
* @param object Object
|
||||
* @return true:非空 false:空
|
||||
*/
|
||||
public static boolean isNotNull(Object object)
|
||||
{
|
||||
return !isNull(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 判断一个对象是否是数组类型(Java基本型别的数组)
|
||||
*
|
||||
* @param object 对象
|
||||
* @return true:是数组 false:不是数组
|
||||
*/
|
||||
public static boolean isArray(Object object)
|
||||
{
|
||||
return isNotNull(object) && object.getClass().isArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 去空格
|
||||
*/
|
||||
public static String trim(String str)
|
||||
{
|
||||
return (str == null ? "" : str.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取字符串
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param start 开始
|
||||
* @return 结果
|
||||
*/
|
||||
public static String substring(final String str, int start)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return NULLSTR;
|
||||
}
|
||||
|
||||
if (start < 0)
|
||||
{
|
||||
start = str.length() + start;
|
||||
}
|
||||
|
||||
if (start < 0)
|
||||
{
|
||||
start = 0;
|
||||
}
|
||||
if (start > str.length())
|
||||
{
|
||||
return NULLSTR;
|
||||
}
|
||||
|
||||
return str.substring(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* 截取字符串
|
||||
*
|
||||
* @param str 字符串
|
||||
* @param start 开始
|
||||
* @param end 结束
|
||||
* @return 结果
|
||||
*/
|
||||
public static String substring(final String str, int start, int end)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return NULLSTR;
|
||||
}
|
||||
|
||||
if (end < 0)
|
||||
{
|
||||
end = str.length() + end;
|
||||
}
|
||||
if (start < 0)
|
||||
{
|
||||
start = str.length() + start;
|
||||
}
|
||||
|
||||
if (end > str.length())
|
||||
{
|
||||
end = str.length();
|
||||
}
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
return NULLSTR;
|
||||
}
|
||||
|
||||
if (start < 0)
|
||||
{
|
||||
start = 0;
|
||||
}
|
||||
if (end < 0)
|
||||
{
|
||||
end = 0;
|
||||
}
|
||||
|
||||
return str.substring(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文本, {} 表示占位符<br>
|
||||
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||
* 例:<br>
|
||||
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
|
||||
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {} 表示
|
||||
* @param params 参数值
|
||||
* @return 格式化后的文本
|
||||
*/
|
||||
public static String format(String template, Object... params)
|
||||
{
|
||||
if (isEmpty(params) || isEmpty(template))
|
||||
{
|
||||
return template;
|
||||
}
|
||||
return StrFormatter.format(template, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下划线转驼峰命名
|
||||
*/
|
||||
public static String toUnderScoreCase(String s)
|
||||
{
|
||||
if (s == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean upperCase = false;
|
||||
for (int i = 0; i < s.length(); i++)
|
||||
{
|
||||
char c = s.charAt(i);
|
||||
|
||||
boolean nextUpperCase = true;
|
||||
|
||||
if (i < (s.length() - 1))
|
||||
{
|
||||
nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
|
||||
}
|
||||
|
||||
if ((i > 0) && Character.isUpperCase(c))
|
||||
{
|
||||
if (!upperCase || !nextUpperCase)
|
||||
{
|
||||
sb.append(SEPARATOR);
|
||||
}
|
||||
upperCase = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
upperCase = false;
|
||||
}
|
||||
|
||||
sb.append(Character.toLowerCase(c));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否包含字符串
|
||||
*
|
||||
* @param str 验证字符串
|
||||
* @param strs 字符串组
|
||||
* @return 包含返回true
|
||||
*/
|
||||
public static boolean inStringIgnoreCase(String str, String... strs)
|
||||
{
|
||||
if (str != null && strs != null)
|
||||
{
|
||||
for (String s : strs)
|
||||
{
|
||||
if (str.equalsIgnoreCase(trim(s)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
|
||||
*
|
||||
* @param name 转换前的下划线大写方式命名的字符串
|
||||
* @return 转换后的驼峰式命名的字符串
|
||||
*/
|
||||
public static String convertToCamelCase(String name)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
// 快速检查
|
||||
if (name == null || name.isEmpty())
|
||||
{
|
||||
// 没必要转换
|
||||
return "";
|
||||
}
|
||||
else if (!name.contains("_"))
|
||||
{
|
||||
// 不含下划线,仅将首字母大写
|
||||
return name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
}
|
||||
// 用下划线将原始字符串分割
|
||||
String[] camels = name.split("_");
|
||||
for (String camel : camels)
|
||||
{
|
||||
// 跳过原始字符串中开头、结尾的下换线或双重下划线
|
||||
if (camel.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// 首字母大写
|
||||
result.append(camel.substring(0, 1).toUpperCase());
|
||||
result.append(camel.substring(1).toLowerCase());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 配置处理工具类
|
||||
*
|
||||
* @author yml
|
||||
*/
|
||||
public class YamlUtil
|
||||
{
|
||||
public static Map<?, ?> loadYaml(String fileName) throws FileNotFoundException
|
||||
{
|
||||
InputStream in = YamlUtil.class.getClassLoader().getResourceAsStream(fileName);
|
||||
return StringUtils.isNotEmpty(fileName) ? (LinkedHashMap<?, ?>) new Yaml().load(in) : null;
|
||||
}
|
||||
|
||||
public static void dumpYaml(String fileName, Map<?, ?> map) throws IOException
|
||||
{
|
||||
if (StringUtils.isNotEmpty(fileName))
|
||||
{
|
||||
FileWriter fileWriter = new FileWriter(YamlUtil.class.getResource(fileName).getFile());
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
Yaml yaml = new Yaml(options);
|
||||
yaml.dump(map, fileWriter);
|
||||
}
|
||||
}
|
||||
|
||||
public static Object getProperty(Map<?, ?> map, Object qualifiedKey)
|
||||
{
|
||||
if (map != null && !map.isEmpty() && qualifiedKey != null)
|
||||
{
|
||||
String input = String.valueOf(qualifiedKey);
|
||||
if (!input.equals(""))
|
||||
{
|
||||
if (input.contains("."))
|
||||
{
|
||||
int index = input.indexOf(".");
|
||||
String left = input.substring(0, index);
|
||||
String right = input.substring(index + 1, input.length());
|
||||
return getProperty((Map<?, ?>) map.get(left), right);
|
||||
}
|
||||
else if (map.containsKey(input))
|
||||
{
|
||||
return map.get(input);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void setProperty(Map<?, ?> map, Object qualifiedKey, Object value)
|
||||
{
|
||||
if (map != null && !map.isEmpty() && qualifiedKey != null)
|
||||
{
|
||||
String input = String.valueOf(qualifiedKey);
|
||||
if (!input.equals(""))
|
||||
{
|
||||
if (input.contains("."))
|
||||
{
|
||||
int index = input.indexOf(".");
|
||||
String left = input.substring(0, index);
|
||||
String right = input.substring(index + 1, input.length());
|
||||
setProperty((Map<?, ?>) map.get(left), right, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
((Map<Object, Object>) map).put(qualifiedKey, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
package com.ruoyi.common.utils.bean;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Bean 工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class BeanUtils
|
||||
{
|
||||
/** Bean方法名中属性名开始的下标 */
|
||||
private static final int BEAN_METHOD_PROP_INDEX = 3;
|
||||
|
||||
/** * 匹配getter方法的正则表达式 */
|
||||
private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
|
||||
|
||||
/** * 匹配setter方法的正则表达式 */
|
||||
private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
|
||||
|
||||
/**
|
||||
* Bean属性复制工具方法。
|
||||
*
|
||||
* @param dest 目标对象
|
||||
* @param src 源对象
|
||||
*/
|
||||
public static void copyBeanProp(Object dest, Object src)
|
||||
{
|
||||
List<Method> destSetters = getSetterMethods(dest);
|
||||
List<Method> srcGetters = getGetterMethods(src);
|
||||
try
|
||||
{
|
||||
for (Method setter : destSetters)
|
||||
{
|
||||
for (Method getter : srcGetters)
|
||||
{
|
||||
if (isMethodPropEquals(setter.getName(), getter.getName())
|
||||
&& setter.getParameterTypes()[0].equals(getter.getReturnType()))
|
||||
{
|
||||
setter.invoke(dest, getter.invoke(src));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象的setter方法。
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 对象的setter方法列表
|
||||
*/
|
||||
public static List<Method> getSetterMethods(Object obj)
|
||||
{
|
||||
// setter方法列表
|
||||
List<Method> setterMethods = new ArrayList<Method>();
|
||||
|
||||
// 获取所有方法
|
||||
Method[] methods = obj.getClass().getMethods();
|
||||
|
||||
// 查找setter方法
|
||||
|
||||
for (Method method : methods)
|
||||
{
|
||||
Matcher m = SET_PATTERN.matcher(method.getName());
|
||||
if (m.matches() && (method.getParameterTypes().length == 1))
|
||||
{
|
||||
setterMethods.add(method);
|
||||
}
|
||||
}
|
||||
// 返回setter方法列表
|
||||
return setterMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象的getter方法。
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return 对象的getter方法列表
|
||||
*/
|
||||
|
||||
public static List<Method> getGetterMethods(Object obj)
|
||||
{
|
||||
// getter方法列表
|
||||
List<Method> getterMethods = new ArrayList<Method>();
|
||||
// 获取所有方法
|
||||
Method[] methods = obj.getClass().getMethods();
|
||||
// 查找getter方法
|
||||
for (Method method : methods)
|
||||
{
|
||||
Matcher m = GET_PATTERN.matcher(method.getName());
|
||||
if (m.matches() && (method.getParameterTypes().length == 0))
|
||||
{
|
||||
getterMethods.add(method);
|
||||
}
|
||||
}
|
||||
// 返回getter方法列表
|
||||
return getterMethods;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查Bean方法名中的属性名是否相等。<br>
|
||||
* 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。
|
||||
*
|
||||
* @param m1 方法名1
|
||||
* @param m2 方法名2
|
||||
* @return 属性名一样返回true,否则返回false
|
||||
*/
|
||||
|
||||
public static boolean isMethodPropEquals(String m1, String m2)
|
||||
{
|
||||
return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.ruoyi.common.utils.file;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* 文件处理工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class FileUtils
|
||||
{
|
||||
/**
|
||||
* 输出指定文件的byte数组
|
||||
*
|
||||
* @param filename 文件
|
||||
* @return
|
||||
*/
|
||||
public static void writeBytes(String filePath, OutputStream os) throws IOException
|
||||
{
|
||||
FileInputStream fis = null;
|
||||
try
|
||||
{
|
||||
File file = new File(filePath);
|
||||
if (!file.exists())
|
||||
{
|
||||
throw new FileNotFoundException(filePath);
|
||||
}
|
||||
fis = new FileInputStream(file);
|
||||
byte[] b = new byte[1024];
|
||||
int length;
|
||||
while ((length = fis.read(b)) > 0)
|
||||
{
|
||||
os.write(b, 0, length);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (os != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
os.close();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (fis != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fis.close();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @param filePath 文件
|
||||
* @return
|
||||
*/
|
||||
public static boolean deleteFile(String filePath)
|
||||
{
|
||||
boolean flag = false;
|
||||
File file = new File(filePath);
|
||||
// 路径为文件且不为空则进行删除
|
||||
if (file.isFile() && file.exists())
|
||||
{
|
||||
file.delete();
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
}
|
@ -0,0 +1,248 @@
|
||||
package com.ruoyi.common.utils.http;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.cert.X509Certificate;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 通用http发送方法
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class HttpUtils
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送GET方法的请求
|
||||
*
|
||||
* @param url 发送请求的 URL
|
||||
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendGet(String url, String param)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
BufferedReader in = null;
|
||||
try
|
||||
{
|
||||
String urlNameString = url + "?" + param;
|
||||
log.info("sendGet - {}", urlNameString);
|
||||
URL realUrl = new URL(urlNameString);
|
||||
URLConnection connection = realUrl.openConnection();
|
||||
connection.setRequestProperty("accept", "*/*");
|
||||
connection.setRequestProperty("connection", "Keep-Alive");
|
||||
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
connection.connect();
|
||||
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null)
|
||||
{
|
||||
result.append(line);
|
||||
}
|
||||
log.info("recv - {}", result);
|
||||
}
|
||||
catch (ConnectException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (SocketTimeoutException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (in != null)
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送POST方法的请求
|
||||
*
|
||||
* @param url 发送请求的 URL
|
||||
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendPost(String url, String param)
|
||||
{
|
||||
PrintWriter out = null;
|
||||
BufferedReader in = null;
|
||||
StringBuilder result = new StringBuilder();
|
||||
try
|
||||
{
|
||||
String urlNameString = url + "?" + param;
|
||||
log.info("sendPost - {}", urlNameString);
|
||||
URL realUrl = new URL(urlNameString);
|
||||
URLConnection conn = realUrl.openConnection();
|
||||
conn.setRequestProperty("accept", "*/*");
|
||||
conn.setRequestProperty("connection", "Keep-Alive");
|
||||
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||
conn.setRequestProperty("contentType", "utf-8");
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
out = new PrintWriter(conn.getOutputStream());
|
||||
out.print(param);
|
||||
out.flush();
|
||||
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null)
|
||||
{
|
||||
result.append(line);
|
||||
}
|
||||
log.info("recv - {}", result);
|
||||
}
|
||||
catch (ConnectException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (SocketTimeoutException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (out != null)
|
||||
{
|
||||
out.close();
|
||||
}
|
||||
if (in != null)
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String sendSSLPost(String url, String param)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
String urlNameString = url + "?" + param;
|
||||
try
|
||||
{
|
||||
log.info("sendSSLPost - {}", urlNameString);
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
|
||||
URL console = new URL(urlNameString);
|
||||
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
|
||||
conn.setRequestProperty("accept", "*/*");
|
||||
conn.setRequestProperty("connection", "Keep-Alive");
|
||||
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
|
||||
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||
conn.setRequestProperty("contentType", "utf-8");
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
|
||||
conn.setSSLSocketFactory(sc.getSocketFactory());
|
||||
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
|
||||
conn.connect();
|
||||
InputStream is = conn.getInputStream();
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
String ret = "";
|
||||
while ((ret = br.readLine()) != null)
|
||||
{
|
||||
if (ret != null && !ret.trim().equals(""))
|
||||
{
|
||||
result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
|
||||
}
|
||||
}
|
||||
log.info("recv - {}", result);
|
||||
conn.disconnect();
|
||||
br.close();
|
||||
}
|
||||
catch (ConnectException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (SocketTimeoutException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static class TrustAnyTrustManager implements X509TrustManager
|
||||
{
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers()
|
||||
{
|
||||
return new X509Certificate[] {};
|
||||
}
|
||||
}
|
||||
|
||||
private static class TrustAnyHostnameVerifier implements HostnameVerifier
|
||||
{
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package com.ruoyi.common.xss;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 防止XSS攻击的过滤器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class XssFilter implements Filter
|
||||
{
|
||||
/**
|
||||
* 排除链接
|
||||
*/
|
||||
public List<String> excludes = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* xss过滤开关
|
||||
*/
|
||||
public boolean enabled = false;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
String tempExcludes = filterConfig.getInitParameter("excludes");
|
||||
String tempEnabled = filterConfig.getInitParameter("enabled");
|
||||
if (StringUtils.isNotEmpty(tempExcludes))
|
||||
{
|
||||
String[] url = tempExcludes.split(",");
|
||||
for (int i = 0; url != null && i < url.length; i++)
|
||||
{
|
||||
excludes.add(url[i]);
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotEmpty(tempEnabled))
|
||||
{
|
||||
enabled = Boolean.valueOf(tempEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException
|
||||
{
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
if (handleExcludeURL(req, resp))
|
||||
{
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
|
||||
chain.doFilter(xssRequest, response);
|
||||
}
|
||||
|
||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response)
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (excludes == null || excludes.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
String url = request.getServletPath();
|
||||
for (String pattern : excludes)
|
||||
{
|
||||
Pattern p = Pattern.compile("^" + pattern);
|
||||
Matcher m = p.matcher(url);
|
||||
if (m.find())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.ruoyi.common.xss;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.safety.Whitelist;
|
||||
|
||||
/**
|
||||
* XSS过滤处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
|
||||
{
|
||||
/**
|
||||
* @param request
|
||||
*/
|
||||
public XssHttpServletRequestWrapper(HttpServletRequest request)
|
||||
{
|
||||
super(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name)
|
||||
{
|
||||
String[] values = super.getParameterValues(name);
|
||||
if (values != null)
|
||||
{
|
||||
int length = values.length;
|
||||
String[] escapseValues = new String[length];
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
// 防xss攻击和过滤前后空格
|
||||
escapseValues[i] = Jsoup.clean(values[i], Whitelist.relaxed()).trim();
|
||||
}
|
||||
return escapseValues;
|
||||
}
|
||||
return super.getParameterValues(name);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user