From 2a36f4ae7e4897c33e0541111aee12554a8ce317 Mon Sep 17 00:00:00 2001 From: pugwoo Date: Mon, 9 Oct 2023 18:42:04 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8DIOUtils.readAll(InputStre?= =?UTF-8?q?am,=20String)=E6=96=B9=E6=B3=95=E8=AF=BB=E5=8F=96=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=97=B6=EF=BC=8C=E6=9C=80=E5=90=8E=E4=B8=80=E8=A1=8C?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=9B=9E=E8=BD=A6=E7=AC=A6=E5=8D=B4=E5=8A=A0?= =?UTF-8?q?=E4=B8=8A=E5=9B=9E=E8=BD=A6=E7=AC=A6=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG | 2 ++ .../java/com/pugwoo/wooutils/io/IOUtils.java | 23 ++++++------------- .../com/pugwoo/wooutils/io/TestIOUtils.java | 6 ++++- src/test/resources/sql/my-no-new-line.sql | 2 ++ 4 files changed, 16 insertions(+), 17 deletions(-) create mode 100644 src/test/resources/sql/my-no-new-line.sql diff --git a/CHANGELOG b/CHANGELOG index 553bc86..4bfbd55 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +v1.2.2 - [fix] 修复IOUtils.readAll(InputStream, String)方法读取文件时,最后一行没有回车符却加上回车符的问题 + 2023年9月28日 v1.2.1 - [add] 新增DateUtils.diffDays(LocalDate,LocalDate)方法 - [fix] 修复IOUtils.readAll(InputStream, String)方法读取文件时,trim掉最后一个回车符的问题 diff --git a/src/main/java/com/pugwoo/wooutils/io/IOUtils.java b/src/main/java/com/pugwoo/wooutils/io/IOUtils.java index 0e87f4a..ba8dc9b 100644 --- a/src/main/java/com/pugwoo/wooutils/io/IOUtils.java +++ b/src/main/java/com/pugwoo/wooutils/io/IOUtils.java @@ -81,26 +81,17 @@ public static byte[] readAllAndClose(InputStream in) throws IOException { * @return */ public static String readAll(InputStream in, String charset) { - BufferedReader reader = null; try { - InputStreamReader inputStreamReader = new InputStreamReader(in, charset); - reader = new BufferedReader(inputStreamReader); - StringBuilder stringBuilder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - stringBuilder.append("\n"); + StringBuilder textBuilder = new StringBuilder(); + try (Reader reader = new BufferedReader(new InputStreamReader(in, charset))) { + int c; + while ((c = reader.read()) != -1) { + textBuilder.append((char) c); + } } - return stringBuilder.toString(); + return textBuilder.toString(); } catch (IOException e) { throw new RuntimeException(e); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException ignored) { - } - } } } diff --git a/src/test/java/com/pugwoo/wooutils/io/TestIOUtils.java b/src/test/java/com/pugwoo/wooutils/io/TestIOUtils.java index 7f32d77..6973709 100644 --- a/src/test/java/com/pugwoo/wooutils/io/TestIOUtils.java +++ b/src/test/java/com/pugwoo/wooutils/io/TestIOUtils.java @@ -25,7 +25,11 @@ public void testListFiles() throws IOException { public void testGetClasspathFile() throws IOException { String content = IOUtils.readClasspathResourceAsString("sql/my.sql"); assert StringTools.isNotBlank(content); - assert content.equals("select *\nfrom dual\n"); + assert content.equals("select *\r\nfrom dual\r\n"); + + content = IOUtils.readClasspathResourceAsString("sql/my-no-new-line.sql"); + assert StringTools.isNotBlank(content); + assert content.equals("select *\r\nfrom dual"); } } diff --git a/src/test/resources/sql/my-no-new-line.sql b/src/test/resources/sql/my-no-new-line.sql new file mode 100644 index 0000000..c1b2081 --- /dev/null +++ b/src/test/resources/sql/my-no-new-line.sql @@ -0,0 +1,2 @@ +select * +from dual \ No newline at end of file From 9b3a4b27915b41cae0b1b9c36a3636e45c14eaee Mon Sep 17 00:00:00 2001 From: pugwoo Date: Mon, 23 Oct 2023 20:56:10 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0jakarta.servlet-api?= =?UTF-8?q?=EF=BC=8C=E5=90=8C=E6=97=B6=E6=94=AF=E6=8C=81jakarta.servlet-ap?= =?UTF-8?q?i=E5=92=8Cjavax.servlet-api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG | 1 + README.md | 12 -- pom.xml | 6 + .../java/com/pugwoo/wooutils/net/Browser.java | 12 ++ .../com/pugwoo/wooutils/net/CookieUtils.java | 124 +++++++++++++++++- .../com/pugwoo/wooutils/net/NetUtils.java | 115 +++++++++++++++- 6 files changed, 249 insertions(+), 21 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 4bfbd55..ac2aaf5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ v1.2.2 - [fix] 修复IOUtils.readAll(InputStream, String)方法读取文件时,最后一行没有回车符却加上回车符的问题 + - [enhance] 增加jakarta.servlet-api,同时支持jakarta.servlet-api和javax.servlet-api 2023年9月28日 v1.2.1 - [add] 新增DateUtils.diffDays(LocalDate,LocalDate)方法 diff --git a/README.md b/README.md index a4461d0..c1ddb9c 100644 --- a/README.md +++ b/README.md @@ -20,15 +20,3 @@ ``` -### 2. 需要使用者根据实际使用的功能自行导入的jar包: - -servlet一般由运行容器提供,实际项目中也不用特别提供,所以使用provided方式引入: - -```xml - - javax.servlet - javax.servlet-api - 4.0.1 - provided - -``` diff --git a/pom.xml b/pom.xml index 82b8c2e..619e41d 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,12 @@ 4.0.1 provided + + jakarta.servlet + jakarta.servlet-api + 6.0.0 + provided + org.junit.jupiter diff --git a/src/main/java/com/pugwoo/wooutils/net/Browser.java b/src/main/java/com/pugwoo/wooutils/net/Browser.java index 386b09e..efcced3 100644 --- a/src/main/java/com/pugwoo/wooutils/net/Browser.java +++ b/src/main/java/com/pugwoo/wooutils/net/Browser.java @@ -194,6 +194,18 @@ public void addRequestHeader(HttpServletRequest request) { } } + /**设置请求时的头部,该设置是Browser实例全局的。
+ * 设置HttpServletRequest的所有头部信息 + * @param request HttpServletRequest + */ + public void addRequestHeader(jakarta.servlet.http.HttpServletRequest request) { + Enumeration headerNames = request.getHeaderNames(); + while(headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + addRequestHeader(headerName, request.getHeader(headerName)); + } + } + /** * 自行添加cookie * @param domain 域名,例如abc.com diff --git a/src/main/java/com/pugwoo/wooutils/net/CookieUtils.java b/src/main/java/com/pugwoo/wooutils/net/CookieUtils.java index f6cb389..f4e223d 100644 --- a/src/main/java/com/pugwoo/wooutils/net/CookieUtils.java +++ b/src/main/java/com/pugwoo/wooutils/net/CookieUtils.java @@ -1,18 +1,17 @@ package com.pugwoo.wooutils.net; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * cookie相关功能,cookie默认都用URLEncode编码和解码。 * 1. 支持指定domain,所有path都设置为根目录,不支持子path的cookie,也不建议这样用,因为path很不稳定。 @@ -49,6 +48,32 @@ public static String getCookieValue(HttpServletRequest request, String name) { } return null; } + + /** + * 根据name读取cookie的值 + * @param request + * @param name + * @return + */ + public static String getCookieValue(jakarta.servlet.http.HttpServletRequest request, String name) { + if(name == null) { + return null; + } + jakarta.servlet.http.Cookie[] cookies = request.getCookies(); + if (null != cookies) { + for (jakarta.servlet.http.Cookie cookie : cookies) { + if(name.equals(cookie.getName())) { + try { + return URLDecoder.decode(cookie.getValue(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + LOGGER.error("URLEncoder.decode fail, value:{}", cookie.getValue(), e); + return cookie.getValue(); + } + } + } + } + return null; + } /** * 根据name读取cookie的值,支持多个相同cookie name的情况 @@ -76,6 +101,33 @@ public static List getCookieValues(HttpServletRequest request, String na } return cookieList; } + + /** + * 根据name读取cookie的值,支持多个相同cookie name的情况 + * @param request + * @param name + * @return + */ + public static List getCookieValues(jakarta.servlet.http.HttpServletRequest request, String name) { + if(name == null) { + return null; + } + List cookieList = new ArrayList(); + jakarta.servlet.http.Cookie[] cookies = request.getCookies(); + if (null != cookies) { + for (jakarta.servlet.http.Cookie cookie : cookies) { + if(name.equals(cookie.getName())) { + try { + cookieList.add(URLDecoder.decode(cookie.getValue(), "UTF-8")); + } catch (UnsupportedEncodingException e) { + LOGGER.error("URLEncoder.decode fail, value:{}", cookie.getValue(), e); + cookieList.add(cookie.getValue()); + } + } + } + } + return cookieList; + } /** * 增加cookie,如果name相同的话,浏览器会把cookie值追加要已有的之上 @@ -105,6 +157,35 @@ public static void addCookie(HttpServletResponse response, String name, String v } response.addCookie(cookie); } + + /** + * 增加cookie,如果name相同的话,浏览器会把cookie值追加要已有的之上 + * + * @param response + * @param name cookie名字 + * @param value cookie值,不建议为null值 + * @param domain 指定域名,null表示不指定 + * @param expireSeconds cookie生命周期 以秒为单位,当设置为0时,cookie默认有效期10年;如果删除,请用removeCookie方法 + */ + public static void addCookie(jakarta.servlet.http.HttpServletResponse response, String name, String value, + String domain, int expireSeconds) { + try { + value = value == null ? null : URLEncoder.encode(value, "UTF-8"); + } catch (UnsupportedEncodingException e) { + LOGGER.error("URLEncoder.encode fail, value:{}", value, e); + } + jakarta.servlet.http.Cookie cookie = new jakarta.servlet.http.Cookie(name, value); + cookie.setPath("/"); + if(domain != null) { + cookie.setDomain(domain); + } + if (expireSeconds == 0) { + cookie.setMaxAge(10 * 365 * 24 * 3600); + } else { + cookie.setMaxAge(expireSeconds); + } + response.addCookie(cookie); + } /** * 增加cookie,如果name相同的话,浏览器会把cookie值追加要已有的之上。有效期100年。 @@ -119,6 +200,19 @@ public static void addCookie(HttpServletResponse response, String name, String v addCookie(response, name, value, domain, 0); } + /** + * 增加cookie,如果name相同的话,浏览器会把cookie值追加要已有的之上。有效期100年。 + * + * @param response + * @param name + * @param value + * @param domain + */ + public static void addCookie(jakarta.servlet.http.HttpServletResponse response, String name, String value, + String domain) { + addCookie(response, name, value, domain, 0); + } + /** * 删除cookie * @param response @@ -134,5 +228,21 @@ public static void removeCookie(HttpServletResponse response, String name, Strin cookie.setMaxAge(0); // delete response.addCookie(cookie); } + + /** + * 删除cookie + * @param response + * @param name + * @param domain 当为null时表示不指定 + */ + public static void removeCookie(jakarta.servlet.http.HttpServletResponse response, String name, String domain) { + jakarta.servlet.http.Cookie cookie = new jakarta.servlet.http.Cookie(name, ""); + cookie.setPath("/"); + if(domain != null) { + cookie.setDomain(domain); + } + cookie.setMaxAge(0); // delete + response.addCookie(cookie); + } } diff --git a/src/main/java/com/pugwoo/wooutils/net/NetUtils.java b/src/main/java/com/pugwoo/wooutils/net/NetUtils.java index 0a23e37..687ae6c 100644 --- a/src/main/java/com/pugwoo/wooutils/net/NetUtils.java +++ b/src/main/java/com/pugwoo/wooutils/net/NetUtils.java @@ -57,7 +57,32 @@ public static String getRemoteIp(HttpServletRequest request) { return ip; } - + + /** + * 获得客户端的ip地址,请配合nginx配置使用 + * @return 可能返回多个ip,以逗号分隔 + */ + public static String getRemoteIp(jakarta.servlet.http.HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if(StringTools.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if(StringTools.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if(StringTools.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if(StringTools.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if(StringTools.isBlank(ip) || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + + return ip; + } + /** * 判断是否在微信浏览器访问 * @param request @@ -70,6 +95,19 @@ public static boolean isWeixinBrowser(HttpServletRequest request) { } return false; } + + /** + * 判断是否在微信浏览器访问 + * @param request + * @return + */ + public static boolean isWeixinBrowser(jakarta.servlet.http.HttpServletRequest request) { + String userAgent = request.getHeader("user-agent"); + if(userAgent != null && userAgent.toLowerCase().contains("micromessenger")) { + return true; + } + return false; + } /** * 判断是否是移动端浏览器 @@ -83,6 +121,19 @@ public static boolean isMobileBrowser(HttpServletRequest request) { } return false; } + + /** + * 判断是否是移动端浏览器 + * @param request + * @return + */ + public static boolean isMobileBrowser(jakarta.servlet.http.HttpServletRequest request) { + String userAgent = request.getHeader("user-agent"); + if(userAgent != null && userAgent.contains("Mobile")) { + return true; + } + return false; + } /** * 获得访问的url的域名部分 @@ -95,7 +146,19 @@ public static String getHttpRootURL(HttpServletRequest request) { || "https".equalsIgnoreCase(request.getScheme()) && request.getServerPort() == 443 ? "" : ":" + request.getServerPort()); } - + + /** + * 获得访问的url的域名部分 + * @param request + * @return 例如http://www.abc.com,不带根/ + */ + public static String getHttpRootURL(jakarta.servlet.http.HttpServletRequest request) { + return request.getScheme() + "://" + request.getServerName() + + ("http".equalsIgnoreCase(request.getScheme()) && request.getServerPort() == 80 + || "https".equalsIgnoreCase(request.getScheme()) && request.getServerPort() == 443 ? "" + : ":" + request.getServerPort()); + } + /** * 获得当前域名,不带端口,例如www.abc.com * @param request @@ -104,6 +167,15 @@ public static String getHttpRootURL(HttpServletRequest request) { public static String getHostname(HttpServletRequest request) { return request.getServerName(); } + + /** + * 获得当前域名,不带端口,例如www.abc.com + * @param request + * @return + */ + public static String getHostname(jakarta.servlet.http.HttpServletRequest request) { + return request.getServerName(); + } /** * 获得当前域名和端口,如果是http协议,返回www.abc.com:80,如果是https协议,返回www.abc.com:443 @@ -114,6 +186,16 @@ public static String getHostname(HttpServletRequest request) { public static String getHostnameWithPort(HttpServletRequest request) { return request.getServerName() + ":" + request.getServerPort(); } + + /** + * 获得当前域名和端口,如果是http协议,返回www.abc.com:80,如果是https协议,返回www.abc.com:443 + * 其它端口正常带上,例如www.abc.com:8080 + * @param request + * @return + */ + public static String getHostnameWithPort(jakarta.servlet.http.HttpServletRequest request) { + return request.getServerName() + ":" + request.getServerPort(); + } /** * 获得当前请求的完整地址 @@ -126,6 +208,18 @@ public static String getFullUrlWithParam(HttpServletRequest request) { String queryString = request.getQueryString(); return domain + path + (queryString == null ? "" : "?" + queryString); } + + /** + * 获得当前请求的完整地址 + * @param request + * @return + */ + public static String getFullUrlWithParam(jakarta.servlet.http.HttpServletRequest request) { + String domain = getHttpRootURL(request); + String path = request.getRequestURI(); + String queryString = request.getQueryString(); + return domain + path + (queryString == null ? "" : "?" + queryString); + } /** * 获得url的路径,例如访问url是http://www.abc.com/is/a/apple?id=3,则返回/is/a/apple @@ -135,6 +229,15 @@ public static String getFullUrlWithParam(HttpServletRequest request) { public static String getUrlPath(HttpServletRequest request) { return request.getRequestURI(); } + + /** + * 获得url的路径,例如访问url是http://www.abc.com/is/a/apple?id=3,则返回/is/a/apple + * @param request + * @return + */ + public static String getUrlPath(jakarta.servlet.http.HttpServletRequest request) { + return request.getRequestURI(); + } /** * 获得url的路径,例如输入:http://www.abc.com/is/a/apple?id=3,返回/is/a/apple @@ -198,4 +301,12 @@ public static String getContextPath(HttpServletRequest request) { return request.getContextPath(); } + /** + * 获得servlet应用的contextPath,即tomcat部署的应用名称的根目录,如admin.war部署之后返回 /admin + * @param request + * @return + */ + public static String getContextPath(jakarta.servlet.http.HttpServletRequest request) { + return request.getContextPath(); + } } From b2e15e1dbba92ee969cc10dcd1d2ef850e3061f5 Mon Sep 17 00:00:00 2001 From: pugwoo Date: Mon, 23 Oct 2023 20:57:26 +0800 Subject: [PATCH 3/3] release 1.2.2 --- CHANGELOG | 1 + README.md | 2 +- pom.xml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ac2aaf5..8639736 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +2023年10月23日 v1.2.2 - [fix] 修复IOUtils.readAll(InputStream, String)方法读取文件时,最后一行没有回车符却加上回车符的问题 - [enhance] 增加jakarta.servlet-api,同时支持jakarta.servlet-api和javax.servlet-api diff --git a/README.md b/README.md index c1ddb9c..7792410 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ com.pugwoo woo-utils - 1.2.1 + 1.2.2 ``` diff --git a/pom.xml b/pom.xml index 619e41d..f56a7ca 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.pugwoo woo-utils jar - 1.2.1 + 1.2.2 woo-utils the common utils