ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
@@ -54,10 +54,10 @@ response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); FileUtils.setAttachmentResponseHeader(response, realFileName); FileUtils.writeBytes(filePath, response.getOutputStream()); FileUtils.writeToStream(filePath, response.getOutputStream()); if (delete) { FileUtils.deleteFile(filePath); FileUtils.del(filePath); } } catch (Exception e) @@ -111,7 +111,7 @@ String downloadName = StrUtil.subAfter(downloadPath, "/",true); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); FileUtils.setAttachmentResponseHeader(response, downloadName); FileUtils.writeBytes(downloadPath, response.getOutputStream()); FileUtils.writeToStream(downloadPath, response.getOutputStream()); } catch (Exception e) { ruoyi-common/src/main/java/com/ruoyi/common/filter/RepeatedlyRequestWrapper.java
@@ -1,75 +1,77 @@ package com.ruoyi.common.filter; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import com.ruoyi.common.utils.http.HttpHelper; /** * æå»ºå¯éå¤è¯»åinputStreamçrequest * * @author ruoyi */ public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException { super(request); request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); body = HttpHelper.getBodyString(request).getBytes("UTF-8"); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public int available() throws IOException { return body.length; } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } }; } } package com.ruoyi.common.filter; import cn.hutool.core.io.IoUtil; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; /** * æå»ºå¯éå¤è¯»åinputStreamçrequest * * @author ruoyi */ public class RepeatedlyRequestWrapper extends HttpServletRequestWrapper { private final byte[] body; public RepeatedlyRequestWrapper(HttpServletRequest request, ServletResponse response) throws IOException { super(request); request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); body = IoUtil.readUtf8(request.getInputStream()).getBytes(StandardCharsets.UTF_8); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } @Override public int available() throws IOException { return body.length; } @Override public boolean isFinished() { return false; } @Override public boolean isReady() { return false; } @Override public void setReadListener(ReadListener readListener) { } }; } } ruoyi-common/src/main/java/com/ruoyi/common/filter/XssHttpServletRequestWrapper.java
@@ -1,9 +1,9 @@ package com.ruoyi.common.filter; import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Validator; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HtmlUtil; import org.apache.commons.io.IOUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; @@ -13,6 +13,7 @@ import javax.servlet.http.HttpServletRequestWrapper; import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; /** * XSSè¿æ»¤å¤ç @@ -57,7 +58,7 @@ } // 为空ï¼ç´æ¥è¿å String json = IOUtils.toString(super.getInputStream(), "utf-8"); String json = IoUtil.read(super.getInputStream(), StandardCharsets.UTF_8); if (Validator.isEmpty(json)) { return super.getInputStream(); @@ -65,7 +66,8 @@ // xssè¿æ»¤ json = HtmlUtil.cleanHtmlTag(json).trim(); final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8")); final ByteArrayInputStream bis = IoUtil.toStream(json, StandardCharsets.UTF_8); return new ServletInputStream() { @Override ruoyi-common/src/main/java/com/ruoyi/common/utils/ServletUtils.java
@@ -2,6 +2,9 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @@ -10,129 +13,118 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.nio.charset.StandardCharsets; /** * 客æ·ç«¯å·¥å ·ç±» * * * @author ruoyi */ public class ServletUtils { /** * è·åStringåæ° */ public static String getParameter(String name) { return getRequest().getParameter(name); } public class ServletUtils extends ServletUtil { /** * è·åStringåæ° */ public static String getParameter(String name) { return getRequest().getParameter(name); } /** * è·åStringåæ° */ public static String getParameter(String name, String defaultValue) { return Convert.toStr(getRequest().getParameter(name), defaultValue); } /** * è·åStringåæ° */ public static String getParameter(String name, String defaultValue) { return Convert.toStr(getRequest().getParameter(name), defaultValue); } /** * è·åIntegeråæ° */ public static Integer getParameterToInt(String name) { return Convert.toInt(getRequest().getParameter(name)); } /** * è·åIntegeråæ° */ public static Integer getParameterToInt(String name) { return Convert.toInt(getRequest().getParameter(name)); } /** * è·åIntegeråæ° */ public static Integer getParameterToInt(String name, Integer defaultValue) { return Convert.toInt(getRequest().getParameter(name), defaultValue); } /** * è·åIntegeråæ° */ public static Integer getParameterToInt(String name, Integer defaultValue) { return Convert.toInt(getRequest().getParameter(name), defaultValue); } /** * è·årequest */ public static HttpServletRequest getRequest() { return getRequestAttributes().getRequest(); } /** * è·årequest */ public static HttpServletRequest getRequest() { return getRequestAttributes().getRequest(); } /** * è·åresponse */ public static HttpServletResponse getResponse() { return getRequestAttributes().getResponse(); } /** * è·åresponse */ public static HttpServletResponse getResponse() { return getRequestAttributes().getResponse(); } /** * è·åsession */ public static HttpSession getSession() { return getRequest().getSession(); } /** * è·åsession */ public static HttpSession getSession() { return getRequest().getSession(); } public static ServletRequestAttributes getRequestAttributes() { RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); return (ServletRequestAttributes) attributes; } public static ServletRequestAttributes getRequestAttributes() { RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); return (ServletRequestAttributes) attributes; } /** * å°å符串渲æå°å®¢æ·ç«¯ * * @param response 渲æå¯¹è±¡ * @param string å¾ æ¸²æçå符串 * @return null */ public static String renderString(HttpServletResponse response, String string) { try { response.setStatus(200); response.setContentType("application/json"); response.setCharacterEncoding("utf-8"); response.getWriter().print(string); } catch (IOException e) { e.printStackTrace(); } return null; } /** * å°å符串渲æå°å®¢æ·ç«¯ * * @param response 渲æå¯¹è±¡ * @param string å¾ æ¸²æçå符串 * @return null */ public static String renderString(HttpServletResponse response, String string) { try { response.setStatus(HttpStatus.HTTP_OK); response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setCharacterEncoding(StandardCharsets.UTF_8.toString()); response.getWriter().print(string); } catch (IOException e) { e.printStackTrace(); } return null; } /** * æ¯å¦æ¯Ajax弿¥è¯·æ± * * @param request */ public static boolean isAjaxRequest(HttpServletRequest request) { String accept = request.getHeader("accept"); if (accept != null && accept.indexOf("application/json") != -1) { return true; } /** * æ¯å¦æ¯Ajax弿¥è¯·æ± * * @param request */ public static boolean isAjaxRequest(HttpServletRequest request) { String xRequestedWith = request.getHeader("X-Requested-With"); if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) { return true; } String accept = request.getHeader("accept"); if (accept != null && accept.indexOf("application/json") != -1) { return true; } String uri = request.getRequestURI(); if (StrUtil.equalsAnyIgnoreCase(uri, ".json", ".xml")) { return true; } String xRequestedWith = request.getHeader("X-Requested-With"); if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) { return true; } String ajax = request.getParameter("__ajax"); if (StrUtil.equalsAnyIgnoreCase(ajax, "json", "xml")) { return true; } return false; } String uri = request.getRequestURI(); if (StrUtil.equalsAnyIgnoreCase(uri, ".json", ".xml")) { return true; } String ajax = request.getParameter("__ajax"); if (StrUtil.equalsAnyIgnoreCase(ajax, "json", "xml")) { return true; } return false; } public static String getClientIP() { return getClientIP(getRequest()); } } ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
@@ -1,5 +1,6 @@ package com.ruoyi.common.utils.file; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.StrUtil; @@ -11,91 +12,16 @@ /** * æä»¶å¤çå·¥å ·ç±» * * * @author ruoyi */ public class FileUtils extends org.apache.commons.io.FileUtils public class FileUtils extends FileUtil { public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; /** * è¾åºæå®æä»¶çbyteæ°ç» * * @param filePath æä»¶è·¯å¾ * @param os è¾åºæµ * @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; } /** * æä»¶åç§°éªè¯ * * * @param filename æä»¶åç§° * @return true æ£å¸¸ false éæ³ */ @@ -130,7 +56,7 @@ /** * ä¸è½½æä»¶åéæ°ç¼ç * * * @param request 请æ±å¯¹è±¡ * @param fileName æä»¶å * @return ç¼ç åçæä»¶å @@ -142,7 +68,7 @@ if (agent.contains("MSIE")) { // IEæµè§å¨ filename = URLEncoder.encode(filename, "utf-8"); filename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()); filename = filename.replace("+", " "); } else if (agent.contains("Firefox")) @@ -153,12 +79,12 @@ else if (agent.contains("Chrome")) { // googleæµè§å¨ filename = URLEncoder.encode(filename, "utf-8"); filename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()); } else { // å ¶å®æµè§å¨ filename = URLEncoder.encode(filename, "utf-8"); filename = URLEncoder.encode(filename, StandardCharsets.UTF_8.toString()); } return filename; } ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpHelper.java
ÎļþÒÑɾ³ý ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java
ÎļþÒÑɾ³ý ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/AddressUtils.java
@@ -1,56 +1,51 @@ package com.ruoyi.common.utils.ip; import cn.hutool.core.net.NetUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.utils.http.HttpUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import lombok.extern.slf4j.Slf4j; /** * è·åå°åç±» * * * @author ruoyi */ public class AddressUtils { private static final Logger log = LoggerFactory.getLogger(AddressUtils.class); @Slf4j public class AddressUtils { // IPå°åæ¥è¯¢ public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; // IPå°åæ¥è¯¢ public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp"; // æªç¥å°å public static final String UNKNOWN = "XX XX"; // æªç¥å°å public static final String UNKNOWN = "XX XX"; public static String getRealAddressByIP(String ip) { String address = UNKNOWN; // å ç½ä¸æ¥è¯¢ if (IpUtils.internalIp(ip)) { return "å ç½IP"; } if (RuoYiConfig.isAddressEnabled()) { try { String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", Constants.GBK); if (StrUtil.isEmpty(rspStr)) { log.error("è·åå°çä½ç½®å¼å¸¸ {}", ip); return UNKNOWN; } JSONObject obj = JSONObject.parseObject(rspStr); String region = obj.getString("pro"); String city = obj.getString("city"); return String.format("%s %s", region, city); } catch (Exception e) { log.error("è·åå°çä½ç½®å¼å¸¸ {}", ip); } } return address; } public static String getRealAddressByIP(String ip) { String address = UNKNOWN; // å ç½ä¸æ¥è¯¢ if (NetUtil.isInnerIP(ip)) { return "å ç½IP"; } if (RuoYiConfig.isAddressEnabled()) { try { String rspStr = HttpUtil.createGet(IP_URL) .body("ip=" + ip + "&json=true", Constants.GBK) .execute() .body(); if (StrUtil.isEmpty(rspStr)) { log.error("è·åå°çä½ç½®å¼å¸¸ {}", ip); return UNKNOWN; } JSONObject obj = JSONObject.parseObject(rspStr); String region = obj.getString("pro"); String city = obj.getString("city"); return String.format("%s %s", region, city); } catch (Exception e) { log.error("è·åå°çä½ç½®å¼å¸¸ {}", ip); } } return address; } } ruoyi-common/src/main/java/com/ruoyi/common/utils/ip/IpUtils.java
ÎļþÒÑɾ³ý ruoyi-common/src/main/java/com/ruoyi/common/utils/reflect/ReflectUtils.java
@@ -1,406 +1,53 @@ package com.ruoyi.common.utils.reflect; import cn.hutool.core.convert.Convert; import com.ruoyi.common.utils.DateUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.poi.ss.usermodel.DateUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.*; import java.util.Date; /** * åå°å·¥å ·ç±». æä¾è°ç¨getter/setteræ¹æ³, 访é®ç§æåé, è°ç¨ç§ææ¹æ³, è·åæ³åç±»åClass, 被AOPè¿ççå®ç±»çå·¥å ·å½æ°. * * @author ruoyi */ @SuppressWarnings("rawtypes") public class ReflectUtils { private static final String SETTER_PREFIX = "set"; private static final String GETTER_PREFIX = "get"; private static final String CGLIB_CLASS_SEPARATOR = "$$"; private static Logger logger = LoggerFactory.getLogger(ReflectUtils.class); /** * è°ç¨Getteræ¹æ³. * æ¯æå¤çº§ï¼å¦ï¼å¯¹è±¡å.对象å.æ¹æ³ */ @SuppressWarnings("unchecked") public static <E> E invokeGetter(Object obj, String propertyName) { Object object = obj; for (String name : StringUtils.split(propertyName, ".")) { String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); } return (E) object; } /** * è°ç¨Setteræ¹æ³, ä» å¹é æ¹æ³åã * æ¯æå¤çº§ï¼å¦ï¼å¯¹è±¡å.对象å.æ¹æ³ */ public static <E> void invokeSetter(Object obj, String propertyName, E value) { Object object = obj; String[] names = StringUtils.split(propertyName, "."); for (int i = 0; i < names.length; i++) { if (i < names.length - 1) { String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]); object = invokeMethod(object, getterMethodName, new Class[] {}, new Object[] {}); } else { String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]); invokeMethodByName(object, setterMethodName, new Object[] { value }); } } } /** * ç´æ¥è¯»åå¯¹è±¡å±æ§å¼, æ è§private/protected修饰符, ä¸ç»è¿getter彿°. */ @SuppressWarnings("unchecked") public static <E> E getFieldValue(final Object obj, final String fieldName) { Field field = getAccessibleField(obj, fieldName); if (field == null) { logger.debug("å¨ [" + obj.getClass() + "] ä¸ï¼æ²¡ææ¾å° [" + fieldName + "] åæ®µ "); return null; } E result = null; try { result = (E) field.get(obj); } catch (IllegalAccessException e) { logger.error("ä¸å¯è½æåºçå¼å¸¸{}", e.getMessage()); } return result; } /** * ç´æ¥è®¾ç½®å¯¹è±¡å±æ§å¼, æ è§private/protected修饰符, ä¸ç»è¿setter彿°. */ public static <E> void setFieldValue(final Object obj, final String fieldName, final E value) { Field field = getAccessibleField(obj, fieldName); if (field == null) { // throw new IllegalArgumentException("å¨ [" + obj.getClass() + "] ä¸ï¼æ²¡ææ¾å° [" + fieldName + "] åæ®µ "); logger.debug("å¨ [" + obj.getClass() + "] ä¸ï¼æ²¡ææ¾å° [" + fieldName + "] åæ®µ "); return; } try { field.set(obj, value); } catch (IllegalAccessException e) { logger.error("ä¸å¯è½æåºçå¼å¸¸: {}", e.getMessage()); } } /** * ç´æ¥è°ç¨å¯¹è±¡æ¹æ³, æ è§private/protected修饰符. * ç¨äºä¸æ¬¡æ§è°ç¨çæ åµï¼å¦ååºä½¿ç¨getAccessibleMethod()彿°è·å¾Methodååå¤è°ç¨. * åæ¶å¹é æ¹æ³å+åæ°ç±»åï¼ */ @SuppressWarnings("unchecked") public static <E> E invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes, final Object[] args) { if (obj == null || methodName == null) { return null; } Method method = getAccessibleMethod(obj, methodName, parameterTypes); if (method == null) { logger.debug("å¨ [" + obj.getClass() + "] ä¸ï¼æ²¡ææ¾å° [" + methodName + "] æ¹æ³ "); return null; } try { return (E) method.invoke(obj, args); } catch (Exception e) { String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; throw convertReflectionExceptionToUnchecked(msg, e); } } /** * ç´æ¥è°ç¨å¯¹è±¡æ¹æ³, æ è§private/protectedä¿®é¥°ç¬¦ï¼ * ç¨äºä¸æ¬¡æ§è°ç¨çæ åµï¼å¦ååºä½¿ç¨getAccessibleMethodByName()彿°è·å¾Methodååå¤è°ç¨. * åªå¹é 彿°åï¼å¦ææå¤ä¸ªåå彿°è°ç¨ç¬¬ä¸ä¸ªã */ @SuppressWarnings("unchecked") public static <E> E invokeMethodByName(final Object obj, final String methodName, final Object[] args) { Method method = getAccessibleMethodByName(obj, methodName, args.length); if (method == null) { // å¦æä¸ºç©ºä¸æ¥éï¼ç´æ¥è¿å空ã logger.debug("å¨ [" + obj.getClass() + "] ä¸ï¼æ²¡ææ¾å° [" + methodName + "] æ¹æ³ "); return null; } try { // ç±»å转æ¢ï¼å°åæ°æ°æ®ç±»å转æ¢ä¸ºç®æ æ¹æ³åæ°ç±»åï¼ Class<?>[] cs = method.getParameterTypes(); for (int i = 0; i < cs.length; i++) { if (args[i] != null && !args[i].getClass().equals(cs[i])) { if (cs[i] == String.class) { args[i] = Convert.toStr(args[i]); if (StringUtils.endsWith((String) args[i], ".0")) { args[i] = StringUtils.substringBefore((String) args[i], ".0"); } } else if (cs[i] == Integer.class) { args[i] = Convert.toInt(args[i]); } else if (cs[i] == Long.class) { args[i] = Convert.toLong(args[i]); } else if (cs[i] == Double.class) { args[i] = Convert.toDouble(args[i]); } else if (cs[i] == Float.class) { args[i] = Convert.toFloat(args[i]); } else if (cs[i] == Date.class) { if (args[i] instanceof String) { args[i] = DateUtils.parseDate(args[i]); } else { args[i] = DateUtil.getJavaDate((Double) args[i]); } } else if (cs[i] == boolean.class || cs[i] == Boolean.class) { args[i] = Convert.toBool(args[i]); } } } return (E) method.invoke(obj, args); } catch (Exception e) { String msg = "method: " + method + ", obj: " + obj + ", args: " + args + ""; throw convertReflectionExceptionToUnchecked(msg, e); } } /** * 循ç¯åä¸è½¬å, è·å对象çDeclaredField, 并强å¶è®¾ç½®ä¸ºå¯è®¿é®. * å¦åä¸è½¬åå°Object仿 æ³æ¾å°, è¿ånull. */ public static Field getAccessibleField(final Object obj, final String fieldName) { // ä¸ºç©ºä¸æ¥éãç´æ¥è¿å null if (obj == null) { return null; } Validate.notBlank(fieldName, "fieldName can't be blank"); for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) { try { Field field = superClass.getDeclaredField(fieldName); makeAccessible(field); return field; } catch (NoSuchFieldException e) { continue; } } return null; } /** * 循ç¯åä¸è½¬å, è·å对象çDeclaredMethod,并强å¶è®¾ç½®ä¸ºå¯è®¿é®. * å¦åä¸è½¬åå°Object仿 æ³æ¾å°, è¿ånull. * å¹é 彿°å+åæ°ç±»åã * ç¨äºæ¹æ³éè¦è¢«å¤æ¬¡è°ç¨çæ åµ. å ä½¿ç¨æ¬å½æ°å åå¾Method,ç¶åè°ç¨Method.invoke(Object obj, Object... args) */ public static Method getAccessibleMethod(final Object obj, final String methodName, final Class<?>... parameterTypes) { // ä¸ºç©ºä¸æ¥éãç´æ¥è¿å null if (obj == null) { return null; } Validate.notBlank(methodName, "methodName can't be blank"); for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { try { Method method = searchType.getDeclaredMethod(methodName, parameterTypes); makeAccessible(method); return method; } catch (NoSuchMethodException e) { continue; } } return null; } /** * 循ç¯åä¸è½¬å, è·å对象çDeclaredMethod,并强å¶è®¾ç½®ä¸ºå¯è®¿é®. * å¦åä¸è½¬åå°Object仿 æ³æ¾å°, è¿ånull. * åªå¹é 彿°åã * ç¨äºæ¹æ³éè¦è¢«å¤æ¬¡è°ç¨çæ åµ. å ä½¿ç¨æ¬å½æ°å åå¾Method,ç¶åè°ç¨Method.invoke(Object obj, Object... args) */ public static Method getAccessibleMethodByName(final Object obj, final String methodName, int argsNum) { // ä¸ºç©ºä¸æ¥éãç´æ¥è¿å null if (obj == null) { return null; } Validate.notBlank(methodName, "methodName can't be blank"); for (Class<?> searchType = obj.getClass(); searchType != Object.class; searchType = searchType.getSuperclass()) { Method[] methods = searchType.getDeclaredMethods(); for (Method method : methods) { if (method.getName().equals(methodName) && method.getParameterTypes().length == argsNum) { makeAccessible(method); return method; } } } return null; } /** * æ¹åprivate/protectedçæ¹æ³ä¸ºpublicï¼å°½éä¸è°ç¨å®é æ¹å¨çè¯å¥ï¼é¿å JDKçSecurityManageræ±æ¨ã */ public static void makeAccessible(Method method) { if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) { method.setAccessible(true); } } /** * æ¹åprivate/protectedçæååé为publicï¼å°½éä¸è°ç¨å®é æ¹å¨çè¯å¥ï¼é¿å JDKçSecurityManageræ±æ¨ã */ public static void makeAccessible(Field field) { if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) { field.setAccessible(true); } } /** * éè¿åå°, è·å¾Classå®ä¹ä¸å£°æçæ³ååæ°çç±»å, æ³¨ææ³åå¿ é¡»å®ä¹å¨ç¶ç±»å¤ * 妿 æ³æ¾å°, è¿åObject.class. */ @SuppressWarnings("unchecked") public static <T> Class<T> getClassGenricType(final Class clazz) { return getClassGenricType(clazz, 0); } /** * éè¿åå°, è·å¾Classå®ä¹ä¸å£°æçç¶ç±»çæ³ååæ°çç±»å. * 妿 æ³æ¾å°, è¿åObject.class. */ public static Class getClassGenricType(final Class clazz, final int index) { Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) { logger.debug(clazz.getSimpleName() + "'s superclass not ParameterizedType"); return Object.class; } Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) { logger.debug("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length); return Object.class; } if (!(params[index] instanceof Class)) { logger.debug(clazz.getSimpleName() + " not set the actual class on superclass generic parameter"); return Object.class; } return (Class) params[index]; } public static Class<?> getUserClass(Object instance) { if (instance == null) { throw new RuntimeException("Instance must not be null"); } Class clazz = instance.getClass(); if (clazz != null && clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) { Class<?> superClass = clazz.getSuperclass(); if (superClass != null && !Object.class.equals(superClass)) { return superClass; } } return clazz; } /** * å°åå°æ¶çchecked exception转æ¢ä¸ºunchecked exception. */ public static RuntimeException convertReflectionExceptionToUnchecked(String msg, Exception e) { if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException || e instanceof NoSuchMethodException) { return new IllegalArgumentException(msg, e); } else if (e instanceof InvocationTargetException) { return new RuntimeException(msg, ((InvocationTargetException) e).getTargetException()); } return new RuntimeException(msg, e); } } package com.ruoyi.common.utils.reflect; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import java.lang.reflect.Method; /** * åå°å·¥å ·ç±». æä¾è°ç¨getter/setteræ¹æ³, 访é®ç§æåé, è°ç¨ç§ææ¹æ³, è·åæ³åç±»åClass, 被AOPè¿ççå®ç±»çå·¥å ·å½æ°. * * @author Lion Li */ @SuppressWarnings("rawtypes") public class ReflectUtils extends ReflectUtil { private static final String SETTER_PREFIX = "set"; private static final String GETTER_PREFIX = "get"; /** * è°ç¨Getteræ¹æ³. * æ¯æå¤çº§ï¼å¦ï¼å¯¹è±¡å.对象å.æ¹æ³ */ @SuppressWarnings("unchecked") public static <E> E invokeGetter(Object obj, String propertyName) { Object object = obj; for (String name : StrUtil.split(propertyName, ".")) { String getterMethodName = GETTER_PREFIX + StrUtil.upperFirst(name); object = invoke(object, getterMethodName); } return (E) object; } /** * è°ç¨Setteræ¹æ³, ä» å¹é æ¹æ³åã * æ¯æå¤çº§ï¼å¦ï¼å¯¹è±¡å.对象å.æ¹æ³ */ public static <E> void invokeSetter(Object obj, String propertyName, E value) { Object object = obj; String[] names = StrUtil.split(propertyName, "."); for (int i = 0; i < names.length; i++) { if (i < names.length - 1) { String getterMethodName = GETTER_PREFIX + StrUtil.upperFirst(names[i]); object = invoke(object, getterMethodName); } else { String setterMethodName = SETTER_PREFIX + StrUtil.upperFirst(names[i]); Method method = getMethodByName(object.getClass(), setterMethodName); invoke(object, method, value); } } } } ruoyi-framework/src/main/java/com/ruoyi/framework/interceptor/impl/SameUrlDataInterceptor.java
@@ -1,126 +1,133 @@ package com.ruoyi.framework.interceptor.impl; import cn.hutool.core.lang.Validator; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.filter.RepeatedlyRequestWrapper; import com.ruoyi.common.utils.http.HttpHelper; import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * å¤æè¯·æ±urlåæ°æ®æ¯å¦åä¸ä¸æ¬¡ç¸åï¼ * 妿å䏿¬¡ç¸åï¼åæ¯éå¤æäº¤è¡¨åã æææ¶é´ä¸º10ç§å ã * * @author ruoyi */ @Component public class SameUrlDataInterceptor extends RepeatSubmitInterceptor { public final String REPEAT_PARAMS = "repeatParams"; public final String REPEAT_TIME = "repeatTime"; // 令çèªå®ä¹æ è¯ @Value("${token.header}") private String header; @Autowired private RedisCache redisCache; /** * é´éæ¶é´ï¼åä½:ç§ é»è®¤10ç§ * * 两次ç¸ååæ°ç请æ±ï¼å¦æé´éæ¶é´å¤§äºè¯¥åæ°ï¼ç³»ç»ä¸ä¼è®¤å®ä¸ºéå¤æäº¤çæ°æ® */ private int intervalTime = 10; public void setIntervalTime(int intervalTime) { this.intervalTime = intervalTime; } @SuppressWarnings("unchecked") @Override public boolean isRepeatSubmit(HttpServletRequest request) { String nowParams = ""; if (request instanceof RepeatedlyRequestWrapper) { RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; nowParams = HttpHelper.getBodyString(repeatedlyRequest); } // bodyåæ°ä¸ºç©ºï¼è·åParameterçæ°æ® if (Validator.isEmpty(nowParams)) { nowParams = JSONObject.toJSONString(request.getParameterMap()); } Map<String, Object> nowDataMap = new HashMap<String, Object>(); nowDataMap.put(REPEAT_PARAMS, nowParams); nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); // 请æ±å°åï¼ä½ä¸ºåæ¾cacheçkeyå¼ï¼ String url = request.getRequestURI(); // å¯ä¸å¼ï¼æ²¡ææ¶æ¯å¤´å使ç¨è¯·æ±å°åï¼ String submitKey = request.getHeader(header); if (Validator.isEmpty(submitKey)) { submitKey = url; } // å¯ä¸æ è¯ï¼æå®key + æ¶æ¯å¤´ï¼ String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey; Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); if (sessionObj != null) { Map<String, Object> sessionMap = (Map<String, Object>) sessionObj; if (sessionMap.containsKey(url)) { Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url); if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap)) { return true; } } } Map<String, Object> cacheMap = new HashMap<String, Object>(); cacheMap.put(url, nowDataMap); redisCache.setCacheObject(cacheRepeatKey, cacheMap, intervalTime, TimeUnit.SECONDS); return false; } /** * 夿忰æ¯å¦ç¸å */ private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap) { String nowParams = (String) nowMap.get(REPEAT_PARAMS); String preParams = (String) preMap.get(REPEAT_PARAMS); return nowParams.equals(preParams); } /** * å¤æä¸¤æ¬¡é´éæ¶é´ */ private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap) { long time1 = (Long) nowMap.get(REPEAT_TIME); long time2 = (Long) preMap.get(REPEAT_TIME); if ((time1 - time2) < (this.intervalTime * 1000)) { return true; } return false; } } package com.ruoyi.framework.interceptor.impl; import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Validator; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.filter.RepeatedlyRequestWrapper; import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; /** * å¤æè¯·æ±urlåæ°æ®æ¯å¦åä¸ä¸æ¬¡ç¸åï¼ * 妿å䏿¬¡ç¸åï¼åæ¯éå¤æäº¤è¡¨åã æææ¶é´ä¸º10ç§å ã * * @author ruoyi */ @Slf4j @Component public class SameUrlDataInterceptor extends RepeatSubmitInterceptor { public final String REPEAT_PARAMS = "repeatParams"; public final String REPEAT_TIME = "repeatTime"; // 令çèªå®ä¹æ è¯ @Value("${token.header}") private String header; @Autowired private RedisCache redisCache; /** * é´éæ¶é´ï¼åä½:ç§ é»è®¤10ç§ * * 两次ç¸ååæ°ç请æ±ï¼å¦æé´éæ¶é´å¤§äºè¯¥åæ°ï¼ç³»ç»ä¸ä¼è®¤å®ä¸ºéå¤æäº¤çæ°æ® */ private int intervalTime = 10; public void setIntervalTime(int intervalTime) { this.intervalTime = intervalTime; } @SuppressWarnings("unchecked") @Override public boolean isRepeatSubmit(HttpServletRequest request) { String nowParams = ""; if (request instanceof RepeatedlyRequestWrapper) { RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; try { nowParams = IoUtil.readUtf8(repeatedlyRequest.getInputStream()); } catch (IOException e) { log.warn("è¯»åæµåºç°é®é¢ï¼"); } } // bodyåæ°ä¸ºç©ºï¼è·åParameterçæ°æ® if (Validator.isEmpty(nowParams)) { nowParams = JSONObject.toJSONString(request.getParameterMap()); } Map<String, Object> nowDataMap = new HashMap<String, Object>(); nowDataMap.put(REPEAT_PARAMS, nowParams); nowDataMap.put(REPEAT_TIME, System.currentTimeMillis()); // 请æ±å°åï¼ä½ä¸ºåæ¾cacheçkeyå¼ï¼ String url = request.getRequestURI(); // å¯ä¸å¼ï¼æ²¡ææ¶æ¯å¤´å使ç¨è¯·æ±å°åï¼ String submitKey = request.getHeader(header); if (Validator.isEmpty(submitKey)) { submitKey = url; } // å¯ä¸æ è¯ï¼æå®key + æ¶æ¯å¤´ï¼ String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey; Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); if (sessionObj != null) { Map<String, Object> sessionMap = (Map<String, Object>) sessionObj; if (sessionMap.containsKey(url)) { Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url); if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap)) { return true; } } } Map<String, Object> cacheMap = new HashMap<String, Object>(); cacheMap.put(url, nowDataMap); redisCache.setCacheObject(cacheRepeatKey, cacheMap, intervalTime, TimeUnit.SECONDS); return false; } /** * 夿忰æ¯å¦ç¸å */ private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap) { String nowParams = (String) nowMap.get(REPEAT_PARAMS); String preParams = (String) preMap.get(REPEAT_PARAMS); return nowParams.equals(preParams); } /** * å¤æä¸¤æ¬¡é´éæ¶é´ */ private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap) { long time1 = (Long) nowMap.get(REPEAT_TIME); long time2 = (Long) preMap.get(REPEAT_TIME); if ((time1 - time2) < (this.intervalTime * 1000)) { return true; } return false; } } ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java
@@ -9,7 +9,6 @@ import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ip.AddressUtils; import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.framework.config.properties.TokenProperties; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; @@ -131,7 +130,7 @@ */ public void setUserAgent(LoginUser loginUser) { UserAgent userAgent = UserAgentUtil.parse(ServletUtils.getRequest().getHeader("User-Agent")); String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); String ip = ServletUtils.getClientIP(); loginUser.setIpaddr(ip); loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); loginUser.setBrowser(userAgent.getBrowser().getName()); ruoyi-generator/src/main/java/com/ruoyi/generator/service/GenTableServiceImpl.java
@@ -263,12 +263,8 @@ StringWriter sw = new StringWriter(); Template tpl = Velocity.getTemplate(template, Constants.UTF8); tpl.merge(context, sw); try { String path = getGenPath(table, template); FileUtils.writeStringToFile(new File(path), sw.toString(), Constants.UTF8); } catch (IOException e) { throw new CustomException("æ¸²ææ¨¡æ¿å¤±è´¥ï¼è¡¨åï¼" + table.getTableName()); } String path = getGenPath(table, template); FileUtils.writeUtf8String(sw.toString(), path); } } }