1、通用结构返回类Result
package com.xuecheng.base.model;
import lombok.Data;
import lombok.ToString;
/**
* @description 通用结果类型
* @author Mr.M
* @date 2022/9/13 14:44
* @version 1.0
*/
@Data
@ToStringpublic class RestResponse<T> {
/**
* 响应编码,0为正常,-1错误
*/
private int code;
/**
* 响应提示信息
*/
private String msg;
/**
* 响应内容
*/
private T result;
public RestResponse() {
this(0, "success");
}
public RestResponse(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 错误信息的封装
*
* @param msg
* @param <T>
* @return
*/
public static <T> RestResponse<T> validfail(String msg) {
RestResponse<T> response = new RestResponse<T>();
response.setCode(-1);
response.setMsg(msg);
return response;
}
public static <T> RestResponse<T> validfail(T result,String msg) {
RestResponse<T> response = new RestResponse<T>();
response.setCode(-1);
response.setResult(result);
response.setMsg(msg);
return response;
}
/**
* 添加正常响应数据(包含响应内容)
*
* @return RestResponse Rest服务封装相应数据
*/
public static <T> RestResponse<T> success(T result) {
RestResponse<T> response = new RestResponse<T>();
response.setResult(result);
return response;
}
public static <T> RestResponse<T> success(T result,String msg) {
RestResponse<T> response = new RestResponse<T>();
response.setResult(result);
response.setMsg(msg);
return response;
}
/**
* 添加正常响应数据(不包含响应内容)
*
* @return RestResponse Rest服务封装相应数据
*/
public static <T> RestResponse<T> success() {
return new RestResponse<T>();
}
public Boolean isSuccessful() {
return this.code == 0;
}
}
2、分页通用参数PageParams
package com.xuecheng.base.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.ToString;
import lombok.extern.java.Log;
/**
* 分页查询通用参数
*/
@Data
@ToString
public class PageParams {
//当前页码
@ApiModelProperty("页码")
private Long pageNo = 1L;
//每页记录数默认值
@ApiModelProperty("每页记录数")
private Long pageSize =10L;
public PageParams(){
}
public PageParams(long pageNo,long pageSize){
this.pageNo = pageNo;
this.pageSize = pageSize;
}
}
3、分页查询结果PageResult
package com.xuecheng.base.model;
import lombok.Data;
import lombok.ToString;
import java.io.Serializable;
import java.util.List;
/**
* @description 分页查询结果模型类
* @author Mr.M
* @date 2022/9/6 14:15
* @version 1.0
*/@Data
@ToString
public class PageResult<T> implements Serializable {
// 数据列表
private List<T> items;
//总记录数
private long counts;
//当前页码
private long page;
//每页记录数
private long pageSize;
public PageResult(List<T> items, long counts, long page, long pageSize) {
this.items = items;
this.counts = counts;
this.page = page;
this.pageSize = pageSize;
}
}
4、通用工具类
-
hiddenMobile(String mobile)
: 该方法用于隐藏手机号码中的中间四位数字,只显示前三位和后四位。如果传入的手机号码为空或无效,将返回空字符串。 -
strToBigDecimal(String s, Boolean isFen)
: 该方法将字符串转换为BigDecimal
对象。如果字符串不是数字,或者isFen
参数为true
,则将字符串表示的金额(以分为单位)转换为以元为单位的BigDecimal
对象。 -
shiFenMiaoToSeconds(String shifenmiao)
: 该方法将表示小时、分钟和秒的字符串转换为秒数。它支持多种格式,如 “HH:mm:ss” 或 “mm:ss”,并能够正确地计算出总秒数。 -
mapUnderscoreToCamelCase(String str)
: 该方法将下划线命名法的字符串转换为骆驼命名法。例如,“user_name” 将被转换为 “userName”。 -
mapCamelCaseToUnderscore(String str)
: 该方法将骆驼命名法的字符串转换为下划线命名法。例如,“userName” 将被转换为 “USER_NAME”。 -
main(String[] args)
: 这是类的主要方法,用于测试其他方法。它演示了如何计算两个Instant
对象之间的时间差,以及如何使用LocalDateTime
和Duration
来计算两个日期之间的秒数。
package com.xuecheng.base.utils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <P>
* 通用工具类
* </p>
*
*/public class CommonUtil {
public static String hiddenMobile(String mobile) {
if (StringUtils.isBlank(mobile)) {
return "";
}
return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2");
}
/**
* @param s
* @param isFen
* @return
*/
public static BigDecimal strToBigDecimal(String s, Boolean isFen) {
if (StringUtils.isBlank(s)) {
return null;
}
if (!NumberUtils.isNumber(s)) {
return null;
}
BigDecimal bd = new BigDecimal(s);
if (isFen != null && isFen.booleanValue()){
bd = bd.divide(new BigDecimal(100), 2);
}
return bd;
}
public static final Pattern shiFenMiaoPattern = Pattern.compile("(\\d{1,2}[::]){0,2}\\d{1,2}");
public static Long shiFenMiaoToSeconds (String shifenmiao) {
if (StringUtils.isBlank(shifenmiao)) {
return 0L;
}
Long totalSeconds = 0L;
shifenmiao = shifenmiao.replaceAll(" ", "");
boolean matched = shiFenMiaoPattern.matcher(shifenmiao).matches();
if (matched) {
List<String> sfmList = new ArrayList<>();
StringTokenizer st = new StringTokenizer(shifenmiao,"::");
while (st.hasMoreTokens()) {
sfmList.add(st.nextToken());
}
Collections.reverse(sfmList);
String[] sfmArr = sfmList.toArray(new String[0]);
for (int i = 0; i < sfmArr.length; i++) {
if (i == 0) {
totalSeconds += Long.valueOf(sfmArr[i]);
} else if (i == 1) {
totalSeconds += Long.valueOf(sfmArr[i]) * 60;
} else if (i == 2) {
totalSeconds += Long.valueOf(sfmArr[i]) * 3600;
}
}
}
return totalSeconds;
}
/**
* 将下划线映射到骆驼命名使用的正则表达式, 预编译正则用于提高效率
*/
private static Pattern patternForUTC = Pattern.compile("_([a-z]){1}");
/**
* 将下划线映射到骆驼命名
*
* @param str
* @return
*/
public static String mapUnderscoreToCamelCase(String str) {
// 先转成全小写
str = str.toLowerCase();
final Matcher matcher = patternForUTC.matcher(str);
while (matcher.find()) {
str = str.replaceAll(matcher.group(), matcher.group(1).toUpperCase());
}
return str;
}
/**
* 将骆驼命名映射到下划线, 必须是标准的驼峰命名, 否则会出现奇怪的结果
*
* @param str
* @return
*/
public static String mapCamelCaseToUnderscore(String str) {
return str.replaceAll("([A-Z]){1}","_$1").toUpperCase();
}
public static void main(String[] args) {
Instant start = Instant.parse("2017-10-03T10:15:30.00Z");
Instant end = Instant.parse("2018-10-04T10:16:30.00Z");
LocalDateTime time1 = LocalDateTime.of(2019,8,8,8,8);
LocalDateTime time2 = LocalDateTime.of(2019,9,9,8,8);
Duration duration = Duration.between(time1, time2);
System.out.println(duration.getSeconds());
System.out.println(duration.isNegative());
System.out.println(time1.until(time2, ChronoUnit.SECONDS));
}
}
5、获取ip
package com.xuecheng.base.utils;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
public class IPUtil {
// 定义一些常量
private static final String UNKNOWN = "unknown";
private static final String LOCALHOST_IPV4 = "127.0.0.1";
private static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:1";
private static final List<String> IP_HEADERS = Arrays.asList(
"x-forwarded-for",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_CLIENT_IP",
"HTTP_X_FORWARDED_FOR",
"X-Real-IP"
);
// IP地址格式验证正则表达式
private static final Pattern IP_PATTERN = Pattern.compile(
"^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$"
);
public static String getIpAddr(HttpServletRequest request) {
String ip = IP_HEADERS.stream()
.map(request::getHeader)
.filter(header -> header != null && !header.isEmpty() && !UNKNOWN.equalsIgnoreCase(header))
.findFirst()
.orElseGet(request::getRemoteAddr);
if (IP_PATTERN.matcher(ip).matches() || isLocalhost(ip)) {
return ip;
}
try {
InetAddress inet = InetAddress.getLocalHost();
ip = inet.getHostAddress();
if (IP_PATTERN.matcher(ip).matches()) {
return ip;
}
} catch (UnknownHostException e) {
// Log the exception or handle it
}
return UNKNOWN; // 返回一个默认值,或者根据情况抛出异常
}
private static boolean isLocalhost(String ip) {
return ip.equals(LOCALHOST_IPV4) || ip.equals(LOCALHOST_IPV6);
}
}
6、优化获取ip
package com.xuecheng.base.utils;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
public class IPUtil {
// 定义一些常量
private static final String UNKNOWN = "unknown";
private static final String LOCALHOST_IPV4 = "127.0.0.1";
private static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:1";
private static final List<String> IP_HEADERS = Arrays.asList(
"x-forwarded-for",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_CLIENT_IP",
"HTTP_X_FORWARDED_FOR",
"X-Real-IP"
);
// IP地址格式验证正则表达式
private static final Pattern IP_PATTERN = Pattern.compile(
"^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$"
);
public static String getIpAddr(HttpServletRequest request) {
String ip = IP_HEADERS.stream()
.map(request::getHeader)
.filter(header -> header != null && !header.isEmpty() && !UNKNOWN.equalsIgnoreCase(header))
.findFirst()
.orElseGet(request::getRemoteAddr);
if (IP_PATTERN.matcher(ip).matches() || isLocalhost(ip)) {
return ip;
}
try {
InetAddress inet = InetAddress.getLocalHost();
ip = inet.getHostAddress();
if (IP_PATTERN.matcher(ip).matches()) {
return ip;
}
} catch (UnknownHostException e) {
// Log the exception or handle it
}
return UNKNOWN; // 返回一个默认值,或者根据情况抛出异常
}
private static boolean isLocalhost(String ip) {
return ip.equals(LOCALHOST_IPV4) || ip.equals(LOCALHOST_IPV6);
}
}
7、二维码生成
package com.xuecheng.base.utils;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang3.StringUtils;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
/**
* @author Mr.M
* @version 1.0
* @description 二维码生成工具
* @date 2022/10/3 0:03
*/public class QRCodeUtil {
/**
* 生成二维码
*
* @param content 二维码对应的URL
* @param width 二维码图片宽度
* @param height 二维码图片高度
* @return
*/
public String createQRCode(String content, int width, int height) throws IOException {
String resultImage = "";
//除了尺寸,传入内容不能为空
if (!StringUtils.isEmpty(content)) {
ServletOutputStream stream = null;
ByteArrayOutputStream os = new ByteArrayOutputStream();
//二维码参数
@SuppressWarnings("rawtypes")
HashMap<EncodeHintType, Comparable> hints = new HashMap<>();
//指定字符编码为“utf-8”
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
//L M Q H四个纠错等级从低到高,指定二维码的纠错等级为M
//纠错级别越高,可以修正的错误就越多,需要的纠错码的数量也变多,相应的二维吗可储存的数据就会减少
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
//设置图片的边距
hints.put(EncodeHintType.MARGIN, 1);
try {
//zxing生成二维码核心类
QRCodeWriter writer = new QRCodeWriter();
//把输入文本按照指定规则转成二维吗
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
//生成二维码图片流
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
//输出流
ImageIO.write(bufferedImage, "png", os);
/**
* 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析,所以加上前缀
*/
resultImage = new String("data:image/png;base64," + EncryptUtil.encodeBase64(os.toByteArray()));
return resultImage;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("生成二维码出错");
} finally {
if (stream != null) {
stream.flush();
stream.close();
}
}
}
return null;
}
// 二维码生成测试
public static void main(String[] args) throws IOException {
QRCodeUtil qrCodeUtil = new QRCodeUtil();
System.out.println(qrCodeUtil.createQRCode("http://10.232.39.166:63030/orders/alipaytest", 200, 200));
}
}
依赖
<!-- ZXing 二维码生成库 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version> <!-- 请使用最新版本 -->
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version> <!-- 请使用最新版本 -->
</dependency>
<!-- Apache Commons Lang 用于字符串操作 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version> <!-- 请使用最新版本 -->
</dependency>
8、二维码转base64码
package com.ruoyi.system.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Base64;
public class EncryptUtil {
private static final Logger logger = LoggerFactory.getLogger(EncryptUtil.class);
public static String encodeBase64(byte[] bytes){
String encoded = Base64.getEncoder().encodeToString(bytes);
return encoded;
}
public static byte[] decodeBase64(String str){
byte[] bytes = null;
bytes = Base64.getDecoder().decode(str);
return bytes;
}
public static String encodeUTF8StringBase64(String str){
String encoded = null;
try {
encoded = Base64.getEncoder().encodeToString(str.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
logger.warn("不支持的编码格式",e);
}
return encoded;
}
public static String decodeUTF8StringBase64(String str){
String decoded = null;
byte[] bytes = Base64.getDecoder().decode(str);
try {
decoded = new String(bytes,"utf-8");
}catch(UnsupportedEncodingException e){
logger.warn("不支持的编码格式",e);
}
return decoded;
}
public static String encodeURL(String url) {
String encoded = null;
try {
encoded = URLEncoder.encode(url, "utf-8");
} catch (UnsupportedEncodingException e) {
logger.warn("URLEncode失败", e);
}
return encoded;
}
public static String decodeURL(String url) {
String decoded = null;
try {
decoded = URLDecoder.decode(url, "utf-8");
} catch (UnsupportedEncodingException e) {
logger.warn("URLDecode失败", e);
}
return decoded;
}
public static void main(String [] args){
String str = "abcd{'a':'b'}";
String encoded = EncryptUtil.encodeUTF8StringBase64(str);
String decoded = EncryptUtil.decodeUTF8StringBase64(encoded);
System.out.println(str);
System.out.println(encoded);
System.out.println(decoded);
String url = "== wo";
String urlEncoded = EncryptUtil.encodeURL(url);
String urlDecoded = EncryptUtil.decodeURL(urlEncoded);
System.out.println(url);
System.out.println(urlEncoded);
System.out.println(urlDecoded);
}
}
9、字符串工具类
package com.xuecheng.base.utils;
import java.io.File;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StringUtil {
/** yyyy-MM-dd日期格式 */
public static final SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
public static final String SPACE = " ";
public static final String DOT = ".";
public static final String SLASH = "/";
public static final String BACKSLASH = "\\";
public static final String EMPTY = "";
public static final String CRLF = "\r\n";
public static final String NEWLINE = "\n";
public static final String UNDERLINE = "_";
public static final String COMMA = ",";
public static final String HTML_NBSP = " ";
public static final String HTML_AMP = "&";
public static final String HTML_QUOTE = """;
public static final String HTML_LT = "<";
public static final String HTML_GT = ">";
public static final String EMPTY_JSON = "{}";
/**
* 字符串是否为空白 空白的定义如下: <br>
* 1、为null <br>
* 2、为不可见字符(如空格)<br>
* 3、""<br>
*
* @param str
* 被检测的字符串
* @return 是否为空
*/
public static boolean isBlank(String str) {
return str == null || str.trim().length() == 0;
}
/**
* 字符串是否为非空白 空白的定义如下: <br>
* 1、不为null <br>
* 2、不为不可见字符(如空格)<br>
* 3、不为""<br>
*
* @param str 被检测的字符串
*
* @return 是否为非空
*/
public static boolean isNotBlank(String str) {
return false == isBlank(str);
}
/**
* 字符串是否为空,空的定义如下 1、为null <br>
* 2、为""<br>
*
* @param str
* 被检测的字符串
* @return 是否为空
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
* 字符串是否为非空白 空白的定义如下: <br>
* 1、不为null <br>
* 2、不为""<br>
*
* @param str
* 被检测的字符串
* @return 是否为非空
*/
public static boolean isNotEmpty(String str) {
return false == isEmpty(str);
}
/**
* 指定字符串是否被包装
*
* @param str
* 字符串
* @param prefix
* 前缀
* @param suffix
* 后缀
* @return 是否被包装
*/
public static boolean isWrap(String str, String prefix, String suffix) {
return str.startsWith(prefix) && str.endsWith(suffix);
}
/**
* 指定字符串是否被同一字符包装(前后都有这些字符串)
*
* @param str
* 字符串
* @param wrapper
* 包装字符串
* @return 是否被包装
*/
public static boolean isWrap(String str, String wrapper) {
return isWrap(str, wrapper, wrapper);
}
/**
* 指定字符串是否被同一字符包装(前后都有这些字符串)
*
* @param str
* 字符串
* @param wrapper
* 包装字符
* @return 是否被包装
*/
public static boolean isWrap(String str, char wrapper) {
return isWrap(str, wrapper, wrapper);
}
/**
* 指定字符串是否被包装
*
* @param str
* 字符串
* @param prefixChar
* 前缀
* @param suffixChar
* 后缀
* @return 是否被包装
*/
public static boolean isWrap(String str, char prefixChar, char suffixChar) {
return str.charAt(0) == prefixChar && str.charAt(str.length() - 1) == suffixChar;
}
/**
* 补充字符串以满足最小长度 StrUtil.padPre("1", 3, '0');//"001"
** @param str
* 字符串
* @param minLength
* 最小长度
* @param padChar
* 补充的字符
* @return 补充后的字符串
*/
public static String padPre(String str, int minLength, char padChar) {
if (str.length() >= minLength) {
return str;
}
StringBuilder sb = new StringBuilder(minLength);
for (int i = str.length(); i < minLength; i++) {
sb.append(padChar);
}
sb.append(str);
return sb.toString();
}
/**
* 补充字符串以满足最小长度 StrUtil.padEnd("1", 3, '0');//"100"
** @param str
* 字符串
* @param minLength
* 最小长度
* @param padChar
* 补充的字符
* @return 补充后的字符串
*/
public static String padEnd(String str, int minLength, char padChar) {
if (str.length() >= minLength) {
return str;
}
StringBuilder sb = new StringBuilder(minLength);
sb.append(str);
for (int i = str.length(); i < minLength; i++) {
sb.append(padChar);
}
return sb.toString();
}
/**
* 创建StringBuilder对象
*
* @return StringBuilder对象
*/
public static StringBuilder builder() {
return new StringBuilder();
}
/**
* 创建StringBuilder对象
*
* @return StringBuilder对象
*/
public static StringBuilder builder(int capacity) {
return new StringBuilder(capacity);
}
/**
* 创建StringBuilder对象
*
* @return StringBuilder对象
*/
public static StringBuilder builder(String... strs) {
final StringBuilder sb = new StringBuilder();
for (String str : strs) {
sb.append(str);
}
return sb;
}
/**
* 获得字符串对应字符集的byte数组
*
* @param str
* 字符串
* @param charset
* 字符集编码
* @return byte数组
*/
public static byte[] bytes(String str, String charset) {
if (null == str) {
return null;
}
if (isBlank(charset)) {
return null;
}
return str.getBytes(Charset.forName(charset));
}
/***
* 判断 String 是否int
** @param input
* @return
*/
public static boolean isInteger(String input) {
Matcher mer = Pattern.compile("^[+-]?[0-9]+$").matcher(input);
return mer.find();
}
/**
* 数字型String字符串转换成int型数组
*
* @param str
* string类型的数组
* @return
*/
public static Integer[] stringToIntegerArray(String[] str) {
Integer array[] = new Integer[str.length];
for (int i = 0; i < str.length; i++) {
array[i] = Integer.parseInt(str[i]);
}
return array;
}
/**
* 数字型String字符串转换成Long型数组
*
* @param str
* string类型的数组
* @return
*/
public static Long[] stringTOLongArray(String[] str) {
Long array[] = new Long[str.length];
for (int i = 0; i < str.length; i++) {
array[i] = Long.parseLong(str[i]);
}
return array;
}
/**
* 获取文件后缀
*
* @param src
* 文件路径/名称 文件路径 C:\Users\Public\Pictures\Sample Pictures\test.jpg
* @return 如果文件后缀 jpg
*/ public static String getFileExt(String src) {
String filename = src.substring(src.lastIndexOf(File.separator) + 1, src.length());// 获取到文件名
return filename.substring(filename.lastIndexOf(".") + 1);
}
/**
* 获取文件名称,不带文件后缀部分
*
* @param src
* 文件路径 C:\Users\Public\Pictures\Sample Pictures\test.jpg
* @return 文件名称 不带文件后缀 test
*/ public static String getFileName(String src) {
String filename = src.substring(src.lastIndexOf(File.separator) + 1, src.length());// 获取到文件名
return filename.substring(0, filename.lastIndexOf("."));
}
/**
* 判断字符串是否为空(不能为空字符串)
*
* @param src
* @return
*/
public static boolean isNull(String src) {
return src == null || src.length() == 0 || src.trim().length() == 0;
}
/**
* 检查数组中,是否含有当前元素
*
* @param arr
* @param checkValue
* @return
*/
public static Boolean checkArrayValue(String[] arr, String checkValue) {
Boolean checkFlag = false;
if (arr != null && arr.length > 0) {
for (int i = 0; i < arr.length; i++) {
if (arr[i].equals(checkValue)) {
checkFlag = true;
break;
}
}
}
return checkFlag;
}
/**
* 检查数组中元素,是否在checkValue中出现
*
* @param arr
* @param checkValue
* @return
*/
public static Boolean isContains(String[] arr, String checkValue) {
Boolean checkFlag = false;
if (arr != null && arr.length > 0) {
for (String str : arr) {
if (checkValue.indexOf(str)!=-1) {
checkFlag = true;
break;
}
}
}
return checkFlag;
}
}
10、跨域配置类
package com.youlai.system.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Collections;
/**
* CORS 资源共享配置
*
*/@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
//1.允许任何来源
corsConfiguration.setAllowedOriginPatterns(Collections.singletonList("*"));
//2.允许任何请求头
corsConfiguration.addAllowedHeader(CorsConfiguration.ALL);
//3.允许任何方法
corsConfiguration.addAllowedMethod(CorsConfiguration.ALL);
//4.允许凭证
corsConfiguration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfiguration);
CorsFilter corsFilter = new CorsFilter(source);
FilterRegistrationBean<CorsFilter> filterRegistrationBean=new FilterRegistrationBean<>(corsFilter);
filterRegistrationBean.setOrder(-101); // 小于 SpringSecurity Filter的 Order(-100) 即可
return filterRegistrationBean;
}
}
11、日志logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<configuration>
<!-- SpringBoot默认logback的配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<springProperty scope="context" name="APP_NAME" source="spring.application.name"/>
<property name="LOG_HOME" value="/logs/${APP_NAME}"/>
<!--1. 输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- <withJansi>true</withJansi>-->
<!--此日志appender是为开发使用,只配置最低级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter> <encoder> <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<charset>UTF-8</charset>
</encoder> </appender>
<!-- 2. 输出到文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 当前记录的日志文档完整路径 -->
<file>${LOG_HOME}/log.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} -%5level ---[%15.15thread] %-40.40logger{39} : %msg%n%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy> <!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy> <!-- 临界值过滤器,输出大于INFO级别日志 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter> </appender>
<!-- 开发环境输出至控制台 -->
<springProfile name="dev">
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root> </springProfile>
<!-- 生产环境输出至文件 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root> </springProfile></configuration>