From 9bc995c3b9e7481a13ec0d599d542d27c1d84a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=8A=9B?= Date: Fri, 6 May 2022 14:00:03 +0800 Subject: [PATCH] commit code --- .../com/storeroom/config/AdminProperties.java | 17 + .../com/storeroom/config/FileProperties.java | 43 +++ .../storeroom/config/YsPermissionConfig.java | 21 ++ .../storeroom/exception/BaseException.java | 67 +++- .../com/storeroom/utils/AdminConstant.java | 26 ++ .../java/com/storeroom/utils/FileUtil.java | 356 ++++++++++++++++++ .../com/storeroom/utils/MessageUtils.java | 13 + .../storeroom/utils/SpringContextHolder.java | 17 + .../java/com/storeroom/utils/SpringUtils.java | 54 +++ .../java/com/storeroom/utils/StringUtils.java | 270 +++++++++++++ pom.xml | 7 + 11 files changed, 881 insertions(+), 10 deletions(-) create mode 100644 common/src/main/java/com/storeroom/config/AdminProperties.java create mode 100644 common/src/main/java/com/storeroom/config/FileProperties.java create mode 100644 common/src/main/java/com/storeroom/config/YsPermissionConfig.java create mode 100644 common/src/main/java/com/storeroom/utils/AdminConstant.java create mode 100644 common/src/main/java/com/storeroom/utils/FileUtil.java create mode 100644 common/src/main/java/com/storeroom/utils/MessageUtils.java create mode 100644 common/src/main/java/com/storeroom/utils/SpringUtils.java create mode 100644 common/src/main/java/com/storeroom/utils/StringUtils.java diff --git a/common/src/main/java/com/storeroom/config/AdminProperties.java b/common/src/main/java/com/storeroom/config/AdminProperties.java new file mode 100644 index 0000000..92f72d1 --- /dev/null +++ b/common/src/main/java/com/storeroom/config/AdminProperties.java @@ -0,0 +1,17 @@ +package com.storeroom.config; + + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Data +@Component +public class AdminProperties { + public static Boolean ipLocal; + + @Value("${ip.local-parsing}") + public void setIpLocal(Boolean ipLocal) { + AdminProperties.ipLocal = ipLocal; + } +} diff --git a/common/src/main/java/com/storeroom/config/FileProperties.java b/common/src/main/java/com/storeroom/config/FileProperties.java new file mode 100644 index 0000000..1e1b2a6 --- /dev/null +++ b/common/src/main/java/com/storeroom/config/FileProperties.java @@ -0,0 +1,43 @@ +package com.storeroom.config; + + +import com.storeroom.utils.AdminConstant; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@ConfigurationProperties(prefix = "file") +public class FileProperties { + + /** 文件大小限制 */ + private Long maxSize; + + /** 头像大小限制 */ + private Long avatarMaxSize; + + private YsPath mac; + + private YsPath linux; + + private YsPath windows; + + public YsPath getPath(){ + String os = System.getProperty("os.name"); + if(os.toLowerCase().startsWith(AdminConstant.WIN)) { + return windows; + } else if(os.toLowerCase().startsWith(AdminConstant.MAC)){ + return mac; + } + return linux; + } + + @Data + public static class YsPath{ + + private String path; + + private String avatar; + } +} diff --git a/common/src/main/java/com/storeroom/config/YsPermissionConfig.java b/common/src/main/java/com/storeroom/config/YsPermissionConfig.java new file mode 100644 index 0000000..fed686a --- /dev/null +++ b/common/src/main/java/com/storeroom/config/YsPermissionConfig.java @@ -0,0 +1,21 @@ +package com.storeroom.config; + +import com.storeroom.utils.SecurityUtils; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + + +//自定义权限拦截 +@Service(value = "ys") +public class YsPermissionConfig { + public Boolean check(String ...permissions){ + // 获取当前用户的所有权限 + List elPermissions = SecurityUtils.getCurrentUser().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); + // 判断当前用户的所有权限是否包含接口上定义的权限 + return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains); + } +} diff --git a/common/src/main/java/com/storeroom/exception/BaseException.java b/common/src/main/java/com/storeroom/exception/BaseException.java index a4e9cf3..d106d98 100644 --- a/common/src/main/java/com/storeroom/exception/BaseException.java +++ b/common/src/main/java/com/storeroom/exception/BaseException.java @@ -1,6 +1,7 @@ package com.storeroom.exception; import com.storeroom.exception.constant.ResponseStatus; +import com.storeroom.utils.MessageUtils; import lombok.Data; import lombok.EqualsAndHashCode; @@ -12,22 +13,68 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) public class BaseException extends RuntimeException{ - private Integer code; - private String message; + private static final long serialVersionUID = 1L; + //所属模块 + private String module; - public BaseException(ResponseStatus responseStatus){ - super(responseStatus.getMessage()); - this.code= responseStatus.getCode(); - this.message= responseStatus.getMessage(); + //错误码 + private String code; + //错误消息 + private Object[] args; + + //错误消息 + private String defaultMessage; + + + public BaseException(String module, String code, Object[] args, String defaultMessage) { + this.module = module; + this.code = code; + this.args = args; + this.defaultMessage = defaultMessage; } + public BaseException(String module, String code, Object[] args) { + + this(module, code, args, null); + } + + public BaseException(String module, String defaultMessage) { + this(module, null, null, defaultMessage); + } + + public BaseException(String code, Object[] args) { + this(null, code, args, null); + } + + public BaseException(String defaultMessage){ + this(null,null,null,defaultMessage); + } + + @Override + public String getMessage(){ + String message=null; + if (code!=null){ + message= MessageUtils.message(String.valueOf(code),args); + } + if (message==null){ + message=defaultMessage; + } + return message; + } + + public String getModule() {return module;} + + public String getCode() {return code;} + + public Object[] getArgs() {return args;} + + public String getDefaultMessage() {return defaultMessage;} - public BaseException(Integer code,String message){ - super(message); - this.code=code; - this.message=message; + @Override + public synchronized Throwable fillInStackTrace() { + return this; } } diff --git a/common/src/main/java/com/storeroom/utils/AdminConstant.java b/common/src/main/java/com/storeroom/utils/AdminConstant.java new file mode 100644 index 0000000..4a42de6 --- /dev/null +++ b/common/src/main/java/com/storeroom/utils/AdminConstant.java @@ -0,0 +1,26 @@ +package com.storeroom.utils; + +public class AdminConstant { + + /** + * 用于IP定位转换 + */ + public static final String REGION = "内网IP|内网IP"; + /** + * win 系统 + */ + public static final String WIN = "win"; + + /** + * mac 系统 + */ + public static final String MAC = "mac"; + + /** + * 常用接口 + */ + public static class Url { + // IP归属地查询 + public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp?ip=%s&json=true"; + } +} diff --git a/common/src/main/java/com/storeroom/utils/FileUtil.java b/common/src/main/java/com/storeroom/utils/FileUtil.java new file mode 100644 index 0000000..f46e9ea --- /dev/null +++ b/common/src/main/java/com/storeroom/utils/FileUtil.java @@ -0,0 +1,356 @@ +package com.storeroom.utils; + +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.util.IdUtil; +import cn.hutool.poi.excel.BigExcelWriter; +import cn.hutool.poi.excel.ExcelUtil; +import com.storeroom.exception.BaseException; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.util.IOUtils; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.security.MessageDigest; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class FileUtil extends cn.hutool.core.io.FileUtil{ + private static final Logger log = LoggerFactory.getLogger(FileUtil.class); + + /** + * 系统临时目录 + *
+ * windows 包含路径分割符,但Linux 不包含, + * 在windows \\==\ 前提下, + * 为安全起见 同意拼装 路径分割符, + *
+     *       java.io.tmpdir
+     *       windows : C:\Users/xxx\AppData\Local\Temp\
+     *       linux: /temp
+     * 
+ */ + public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator; + /** + * 定义GB的计算常量 + */ + private static final int GB = 1024 * 1024 * 1024; + /** + * 定义MB的计算常量 + */ + private static final int MB = 1024 * 1024; + /** + * 定义KB的计算常量 + */ + private static final int KB = 1024; + + /** + * 格式化小数 + */ + private static final DecimalFormat DF = new DecimalFormat("0.00"); + + public static final String IMAGE = "图片"; + public static final String TXT = "文档"; + public static final String MUSIC = "音乐"; + public static final String VIDEO = "视频"; + public static final String OTHER = "其他"; + + + /** + * MultipartFile转File + */ + public static File toFile(MultipartFile multipartFile) { + // 获取文件名 + String fileName = multipartFile.getOriginalFilename(); + // 获取文件后缀 + String prefix = "." + getExtensionName(fileName); + File file = null; + try { + // 用uuid作为文件名,防止生成的临时文件重复 + file = File.createTempFile(IdUtil.simpleUUID(), prefix); + // MultipartFile to File + multipartFile.transferTo(file); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + return file; + } + + /** + * 获取文件扩展名,不带 . + */ + public static String getExtensionName(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length() - 1))) { + return filename.substring(dot + 1); + } + } + return filename; + } + + /** + * Java文件操作 获取不带扩展名的文件名 + */ + public static String getFileNameNoEx(String filename) { + if ((filename != null) && (filename.length() > 0)) { + int dot = filename.lastIndexOf('.'); + if ((dot > -1) && (dot < (filename.length()))) { + return filename.substring(0, dot); + } + } + return filename; + } + + /** + * 文件大小转换 + */ + public static String getSize(long size) { + String resultSize; + if (size / GB >= 1) { + //如果当前Byte的值大于等于1GB + resultSize = DF.format(size / (float) GB) + "GB "; + } else if (size / MB >= 1) { + //如果当前Byte的值大于等于1MB + resultSize = DF.format(size / (float) MB) + "MB "; + } else if (size / KB >= 1) { + //如果当前Byte的值大于等于1KB + resultSize = DF.format(size / (float) KB) + "KB "; + } else { + resultSize = size + "B "; + } + return resultSize; + } + + /** + * inputStream 转 File + */ + static File inputStreamToFile(InputStream ins, String name) throws Exception { + File file = new File(SYS_TEM_DIR + name); + if (file.exists()) { + return file; + } + OutputStream os = new FileOutputStream(file); + int bytesRead; + int len = 8192; + byte[] buffer = new byte[len]; + while ((bytesRead = ins.read(buffer, 0, len)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + return file; + } + + /** + * 将文件名解析成文件的上传路径 + */ + public static File upload(MultipartFile file, String filePath) { + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS"); + String name = getFileNameNoEx(file.getOriginalFilename()); + String suffix = getExtensionName(file.getOriginalFilename()); + String nowStr = "-" + format.format(date); + try { + String fileName = name + nowStr + "." + suffix; + String path = filePath + fileName; + // getCanonicalFile 可解析正确各种路径 + File dest = new File(path).getCanonicalFile(); + // 检测是否存在目录 + if (!dest.getParentFile().exists()) { + if (!dest.getParentFile().mkdirs()) { + System.out.println("was not successful."); + } + } + // 文件写入 + file.transferTo(dest); + return dest; + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } + + /** + * 导出excel + */ + public static void downloadExcel(List> list, HttpServletResponse response) throws IOException { + String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx"; + File file = new File(tempPath); + BigExcelWriter writer = ExcelUtil.getBigWriter(file); + // 一次性写出内容,使用默认样式,强制输出标题 + writer.write(list, true); + SXSSFSheet sheet = (SXSSFSheet)writer.getSheet(); + //上面需要强转SXSSFSheet 不然没有trackAllColumnsForAutoSizing方法 + sheet.trackAllColumnsForAutoSizing(); + //列宽自适应 + writer.autoSizeColumnAll(); + //列宽自适应支持中文单元格 + sizeChineseColumn(sheet, writer); + //response为HttpServletResponse对象 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); + //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码 + response.setHeader("Content-Disposition", "attachment;filename=file.xlsx"); + ServletOutputStream out = response.getOutputStream(); + // 终止后删除临时文件 + file.deleteOnExit(); + writer.flush(out, true); + //此处记得关闭输出Servlet流 + IoUtil.close(out); + } + + /** + * 自适应宽度(中文支持) + */ + private static void sizeChineseColumn(SXSSFSheet sheet, BigExcelWriter writer) { + for (int columnNum = 0; columnNum < writer.getColumnCount(); columnNum++) { + int columnWidth = sheet.getColumnWidth(columnNum) / 256; + for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) { + SXSSFRow currentRow; + if (sheet.getRow(rowNum) == null) { + currentRow = sheet.createRow(rowNum); + } else { + currentRow = sheet.getRow(rowNum); + } + if (currentRow.getCell(columnNum) != null) { + SXSSFCell currentCell = currentRow.getCell(columnNum); + if (currentCell.getCellTypeEnum() == CellType.STRING) { + int length = currentCell.getStringCellValue().getBytes().length; + if (columnWidth < length) { + columnWidth = length; + } + } + } + } + sheet.setColumnWidth(columnNum, columnWidth * 256); + } + } + + public static String getFileType(String type) { + String documents = "txt doc pdf ppt pps xlsx xls docx"; + String music = "mp3 wav wma mpa ram ra aac aif m4a"; + String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg"; + String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg"; + if (image.contains(type)) { + return IMAGE; + } else if (documents.contains(type)) { + return TXT; + } else if (music.contains(type)) { + return MUSIC; + } else if (video.contains(type)) { + return VIDEO; + } else { + return OTHER; + } + } + + public static void checkSize(long maxSize, long size) { + // 1M + int len = 1024 * 1024; + if (size > (maxSize * len)) { + throw new BaseException("文件超出规定大小"); + } + } + + /** + * 判断两个文件是否相同 + */ + public static boolean check(File file1, File file2) { + String img1Md5 = getMd5(file1); + String img2Md5 = getMd5(file2); + return img1Md5.equals(img2Md5); + } + + /** + * 判断两个文件是否相同 + */ + public static boolean check(String file1Md5, String file2Md5) { + return file1Md5.equals(file2Md5); + } + + private static byte[] getByte(File file) { + // 得到文件长度 + byte[] b = new byte[(int) file.length()]; + try { + InputStream in = new FileInputStream(file); + try { + System.out.println(in.read(b)); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } catch (FileNotFoundException e) { + log.error(e.getMessage(), e); + return null; + } + return b; + } + + private static String getMd5(byte[] bytes) { + // 16进制字符 + char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(bytes); + byte[] md = mdTemp.digest(); + int j = md.length; + char[] str = new char[j * 2]; + int k = 0; + // 移位 输出字符串 + for (byte byte0 : md) { + str[k++] = hexDigits[byte0 >>> 4 & 0xf]; + str[k++] = hexDigits[byte0 & 0xf]; + } + return new String(str); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return null; + } + + /** + * 下载文件 + * + * @param request / + * @param response / + * @param file / + */ + public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) { + response.setCharacterEncoding(request.getCharacterEncoding()); + response.setContentType("application/octet-stream"); + FileInputStream fis = null; + try { + fis = new FileInputStream(file); + response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); + IOUtils.copy(fis, response.getOutputStream()); + response.flushBuffer(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + if (fis != null) { + try { + fis.close(); + if (deleteOnExit) { + file.deleteOnExit(); + } + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + } + } + + public static String getMd5(File file) { + return getMd5(getByte(file)); + } + +} diff --git a/common/src/main/java/com/storeroom/utils/MessageUtils.java b/common/src/main/java/com/storeroom/utils/MessageUtils.java new file mode 100644 index 0000000..899f958 --- /dev/null +++ b/common/src/main/java/com/storeroom/utils/MessageUtils.java @@ -0,0 +1,13 @@ +package com.storeroom.utils; + +import cn.hutool.extra.spring.SpringUtil; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; + +public class MessageUtils { + + public static String message(String code,Object... args){ + MessageSource messageSource= SpringUtils.getBean(MessageSource.class); + return messageSource.getMessage(code,args,LocaleContextHolder.getLocale()); + } +} diff --git a/common/src/main/java/com/storeroom/utils/SpringContextHolder.java b/common/src/main/java/com/storeroom/utils/SpringContextHolder.java index 259d951..5ce1bb9 100644 --- a/common/src/main/java/com/storeroom/utils/SpringContextHolder.java +++ b/common/src/main/java/com/storeroom/utils/SpringContextHolder.java @@ -5,6 +5,7 @@ import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; import java.util.ArrayList; @@ -60,6 +61,22 @@ public class SpringContextHolder implements ApplicationContextAware, DisposableB applicationContext = null; } + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @param defaultValue 默认值 + * @param requiredType 返回类型 + * @return / + */ + public static T getProperties(String property, T defaultValue, Class requiredType) { + T result = defaultValue; + try { + result = getBean(Environment.class).getProperty(property, requiredType); + } catch (Exception ignored) {} + return result; + } + @Override public void destroy() { SpringContextHolder.clearHolder(); diff --git a/common/src/main/java/com/storeroom/utils/SpringUtils.java b/common/src/main/java/com/storeroom/utils/SpringUtils.java new file mode 100644 index 0000000..bc569ea --- /dev/null +++ b/common/src/main/java/com/storeroom/utils/SpringUtils.java @@ -0,0 +1,54 @@ +package com.storeroom.utils; + +import org.springframework.aop.framework.AopContext; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.stereotype.Component; + +@Component +public class SpringUtils implements BeanFactoryPostProcessor { + + //Spring 应用上下文环境 + private static ConfigurableListableBeanFactory beanFactory; + + + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + SpringUtils.beanFactory = beanFactory; + } + + //获取对象 + public static T getBean(String name) throws BeansException { + return (T) beanFactory.getBean(name); + } + + + //获取类型为requiredType对象 + public static T getBean(Class clz) throws BeansException { + T result = (T) beanFactory.getBean(clz); + return result; + } + + //判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException) + public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException { + return beanFactory.isSingleton(name); + } + + //Class 注册对象的类型 + public static Class getType(String name) throws NoSuchBeanDefinitionException { + return beanFactory.getType(name); + } + + //如果给定的bean名字在bean定义中有别名,则返回这些别名 + public static String[] getAliases(String name) throws NoSuchBeanDefinitionException { + return beanFactory.getAliases(name); + } + + //获取aop代理对象 + @SuppressWarnings("unchecked") + public static T getAopProxy(T invoker) { + return (T) AopContext.currentProxy(); + } +} diff --git a/common/src/main/java/com/storeroom/utils/StringUtils.java b/common/src/main/java/com/storeroom/utils/StringUtils.java new file mode 100644 index 0000000..c003a62 --- /dev/null +++ b/common/src/main/java/com/storeroom/utils/StringUtils.java @@ -0,0 +1,270 @@ +package com.storeroom.utils; + +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.storeroom.config.AdminProperties; +import eu.bitwalker.useragentutils.Browser; +import eu.bitwalker.useragentutils.UserAgent; +import lombok.extern.slf4j.Slf4j; +import org.lionsoul.ip2region.DataBlock; +import org.lionsoul.ip2region.DbConfig; +import org.lionsoul.ip2region.DbSearcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.UnknownHostException; +import java.util.Calendar; +import java.util.Date; +import java.util.Enumeration; + + +public class StringUtils extends org.apache.commons.lang3.StringUtils{ + + private static final Logger log = LoggerFactory.getLogger(StringUtils.class); + private static boolean ipLocal = false; + private static File file = null; + private static DbConfig config; + private static final char SEPARATOR = '_'; + private static final String UNKNOWN = "unknown"; + + static { + SpringContextHolder.addCallBacks(() -> { + StringUtils.ipLocal = SpringContextHolder.getProperties("ip.local-parsing", false, Boolean.class); + if (ipLocal) { + /* + * 此文件为独享 ,不必关闭 + */ + String path = "ip2region/ip2region.db"; + String name = "ip2region.db"; + try { + config = new DbConfig(); + file = FileUtil.inputStreamToFile(new ClassPathResource(path).getInputStream(), name); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + }); + } + + /** + * 驼峰命名法工具 + * + * @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" + */ + 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(); + } + + /** + * 获取ip地址 + */ + public static String getIp(HttpServletRequest request) { + 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("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + String comma = ","; + String localhost = "127.0.0.1"; + if (ip.contains(comma)) { + ip = ip.split(",")[0]; + } + if (localhost.equals(ip)) { + // 获取本机真正的ip地址 + try { + ip = InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + log.error(e.getMessage(), e); + } + } + return ip; + } + + /** + * 根据ip获取详细地址 + */ + public static String getCityInfo(String ip) { + if (ipLocal) { + return getLocalCityInfo(ip); + } else { + return getHttpCityInfo(ip); + } + } + + /** + * 根据ip获取详细地址 + */ + public static String getHttpCityInfo(String ip) { + String api = String.format(AdminConstant.Url.IP_URL, ip); + JSONObject object = JSONUtil.parseObj(HttpUtil.get(api)); + return object.get("addr", String.class); + } + + /** + * 根据ip获取详细地址 + */ + public static String getLocalCityInfo(String ip) { + try { + DataBlock dataBlock = new DbSearcher(config, file.getPath()) + .binarySearch(ip); + String region = dataBlock.getRegion(); + String address = region.replace("0|", ""); + char symbol = '|'; + if (address.charAt(address.length() - 1) == symbol) { + address = address.substring(0, address.length() - 1); + } + return address.equals(AdminConstant.REGION) ? "内网IP" : address; + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return ""; + } + + public static String getBrowser(HttpServletRequest request) { + UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); + Browser browser = userAgent.getBrowser(); + return browser.getName(); + } + + /** + * 获得当天是周几 + */ + public static String getWeekDay() { + String[] weekDays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + + int w = cal.get(Calendar.DAY_OF_WEEK) - 1; + if (w < 0) { + w = 0; + } + return weekDays[w]; + } + + /** + * 获取当前机器的IP + * + * @return / + */ + public static String getLocalIp() { + try { + InetAddress candidateAddress = null; + // 遍历所有的网络接口 + for (Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();) { + NetworkInterface anInterface = interfaces.nextElement(); + // 在所有的接口下再遍历IP + for (Enumeration inetAddresses = anInterface.getInetAddresses(); inetAddresses.hasMoreElements();) { + InetAddress inetAddr = inetAddresses.nextElement(); + // 排除loopback类型地址 + if (!inetAddr.isLoopbackAddress()) { + if (inetAddr.isSiteLocalAddress()) { + // 如果是site-local地址,就是它了 + return inetAddr.getHostAddress(); + } else if (candidateAddress == null) { + // site-local类型的地址未被发现,先记录候选地址 + candidateAddress = inetAddr; + } + } + } + } + if (candidateAddress != null) { + return candidateAddress.getHostAddress(); + } + // 如果没有发现 non-loopback地址.只能用最次选的方案 + InetAddress jdkSuppliedAddress = InetAddress.getLocalHost(); + if (jdkSuppliedAddress == null) { + return ""; + } + return jdkSuppliedAddress.getHostAddress(); + } catch (Exception e) { + return ""; + } + } +} diff --git a/pom.xml b/pom.xml index 8d3e02a..7fef809 100644 --- a/pom.xml +++ b/pom.xml @@ -210,6 +210,13 @@ 15.3 + + + net.dreamlu + mica-ip2region + 2.5.6 + + eu.bitwalker