ruoyi后台管理系统分析(一)
ruoyi后台管理系统框架:
接下来我们,边看代码边分析代码:
一、common包
----constant包
constant.java
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"; }
PermissionConstants.java
1 package com.ruoyi.common.constant; 2 3 /** 4 * 权限通用常量 5 * 6 * @author ruoyi 7 */ 8 public class PermissionConstants 9 { 10 /** 新增权限 */ 11 public static final String ADD_PERMISSION = "add"; 12 13 /** 修改权限 */ 14 public static final String EDIT_PERMISSION = "edit"; 15 16 /** 删除权限 */ 17 public static final String REMOVE_PERMISSION = "remove"; 18 19 /** 导出权限 */ 20 public static final String EXPORT_PERMISSION = "export"; 21 22 /** 显示权限 */ 23 public static final String VIEW_PERMISSION = "view"; 24 25 /** 查询权限 */ 26 public static final String LIST_PERMISSION = "list"; 27 }
ScheduleConstants.java
1 package com.ruoyi.common.constant; 2 3 /** 4 * 任务调度通用常量 5 * 6 * @author ruoyi 7 */ 8 public interface ScheduleConstants 9 { 10 public static final String TASK_CLASS_NAME = "__TASK_CLASS_NAME__"; 11 12 public static final String TASK_PROPERTIES = "__TASK_PROPERTIES__"; 13 14 /** 默认 */ 15 public static final String MISFIRE_DEFAULT = "0"; 16 17 /** 立即触发执行 */ 18 public static final String MISFIRE_IGNORE_MISFIRES = "1"; 19 20 /** 触发一次执行 */ 21 public static final String MISFIRE_FIRE_AND_PROCEED = "2"; 22 23 /** 不触发立即执行 */ 24 public static final String MISFIRE_DO_NOTHING = "3"; 25 26 public enum Status 27 { 28 /** 29 * 正常 30 */ 31 NORMAL("0"), 32 /** 33 * 暂停 34 */ 35 PAUSE("1"); 36 37 private String value; 38 39 private Status(String value) 40 { 41 this.value = value; 42 } 43 44 public String getValue() 45 { 46 return value; 47 } 48 } 49 }
ShiroConstants.java
1 package com.ruoyi.common.constant; 2 3 /** 4 * Shiro通用常量 5 * 6 * @author ruoyi 7 */ 8 public interface ShiroConstants 9 { 10 /** 11 * 当前登录的用户 12 */ 13 public static final String CURRENT_USER = "currentUser"; 14 15 /** 16 * 用户名 17 */ 18 public static final String CURRENT_USERNAME = "username"; 19 20 /** 21 * 消息key 22 */ 23 public static String MESSAGE = "message"; 24 25 /** 26 * 错误key 27 */ 28 public static String ERROR = "errorMsg"; 29 30 /** 31 * 编码格式 32 */ 33 public static String ENCODING = "UTF-8"; 34 35 /** 36 * 当前在线会话 37 */ 38 public String ONLINE_SESSION = "online_session"; 39 40 /** 41 * 验证码key 42 */ 43 public static final String CURRENT_CAPTCHA = "captcha"; 44 45 /** 46 * 验证码开关 47 */ 48 public static final String CURRENT_ENABLED = "captchaEnabled"; 49 50 /** 51 * 验证码开关 52 */ 53 public static final String CURRENT_TYPE = "captchaType"; 54 55 /** 56 * 验证码 57 */ 58 public static final String CURRENT_VALIDATECODE = "validateCode"; 59 60 /** 61 * 验证码错误 62 */ 63 public static final String CAPTCHA_ERROR = "captchaError"; 64 }
UserConstants.java
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])))\\.?"; }
--exception包
-----file包----文件异常处理类
FileNameLengthLimitExceededException.java和
InvalidExtensionException.java
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; } }
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); } } }
------job包----计划策略异常类
1 package com.ruoyi.common.exception.job; 2 3 /** 4 * 计划策略异常 5 * 6 * @author ruoyi 7 */ 8 public class TaskException extends Exception 9 { 10 private static final long serialVersionUID = 1L; 11 12 private Code code; 13 14 public TaskException(String msg, Code code) 15 { 16 this(msg, code, null); 17 } 18 19 public TaskException(String msg, Code code, Exception nestedEx) 20 { 21 super(msg, nestedEx); 22 this.code = code; 23 } 24 25 public Code getCode() 26 { 27 return code; 28 } 29 30 public enum Code 31 { 32 TASK_EXISTS, NO_TASK_EXISTS, TASK_ALREADY_STARTED, UNKNOWN, CONFIG_ERROR, TASK_NODE_NOT_AVAILABLE 33 } 34 }
DemoModeException.java
package com.ruoyi.common.exception; /** * 演示模式异常 * * @author ruoyi */ public class DemoModeException extends RuntimeException { private static final long serialVersionUID = 1L; public DemoModeException() { } }
RRException.java
package com.ruoyi.common.exception; /** * 自定义异常 * */ public class RRException extends RuntimeException { private static final long serialVersionUID = 1L; private String msg; private int code = 500; public RRException(String msg) { super(msg); this.msg = msg; } public RRException(String msg, Throwable e) { super(msg, e); this.msg = msg; } public RRException(String msg, int code) { super(msg); this.msg = msg; this.code = code; } public RRException(String msg, int code, Throwable e) { super(msg, e); this.msg = msg; this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } }
------support包
CharsetKit.java
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(); } }
Convert.java
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("^整$", "零元整"); } }
StrFormatter.java
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(); } }
-utils包
------bean包
BeanUtils.java
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)); } }
-------file包
FileUtils.java
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; } }
HttpUtils.java
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; } } }
--------------------------------
AddressUtils.java
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"; String localIp = "127.0.0.1"; if (localIp.equals(ip)){ address = "XX 内网IP"; return address; } 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; } }
DateUtils.java
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"); } }
ExcelUtil.java
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; } }
IpUtils.java
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; } }
MapDataUtil.java
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; } }
Md5Utils.java
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; } } }
R.java
package com.ruoyi.common.utils; import java.util.HashMap; import java.util.Map; /** * 返回数据 * */ public class R extends HashMap<String, Object> { private static final long serialVersionUID = 1L; public R() { put("code", 0); put("msg", "success"); } public static R error() { return error(500, "未知异常,请联系管理员"); } public static R error(String msg) { return error(500, msg); } public static R error(int code, String msg) { R r = new R(); r.put("code", code); r.put("msg", msg); return r; } public static R ok(String msg) { R r = new R(); r.put("msg", msg); return r; } public static R ok(Map<String, Object> map) { R r = new R(); r.putAll(map); return r; } public static R ok() { return new R(); } @Override public R put(String key, Object value) { super.put(key, value); return this; } }
StringUtils.java
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(); } }
YamlUtil.java
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); } } } } }
-------xss包
XssFilter.java
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() { } }
XssHttpServletRequestWrapper.java
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); } }
文章来自:https://www.cnblogs.com/zhzJAVA11/p/9994362.html