springboot常用解决跨域问题方式以及commons-lang3(常用工具)以及springboot 定制启动图案
1、处理个别controller,在controller上使用@CrossOrigin注解即可 @RestController @RequestMapping("/api") public class SysController { @CrossOrigin @GetMapping("/systime") public ApiResult sysTime() { try { List<SysTimeVO> sysTimeVOList = sysService.querySysTime(); return new ApiResult() .setSuccess(true) ...... 2、全局配置,配置WebMvcConfigurer @Configuration public class WebConfig implements WebMvcConfigurer { // 设置允许跨域请求 @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry .addMapping("/**") // .allowedOrigins("http://yyy.com", "http://xxx.com") // // 允许跨域的域名 .allowedOriginPatterns("*") // 允许所有域 .allowedMethods("*") // 允许任何方法(post、get等) .allowedHeaders("*") // 允许任何请求头 .allowCredentials(true) // 允许证书、cookie .exposedHeaders(HttpHeaders.SET_COOKIE) .maxAge(3600L); // maxAge(3600)表明在3600秒内,不需要再发送预检验请求,可以缓存该结果 } }; } }
拦截器 设置ip白名单 参考: https://www.cnblogs.com/huhongy/p/12192310.html https://www.cnblogs.com/zktww/p/11550891.html
commons-lang3(常用)
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.9</version> </dependency> 字符串的处理类(StringUtils) //缩短到某长度,用...结尾.其实就是(substring(str, 0, max-3) + "...") //public static String abbreviate(String str,int maxWidth) StringUtils.abbreviate("abcdefg", 6);// ---"abc..." //字符串结尾的后缀是否与你要结尾的后缀匹配,若不匹配则添加后缀 StringUtils.appendIfMissing("abc","xyz");//---"abcxyz" StringUtils.appendIfMissingIgnoreCase("abcXYZ","xyz");//---"abcXYZ" //首字母大小写转换 StringUtils.capitalize("cat");//---"Cat" StringUtils.uncapitalize("Cat");//---"cat" //字符串扩充至指定大小且居中(若扩充大小少于原字符大小则返回原字符,若扩充大小为 负数则为0计算 ) StringUtils.center("abcd", 2);//--- "abcd" StringUtils.center("ab", -1);//--- "ab" StringUtils.center("ab", 4);//---" ab " StringUtils.center("a", 4, "yz");//---"yayz" StringUtils.center("abc", 7, "");//---" abc " //去除字符串中的"\n", "\r", or "\r\n" StringUtils.chomp("abc\r\n");//---"abc" //判断一字符串是否包含另一字符串 StringUtils.contains("abc", "z");//---false StringUtils.containsIgnoreCase("abc", "A");//---true //统计一字符串在另一字符串中出现次数 StringUtils.countMatches("abba", "a");//---2 //删除字符串中的梭有空格 StringUtils.deleteWhitespace(" ab c ");//---"abc" //比较两字符串,返回不同之处。确切的说是返回第二个参数中与第一个参数所不同的字符串 StringUtils.difference("abcde", "abxyz");//---"xyz" //检查字符串结尾后缀是否匹配 StringUtils.endsWith("abcdef", "def");//---true StringUtils.endsWithIgnoreCase("ABCDEF", "def");//---true StringUtils.endsWithAny("abcxyz", new String[] {null, "xyz", "abc"});//---true //检查起始字符串是否匹配 StringUtils.startsWith("abcdef", "abc");//---true StringUtils.startsWithIgnoreCase("ABCDEF", "abc");//---true StringUtils.startsWithAny("abcxyz", new String[] {null, "xyz", "abc"});//---true //判断两字符串是否相同 StringUtils.equals("abc", "abc");//---true StringUtils.equalsIgnoreCase("abc", "ABC");//---true //比较字符串数组内的所有元素的字符序列,起始一致则返回一致的字符串,若无则返回"" StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"});//---"ab" //正向查找字符在字符串中第一次出现的位置 StringUtils.indexOf("aabaabaa", "b");//---2 StringUtils.indexOf("aabaabaa", "b", 3);//---5(从角标3后查找) StringUtils.ordinalIndexOf("aabaabaa", "a", 3);//---1(查找第n次出现的位置) //反向查找字符串第一次出现的位置 StringUtils.lastIndexOf("aabaabaa", ‘b‘);//---5 StringUtils.lastIndexOf("aabaabaa", ‘b‘, 4);//---2 StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2);//---1 //判断字符串大写、小写 StringUtils.isAllUpperCase("ABC");//---true StringUtils.isAllLowerCase("abC");//---false //判断是否为空(注:isBlank与isEmpty 区别) StringUtils.isBlank(null);StringUtils.isBlank("");StringUtils.isBlank(" ");//---true StringUtils.isNoneBlank(" ", "bar");//---false StringUtils.isEmpty(null);StringUtils.isEmpty("");//---true StringUtils.isEmpty(" ");//---false StringUtils.isNoneEmpty(" ", "bar");//---true //判断字符串数字 StringUtils.isNumeric("123");//---false StringUtils.isNumeric("12 3");//---false (不识别运算符号、小数点、空格……) StringUtils.isNumericSpace("12 3");//---true //数组中加入分隔符号 //StringUtils.join([1, 2, 3], ‘;‘);//---"1;2;3" //大小写转换 StringUtils.upperCase("aBc");//---"ABC" StringUtils.lowerCase("aBc");//---"abc" StringUtils.swapCase("The dog has a BONE");//---"tHE DOG HAS A bone" //替换字符串内容……(replacePattern、replceOnce) StringUtils.replace("aba", "a", "z");//---"zbz" StringUtils.overlay("abcdef", "zz", 2, 4);//---"abzzef"(指定区域) StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"});//---"wcte"(多组指定替换ab->w,d->t) //重复字符 StringUtils.repeat(‘e‘, 3);//---"eee" //反转字符串 StringUtils.reverse("bat");//---"tab" //删除某字符 StringUtils.remove("queued", ‘u‘);//---"qeed" //分割字符串 StringUtils.split("a..b.c", ‘.‘);//---["a", "b", "c"] StringUtils.split("ab:cd:ef", ":", 2);//---["ab", "cd:ef"] StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 2);//---["ab", "cd-!-ef"] StringUtils.splitByWholeSeparatorPreserveAllTokens("ab::cd:ef", ":");//-["ab"," ","cd","ef"] //去除首尾空格,类似trim……(stripStart、stripEnd、stripAll、stripAccents) StringUtils.strip(" ab c ");//---"ab c" StringUtils.stripToNull(null);//---null StringUtils.stripToEmpty(null);//---"" //截取字符串 StringUtils.substring("abcd", 2);//---"cd" StringUtils.substring("abcdef", 2, 4);//---"cd" //left、right从左(右)开始截取n位字符 StringUtils.left("abc", 2);//---"ab" StringUtils.right("abc", 2);//---"bc" //从第n位开始截取m位字符 n m StringUtils.mid("abcdefg", 2, 4);//---"cdef" StringUtils.substringBefore("abcba", "b");//---"a" StringUtils.substringBeforeLast("abcba", "b");//---"abc" StringUtils.substringAfter("abcba", "b");//---"cba" StringUtils.substringAfterLast("abcba", "b");//---"a" StringUtils.substringBetween("tagabctag", "tag");//---"abc" StringUtils.substringBetween("yabczyabcz", "y", "z");//---"abc" 随机数生成类(RandomStringUtils) //随机生成n位数数字 RandomStringUtils.randomNumeric(n); //在指定字符串中生成长度为n的随机字符串 RandomStringUtils.random(n, "abcdefghijk"); //指定从字符或数字中生成随机字符串 System.out.println(RandomStringUtils.random(n, true, false)); System.out.println(RandomStringUtils.random(n, false, true)); 数字类NumberUtils //从数组中选出最大值 NumberUtils.max(new int[] { 1, 2, 3, 4 });//---4 //判断字符串是否全是整数 NumberUtils.isDigits("153.4");//--false //判断字符串是否是有效数字 NumberUtils.isNumber("0321.1");//---false 数组类 ArrayUtils //创建数组 String[] array = ArrayUtils.toArray("1", "2"); //判断两个数据是否相等,如果内容相同, 顺序相同 则返回 true ArrayUtils.isEquals(arr1,arr2); //判断数组中是否包含某一对象 ArrayUtils.contains(arr, "33"); //二维数组转换成MAP Map map = ArrayUtils.toMap(new String[][] { { "RED", "#FF0000" }, { "GREEN", "#00FF00" }, { "BLUE", "#0000FF" } }); 日期类DateUtils //日期加n天 DateUtils.addDays(new Date(), n); //判断是否同一天 DateUtils.isSameDay(date1, date2); //字符串时间转换为Date DateUtils.parseDate(str, parsePatterns); 附: StringUtile /* * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.funtl.leesite.common.utils; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import com.google.common.collect.Lists; import org.apache.commons.lang3.StringEscapeUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.LocaleResolver; /** * 字符串工具类, 继承org.apache.commons.lang3.StringUtils类 * * @author Lusifer * @version 2013-05-22 */ public class StringUtils extends org.apache.commons.lang3.StringUtils { private static final char SEPARATOR = '_'; private static final String CHARSET_NAME = "UTF-8"; /** * 转换为字节数组 * * @param str * @return */ public static byte[] getBytes(String str) { if (str != null) { try { return str.getBytes(CHARSET_NAME); } catch (UnsupportedEncodingException e) { return null; } } else { return null; } } /** * 转换为字节数组 * * @param str * @return */ public static String toString(byte[] bytes) { try { return new String(bytes, CHARSET_NAME); } catch (UnsupportedEncodingException e) { return EMPTY; } } /** * 是否包含字符串 * * @param str 验证字符串 * @param strs 字符串组 * @return 包含返回true */ public static boolean inString(String str, String... strs) { if (str != null) { for (String s : strs) { if (str.equals(trim(s))) { return true; } } } return false; } /** * 替换掉HTML标签方法 */ public static String replaceHtml(String html) { if (isBlank(html)) { return ""; } String regEx = "<.+?>"; Pattern p = Pattern.compile(regEx); Matcher m = p.matcher(html); String s = m.replaceAll(""); return s; } /** * 替换为手机识别的HTML,去掉样式及属性,保留回车。 * * @param html * @return */ public static String replaceMobileHtml(String html) { if (html == null) { return ""; } return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>"); } /** * 替换为手机识别的HTML,去掉样式及属性,保留回车。 * * @param txt * @return */ public static String toHtml(String txt) { if (txt == null) { return ""; } return replace(replace(Encodes.escapeHtml(txt), "\n", "<br/>"), "\t", " "); } /** * 缩略字符串(不区分中英文字符) * * @param str 目标字符串 * @param length 截取长度 * @return */ public static String abbr(String str, int length) { if (str == null) { return ""; } try { StringBuilder sb = new StringBuilder(); int currentLength = 0; for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) { currentLength += String.valueOf(c).getBytes("GBK").length; if (currentLength <= length - 3) { sb.append(c); } else { sb.append("..."); break; } } return sb.toString(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return ""; } public static String abbr2(String param, int length) { if (param == null) { return ""; } StringBuffer result = new StringBuffer(); int n = 0; char temp; boolean isCode = false; // 是不是HTML代码 boolean isHTML = false; // 是不是HTML特殊字符,如 for (int i = 0; i < param.length(); i++) { temp = param.charAt(i); if (temp == '<') { isCode = true; } else if (temp == '&') { isHTML = true; } else if (temp == '>' && isCode) { n = n - 1; isCode = false; } else if (temp == ';' && isHTML) { isHTML = false; } try { if (!isCode && !isHTML) { n += String.valueOf(temp).getBytes("GBK").length; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } if (n <= length - 3) { result.append(temp); } else { result.append("..."); break; } } // 取出截取字符串中的HTML标记 String temp_result = result.toString().replaceAll("(>)[^<>]*(<?)", "$1$2"); // 去掉不需要结素标记的HTML标记 temp_result = temp_result.replaceAll("</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>", ""); // 去掉成对的HTML标记 temp_result = temp_result.replaceAll("<([a-zA-Z]+)[^<>]*>(.*?)</\\1>", "$2"); // 用正则表达式取出标记 Pattern p = Pattern.compile("<([a-zA-Z]+)[^<>]*>"); Matcher m = p.matcher(temp_result); List<String> endHTML = Lists.newArrayList(); while (m.find()) { endHTML.add(m.group(1)); } // 补全不成对的HTML标记 for (int i = endHTML.size() - 1; i >= 0; i--) { result.append("</"); result.append(endHTML.get(i)); result.append(">"); } return result.toString(); } /** * 转换为Double类型 */ public static Double toDouble(Object val) { if (val == null) { return 0D; } try { return Double.valueOf(trim(val.toString())); } catch (Exception e) { return 0D; } } /** * 转换为Float类型 */ public static Float toFloat(Object val) { return toDouble(val).floatValue(); } /** * 转换为Long类型 */ public static Long toLong(Object val) { return toDouble(val).longValue(); } /** * 转换为Integer类型 */ public static Integer toInteger(Object val) { return toLong(val).intValue(); } /** * 获得i18n字符串 */ public static String getMessage(String code, Object[] args) { LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); Locale localLocale = localLocaleResolver.resolveLocale(request); return SpringContextHolder.getApplicationContext().getMessage(code, args, localLocale); } /** * 获得用户远程地址 */ public static String getRemoteAddr(HttpServletRequest request) { String remoteAddr = request.getHeader("X-Real-IP"); if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("X-Forwarded-For"); } else if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("Proxy-Client-IP"); } else if (isNotBlank(remoteAddr)) { remoteAddr = request.getHeader("WL-Proxy-Client-IP"); } return remoteAddr != null ? remoteAddr : request.getRemoteAddr(); } /** * 驼峰命名法工具 * * @return toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" */ public static String toCamelCase(String s) { if (s == null) { return null; } s = s.toLowerCase(); StringBuilder sb = new StringBuilder(s.length()); boolean upperCase = false; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == SEPARATOR) { upperCase = true; } else if (upperCase) { sb.append(Character.toUpperCase(c)); upperCase = false; } else { sb.append(c); } } return sb.toString(); } /** * 驼峰命名法工具 * * @return toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" */ public static String toCapitalizeCamelCase(String s) { if (s == null) { return null; } s = toCamelCase(s); return s.substring(0, 1).toUpperCase() + s.substring(1); } /** * 驼峰命名法工具 * * @return toCamelCase("hello_world") == "helloWorld" * toCapitalizeCamelCase("hello_world") == "HelloWorld" * toUnderScoreCase("helloWorld") = "hello_world" */ 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 target * @param source */ public static void setValueIfNotBlank(String target, String source) { if (isNotBlank(source)) { target = source; } } /** * 转换为JS获取对象值,生成三目运算返回结果 * * @param objectString 对象串 * 例如:row.user.id * 返回:!row?'':!row.user?'':!row.user.id?'':row.user.id */ public static String jsGetVal(String objectString) { StringBuilder result = new StringBuilder(); StringBuilder val = new StringBuilder(); String[] vals = split(objectString, "."); for (int i = 0; i < vals.length; i++) { val.append("." + vals[i]); result.append("!" + (val.substring(1)) + "?'':"); } result.append(val.substring(1)); return result.toString(); } /** * 通过正则表达式获取内容 * * @param regex 正则表达式 * @param from 原字符串 * @return */ public static String[] regex(String regex, String from) { Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(from); List<String> results = new ArrayList<String>(); while (matcher.find()) { for (int i = 0; i < matcher.groupCount(); i++) { results.add(matcher.group(i + 1)); } } return results.toArray(new String[]{}); } }
Spring Boot在启动的时候会显示一个默认的Spring的图案,对应的类为SpringBootBanner
图案输出有以下几种模式,默认是CONSOLE的,即只打印到控制台,也可以输出到日志文件
springboot项目启动的的打印数据,在log中可以清楚的看到有一个spring的banner图案,这个图案其实我们是可以自己进行设置的
我们在项目目录的resources目录下创建一个banner.txt文件,将我们自己的图案放进去就可以了,这里有几个可以生成banner的网址,有兴趣的小伙伴可以试试:http://patorjk.com/software/taag/、http://www.network-science.de/ascii/
如果我们不想显示banner也是可以的,有两种方法可以
第一种:在启动类main方法中进行设置
@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication application = new SpringApplication(DemoApplication.class); application.setBannerMode(Banner.Mode.OFF); application.run(args); } }
第二种:在application.properties配置文件中进行配置
spring.main.banner-mode=off
其实我们直接在resources目录下创建一个空的banner.txt文件也是可以起到去除效果的
enum Mode { /** * Disable printing of the banner. */ OFF, /** * Print the banner to System.out. */ CONSOLE, /** * Print the banner to the log file. */ LOG
}