Files
wxSend/src/main/java/cn/van333/wxsend/util/QCUtil.java
雷欧(林平凡) 3edd22705e 1
2025-07-29 16:04:54 +08:00

1555 lines
40 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package cn.van333.wxsend.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.web.util.HtmlUtils;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
/**
* 最基础的工具类
*/
public class QCUtil {
private static final Logger log = LoggerFactory.getLogger(QCUtil.class);
/**
* byte数组倒序
*
* @param bytes
* @return
*/
public static final byte[] byteArrayDesc(byte[] bytes) {
if (QCUtil.isEmpty(bytes)) {
return new byte[0];
}
int len = bytes.length;
byte[] tmp = new byte[len];
for (int i = len - 1; i >= 0; i--) {
tmp[len - i - 1] = bytes[i];
}
return tmp;
}
/**
* 打印程序耗时
*
* @param msg
*/
public static final void consume(long start, long end, String msg) {
System.err.printf("%s consume times: %s=%s-%s%n", msg, (end - start), end, start);
}
/**
* 将非法且不可见的XML字符转为空格空格的的ascii码是32
*
* @param bts
* byte[]
* @return 转换后的 byte[]
*/
public static final byte[] convertInvalidInvisibleToSpace(byte[] bytes) {
if (QCUtil.isEmpty(bytes)) {
return new byte[0];
}
byte[] tmp = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
if (b >= 0 && b <= 8 || b >= 14 && b <= 31 || b == 11 || b == 12 || b == 127) {
tmp[i] = 32;
} else {
tmp[i] = bytes[i];
}
}
return tmp;
}
/**
* 将非法且不可见的XML字符转为空格
*
*/
public static final String convertInvalidInvisibleToSpace(String str) {
if (QCUtil.isEmpty(str)) {
return "";
}
return new String(QCUtil.convertInvalidInvisibleToSpace(str.getBytes()));
}
/**
* 将非法且不可见的XML字符转为空格
*
* @param bts
* byte[]
* @return 转换后的 byte[]
*/
public static final byte[] convertInvalidInvisibleXml(byte[] bytes) {
if (QCUtil.isEmpty(bytes)) {
return new byte[0];
}
byte[] tmp = new byte[bytes.length];
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
if (b >= 0 && b <= 8)// \\x00-\\x08
{
tmp[i] = 32;
} else if (b >= 14 && b <= 31)// \\x0e-\\x1f
{
tmp[i] = 32;
} else if (b == 11 || b == 12 || b == 127)// \\x0b-\\x0c and \\x7f
{
tmp[i] = 32;
} else {
tmp[i] = bytes[i];
}
}
return tmp;
}
/**
* 删除临时文件.
*
* @param dir
*/
public static final void deleteTempFile(String dir) {
File tf = new File(dir);
String[] childs = tf.list();
for (String child : childs) {
new File(dir + File.separator + child).delete();
}
}
/**
* 读取文件路径返回DataSource容器
*
* @param attFiles
* @return
*/
public static final List<DataSource> fileDirsToDatasource(List<File> attFiles) {
DataSource dc = null;
List<DataSource> dcs = new ArrayList<DataSource>();
if (isNotEmpty(attFiles)) {
for (File file : attFiles) {
dc = new FileDataSource(file);
dcs.add(dc);
}
}
return dcs;
}
/**
* 得到数组中非空元素的数量
*
* @param arr
* @return
*/
public static final int getArraySizeWithoutEmptyElement(String[] arr) {
if (QCUtil.isEmpty(arr)) {
return 0;
}
int count = 0;
for (String s : arr) {
if (!QCUtil.isEmpty(s)) {
count++;
}
}
return count;
}
/**
* 指定cookie的key获取对应的value。
*
* @param request
* @param key
* cookie key
* @return cookie value
*/
public static final String getCookieValue(HttpServletRequest request, String key) {
if (QCUtil.isAnyEmpty(key, request)) {
return "";
}
Cookie[] cookies = request.getCookies();
if (QCUtil.isNotEmpty(cookies)) {
for (Cookie c : cookies) {
if (key.equals(c.getName())) {
if (QCUtil.isNotEmpty(c.getValue())) {
return c.getValue();
}
break;
}
}
}
return "";
}
/**
*
* @param response
* @param key
* 键
* @param value
* 值
* @param maxAge
* 存活时间,默认-1
* @param path
* 有效域,默认/
*/
public static void setCookie(HttpServletResponse response, String key, String value, Integer maxAge, String path) {
Cookie cookie = new Cookie(key, value);
// 设置浏览器的cookie保留时间单位秒。负值标识浏览器关闭即删除cookie0表示马上删除。
// 这里设置成一年如果想控制登录超时可以用ADMIN_SESSION_TIMEOUT在t_parameter中设置redis的超时时间统一后台控制。
if (QCUtil.isEmpty(maxAge)) {
cookie.setMaxAge(-1);
} else {
cookie.setMaxAge(maxAge);
}
if (QCUtil.isEmpty(path)) {
cookie.setPath("/");
} else {
cookie.setPath(path);
}
// 这两个参数是因为应付漏洞扫描加入的。
// 不允许前端javaScript显性读取
// cookie.setHttpOnly(true);
// 只允许https请求时提交给服务器也就是说http测试环境服务器端读取不到cookie。
// cookie.setSecure(true);
response.addCookie(cookie);
}
/**
* 将InputStream流写入一个File对象中返回
*
* @param inputStream
* @return
* @throws IOException
*/
//public static final File inputStreamToFile(InputStream in, String name) throws IOException {
// if (QCUtil.isEmpty(in)) {
// return null;
// }
// if (QCUtil.isEmpty(name)) {
// name = QCUtil.times() + "";
// }
// File f = new File(name);
// FileUtils.copyInputStreamToFile(in, f);
// return f;
//}
/**
* 判断送入的字符串是否全部为中文
*
* @param name
* 需判断的字符串
* @return 判断结果返回 true为中文 false为非中文
*/
public static final boolean isChinese(String str) {
if (QCUtil.isEmpty(str)) {
return false;
}
str = str.replaceAll("[\u4e00-\u9FFF]", "");
if (QCUtil.isEmpty(str)) {
return true;
}
return false;
}
/**
* 判断一个对象是否为空或者长度为0时返回true否则返回false String:null或length=0返回true
* List,Set,Map:null或size=0返回true 其他null返回true
*
* @param o
* @return
*/
@SuppressWarnings("rawtypes")
public static final boolean isEmpty(Object o) {
if (null == o) {
return true;
}
if (o instanceof String) {
return (0 == ((String) o).trim().length());
}
if (o instanceof List) {
return (0 == ((List) o).size());
}
if (o instanceof Set) {
return (0 == ((Set) o).size());
}
if (o instanceof Map) {
return (0 == ((Map) o).size());
}
if (o instanceof Object[]) {
return (0 == ((Object[]) o).length);
}
return false;
}
/**
* 判断一个对象不为null并且长度不为0时返回true否则返回false 规则参考QCUtil.isEmpty()
*
* @see #isEmpty(Object o)
* @param o
* @return
*/
public static final boolean isNotEmpty(Object o) {
return !isEmpty(o);
}
/**
* 获取非空对象,若空返回对象类型默认值
*
* @param t
* @return
*/
public static final String getNotNull(String t) {
return isEmpty(t) ? new String("") : t;
}
/**
* 获取非空对象,若空返回对象类型默认值
*
* @param t
* @return
*/
public static final Character getNotNull(Character t) {
return isEmpty(t) ? new Character('\0') : t;
}
/**
* 获取非空对象
*
* @param t
* @return
*/
public static final Byte getNotNull(Byte t) {
byte b = 0;
return isEmpty(t) ? b : t;
}
/**
* 获取非空对象,若空返回对象类型默认值
*
* @param t
* @return
*/
public static final Short getNotNull(Short t) {
short s = 0;
return isEmpty(t) ? s : t;
}
/**
* 获取非空对象,若空返回对象类型默认值
*
* @param t
* @return
*/
public static final Integer getNotNull(Integer t) {
return isEmpty(t) ? new Integer(0) : t;
}
/**
* 获取非空对象,若空返回对象类型默认值
*
* @param t
* @return
*/
public static final Long getNotNull(Long t) {
return isEmpty(t) ? new Long(0) : t;
}
/**
* 获取非空对象,若空返回对象类型默认值
*
* @param t
* @return
*/
public static final Float getNotNull(Float t) {
return isEmpty(t) ? new Float(0) : t;
}
/**
* 获取非空对象,若空返回对象类型默认值
*
* @param t
* @return
*/
public static final Double getNotNull(Double t) {
return isEmpty(t) ? new Double(0) : t;
}
/**
* 获取非空对象,若空返回对象类型默认值
*
* @param t
* @return
*/
public static BigDecimal getNotNull(BigDecimal t) {
return isEmpty(t) ? new BigDecimal(0) : t;
}
//
///**
// * 倒序行读文件内容确保文件为UTF-8编码才能显示中文
// *
// * @param filename
// * 文件完整路径(确保文件必须存在并且是文件而不是路径)
// * @param seekIndex
// * 从该字节位置往前读取初始为0输入null时从最后一个字节往前读取
// * @param howManyLineToRead
// * 读取行数
// * @param isNewline
// * 返回的内容是否换行
// * @return 返回指针位置(下标0用于下次继续读取_读取内容(下标1)
// * @throws BusinessException
// */
//public static final List<String> readLineDesc(String filename, Long seekIndex, int howManyLineToRead,
// Boolean isNewline) throws BusinessException {
//
// if (QCUtil.isEmpty(filename)) {
// return null;
// }
//
// if (seekIndex != null && seekIndex <= 0 || howManyLineToRead <= 0) {
// return null;
// }
//
// RandomAccessFile rf = null;
// StringBuffer result = new StringBuffer("");
// List<String> temResult = new ArrayList<String>();
// int lineCount = 0;
// List<String> seekIndex_resultStr = null;
// String r = "";
// if (isNewline) {
// r = "\n";
// }
//
// try {
// rf = new RandomAccessFile(filename, "r");
// // 计算文件指针位置,默认是文件字节数-1即从最后一个字节开始
// long nextend = 0L;
// if (seekIndex == null) {
// // 得到文件最后一个字节的指针,指向该字节下方
// nextend = rf.length() - 1;
// } else {
// nextend = seekIndex;
// }
//
// int c = -1;
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// while (nextend >= 0 && howManyLineToRead > lineCount) {
// rf.seek(nextend);
// // 读取指针指向的字节
// c = rf.read();
// // 如果该字节的ascii码与换行符的ascii码相等
// if ((c == '\n') && nextend != 0) {
// lineCount++;
// String line = QCUtil.trim(new String(byteArrayDesc(out.toByteArray())));
// if (QCUtil.isNotEmpty(line)) {
// temResult.add(line + r);
// }
// out = new ByteArrayOutputStream();
// } else {
// out.write(c);
// }
// if (nextend == 0) {// 当文件指针退至文件开始处,输出第一行
// String line = QCUtil.trim(new String(byteArrayDesc(out.toByteArray())));
// if (QCUtil.isNotEmpty(line)) {
// temResult.add(line + r);
// }
// log.info("Have seek to the first byte.");
// break;
// }
// nextend--;
// }
// seekIndex_resultStr = new ArrayList<String>();
// seekIndex_resultStr.add(nextend + "");
// for (int i = temResult.size() - 1; i >= 0; i--) {
// if (i == 0) {
// result.append(temResult.get(i).trim());
// } else {
// result.append(temResult.get(i));
// }
// }
// seekIndex_resultStr.add(result.toString());
// return seekIndex_resultStr;
// } catch (FileNotFoundException e) {
// throw new BusinessException("Can't locate file " + filename + ",", e);
// } catch (IOException e) {
// throw new BusinessException("Read data from file " + filename + " failed,", e);
// } finally {
// try {
// if (rf != null) {
// rf.close();
// }
// } catch (IOException e) {
// throw new BusinessException("Close file " + filename + " failed,", e);
// }
// }
//}
/**
* 获取当前时间毫秒数
*
* @return
*/
public static final long times() {
return System.currentTimeMillis();
}
/**
* 强化trim()
*
* @param val
* @return
*/
public static final String trim(String val) {
if (isEmpty(val)) {
return "";
} else {
return val.trim();
}
}
/**
* 将File f对象写到服务器本地
*
* @param f
* @param dir
* 服务器本地路径,可以是一个目录路径,也可以是一个文件路径 如果是目录路径,此目录若不存在,程序自动创建
* 如果是文件路径程序会自动创建此文件包括不存在的目录并将File
* f写入此文件中注意文件路径必须有文件后缀否则被认为是目录路径 如果是目录路径文件名是f.getName();
* 如果是文件路径,文件名为路径中指定的文件名;
* 路径如果不存在创建的时候如果此路径为绝对路径那么创建相应的绝对路径如果是相对路径那么相对于用户的user目录参考File
* getAbsolutePath()方法
* @throws IOException
* @throws BusinessException
*/
//public static final void writeFileToLocalDir(File f, String dir) throws IOException, BusinessException {
// if (QCUtil.isEmpty(f)) {
// throw new BusinessException("QCUtil.writeFileToLocalDir()'s File f is null.");
// }
// if (QCUtil.isEmpty(dir)) {
// throw new BusinessException("QCUtil.writeFileToLocalDir()'s File dir is empty.");
// }
// File dirf = new File(dir);
// if (!dirf.exists()) {
// String[] dirArr = dirf.getAbsolutePath().split("\\" + File.separator);
// String lastDir = dirArr[dirArr.length - 1];
// if (!lastDir.contains(".")) {
// dirf = new File(dirf.getAbsolutePath() + File.separator + f.getName());
// }
// } else if (dirf.exists() && dirf.isDirectory()) {
// dirf = new File(dirf.getAbsolutePath() + File.separator + f.getName());
// }
// FileUtils.writeByteArrayToFile(dirf, FileUtils.readFileToByteArray(f));
//}
/**
* 将字符串的首字母变小写
*
* @param s
* @return
*/
public static final String lowerCaseFirstChar(String s) {
if (QCUtil.isEmpty(s)) {
return "";
}
return s.substring(0, 1).toString().toLowerCase() + s.substring(1).toString();
}
/**
* 将字符串的首字母变大写
*
* @param s
* @return
*/
public static final String upperCaseFirstChar(String s) {
if (QCUtil.isEmpty(s)) {
return "";
}
return s.substring(0, 1).toString().toUpperCase() + s.substring(1).toString();
}
/**
* 只要其中一个对象是empty返回true否则返回false
*
* @param o
* @return
*/
public static final boolean isAnyEmpty(Object... o) {
for (int i = 0; i < o.length; i++) {
Object obj = o[i];
if (QCUtil.isEmpty(obj)) {
return true;
}
}
return false;
}
/**
* 所有对象都不为empty返回true否则返回false
*
* @param o
* @return
*/
public static final boolean isNotAnyEmpty(Object... o) {
return !isAnyEmpty(o);
}
/**
* 获取UUID纳秒+uuid用纳秒开头是为了让记录可以使用这个uuid进行排序
*/
public static final String getUUID() {
return System.nanoTime() + UUID.randomUUID().toString().replaceAll("\\-", "");
}
/**
* 使用不可见字符串Constant.unsee0x01将字符串隔开重新组成一串字符串
*
* @param strs
* @return
*/
public static final String joinStringWithUnseeChar(Collection<String> strs) {
return joinStringWithSplitor(strs, String.valueOf((char) 0x01));
}
/**
* 用任何分隔符将字符串容器中的字符串组成一串字符串。
*
* @param strs
* @param splitor
* @return
*/
public static final String joinStringWithSplitor(Collection<String> strs, String splitor) {
if (QCUtil.isEmpty(strs)) {
return "";
}
StringBuffer res = new StringBuffer("");
for (String s : strs) {
res.append(s + splitor);
}
if (QCUtil.isNotEmpty(res.toString())) {
return res.toString().substring(0, res.toString().length() - 1);
}
return res.toString();
}
/**
* 使用不可见字符串Constant.unsee0x01将字符串隔开重新组成一串字符串
*
* @param strs
* @return
*/
public static final String joinStringWithUnseeChar(String[] strs) {
return joinStringWithSplitor(strs, String.valueOf((char) 0x01));
}
/**
* 用任何分隔符将字符串数组中的字符串组成一串字符串。
*
* @param strs
* @param splitor
* @return
*/
public static final String joinStringWithSplitor(String[] strs, String splitor) {
if (QCUtil.isEmpty(strs)) {
return "";
}
StringBuffer res = new StringBuffer("");
for (String s : strs) {
res.append(s + splitor);
}
if (QCUtil.isNotEmpty(res.toString())) {
return res.toString().substring(0, res.toString().length() - 1);
}
return res.toString();
}
/**
* 去除字符串数组中的空串
*
* @param split
* @return
*/
public static final String[] removeEmptyElements(String[] split) {
List<String> l = new ArrayList<String>();
for (String s : split) {
if (QCUtil.isNotEmpty(s)) {
l.add(s);
}
}
String[] res = new String[l.size()];
return l.toArray(res);
}
/**
* 去除队列中为null的元素
*
* @param list
* @return
*/
@SuppressWarnings("unchecked")
public static <T> List<T> removeNull(List<? extends T> list) {
if (QCUtil.isEmpty(list)) {
return (List<T>) list;
}
list.removeAll(Collections.singleton(null));
List<T> res = (List<T>) list;
return res;
}
/**
* 去除队列中为null的元素
*
* @param list
* @return
*/
@SuppressWarnings("unchecked")
public static <T> List<T> removeEmpty(List<? extends T> list) {
if (QCUtil.isEmpty(list)) {
return (List<T>) list;
}
List<T> newList = new ArrayList<T>();
for (T t : list) {
if (QCUtil.isNotEmpty(t)) {
newList.add(t);
}
}
return newList;
}
/**
* 获取文件后缀
*
* @param fileName
* 文件名File对象调用getName();
* @return
*/
public static final String getSuffix(String fileName) {
if (QCUtil.isEmpty(fileName)) {
return "";
}
fileName = getRealFileName(fileName);
return fileName.substring(fileName.lastIndexOf("."));
}
/**
* 获取文件后缀(连后缀的最开始的“.”都不要了)
*
* @param fileName
* 文件名File对象调用getName();
* @return
*/
public static final String getSuffixWithoutDot(String fileName) {
if (QCUtil.isEmpty(fileName)) {
return "";
}
fileName = getRealFileName(fileName);
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
/**
* 获取除掉后缀的文件名
*
* @param fileName
* 文件名File对象调用getName();
* @return
*/
public static final String getFileNameIgnoreSuffix(String fileName) {
if (QCUtil.isEmpty(fileName)) {
return "";
}
fileName = getRealFileName(fileName);
return fileName.substring(0, fileName.lastIndexOf("."));
}
/**
* 获取文件名,有些文件名是一串路径,有些是正确的文件名,这个方法做兼容。
* 比如IE上传到后台接收到的MultipartFile的getOriginalFilename就是一串路径。
*
* @return 最终的文件名
*/
public static final String getRealFileName(String fileName) {
if (fileName.indexOf("/") != -1) {
fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
}
if (fileName.indexOf("\\") != -1) {
fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
}
return fileName;
}
/**
* 删除第一个字符以及最后一个字符
*
* @return
*/
public static final String removeFirstLastChar(String s) {
if (QCUtil.isEmpty(s)) {
return "";
}
return s.substring(1, s.length() - 1);
}
/**
* spring mvc专用下载
*
* @param response
* @param request
* @param name
* 客户端附件下载的名字
* @param b
* 下载数据
* @throws IOException
* @throws BusinessException
*/
//public static final ResponseEntity<byte[]> write(String name, byte[] b) throws IOException, BusinessException {
// try {
// HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// String downloadFileName = new String(name.getBytes(Constant.ENCODING), "iso-8859-1");// 设置编码
// headers.setContentDispositionFormData("attachment", downloadFileName);
// return new ResponseEntity<byte[]>(b, headers, HttpStatus.CREATED);
// } catch (Exception e) {
// throw new BusinessException(e);
// }
//}
/**
* 将Map的value中的String[]变成以Constant.unsee0x01隔开的字符串。 原因是Controller不能传递Map<String,
* String[]>的形式到WS层方法 因为不想做那么复杂当前只支持用j_m_m_xxx传递Map<String, model>
* 的变量所以当分页的时候需要传递的searchParams就是Map<String, String[]>
* 形式的所以需要将Map里面的String[]变成字符串从而整个变量就能使用j_map_xxx来传递
*
* @param j_map_searchParams
* @return
*/
public static Map<String, String> convertMapArrayToStirng(Map<String, Object> j_map_searchParams) {
Map<String, String> res = new HashMap<String, String>();
if (QCUtil.isEmpty(j_map_searchParams)) {
return res;
}
for (Entry<String, Object> en : j_map_searchParams.entrySet()) {
if (QCUtil.isNotEmpty(en.getValue())) {
if (en.getValue() instanceof String[]) {
res.put(en.getKey(), QCUtil.joinStringWithUnseeChar((String[]) en.getValue()));
} else {
res.put(en.getKey(), (String) en.getValue());
}
}
}
return res;
}
/**
* 格式化文件的大小如果小于1024kb直接显示kb如果大于1024kb换算成mb进行显示以此类推。
*
* @param size
* 传一个b为单位的数字
* @return
*/
public static String formatFileSize(long size) {
String fileSize = "";
double kbNum = new BigDecimal(size).divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
if (1024 < kbNum) {
double mbNum = new BigDecimal(kbNum).divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP)
.doubleValue();
if (1024 < mbNum) {
double gbNum = new BigDecimal(mbNum).divide(new BigDecimal(1024), 2, BigDecimal.ROUND_HALF_UP)
.doubleValue();
fileSize = gbNum + "GB";
} else {
fileSize = mbNum + "MB";
}
} else {
fileSize = kbNum + "KB";
}
return fileSize;
}
/**
* 判断字符串中字母的个数
*/
public static int getAlphaCharLength(String str) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) * 1 >= 65 && str.charAt(i) * 1 <= 90
|| str.charAt(i) * 1 >= 97 && str.charAt(i) * 1 <= 122) {
count++;
}
}
return count;
}
/**
* 判断字符串中数字个数
*/
public static int getNumLength(String str) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) * 1 >= 48 && str.charAt(i) * 1 <= 57) {
count++;
}
}
return count;
};
/**
* 判断字符串中特殊字符个数。
*/
public static int getSpecialCharLength(String str) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) * 1 < 48 || str.charAt(i) * 1 > 57 && str.charAt(i) * 1 < 65
|| str.charAt(i) * 1 > 90 && str.charAt(i) * 1 < 97 || str.charAt(i) * 1 > 122) {
count++;
}
}
return count;
};
/**
* 判断字符串是否包含大小写。
*/
public static boolean containBigAndSmall(String str) {
boolean big = false;
boolean small = false;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) * 1 >= 65 && str.charAt(i) * 1 <= 90) {
big = true;
break;
}
}
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) * 1 >= 97 && str.charAt(i) * 1 <= 122) {
small = true;
break;
}
}
if (big && small) {
return true;
}
return false;
}
/**
* 简单混淆字符串中字符。 当前是0位和1位调换最后两位字符调换。
*
* @param str
* @return
*/
public static String confusionStr(String str) {
char[] c = str.toCharArray();
char a = c[1];
c[1] = c[0];
c[0] = a;
a = c[c.length - 1];
c[c.length - 1] = c[c.length - 2];
c[c.length - 2] = a;
return new String(c);
}
/**
* 获取某个范围的随机数。 如获取0-5的随机数minRang:0maxRang:5 如获取5-50的随机数minRang:5maxRang:50
*
* @param minRang
* @param maxRang
* @return
*/
public static int getRandomIntInRang(int minRang, int maxRang) {
Random rand = new Random();
int randNum = rand.nextInt(maxRang + 1) + minRang;
return randNum;
}
/**
* 随机获取a-z0-9中的n个字符作为验证码。
*
* @return
*/
public static String getVerifyCodeChars(int n) {
char[] c = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
int randNum = -1;
char[] resc = new char[n];
for (int i = 0; i < n; i++) {
randNum = getRandomIntInRang(0, 35);
try {
resc[i] = c[randNum];
} catch (Exception e) {
resc[i] = 'p';
continue;
}
}
return new String(resc);
}
/**
* 随机获取0-9中的n个字符作为验证码。一般用作短信验证码时。
*
* @return
*/
public static String getVerifyCodeCharsOnliNum(int n) {
char[] c = new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
int randNum = -1;
char[] resc = new char[n];
for (int i = 0; i < n; i++) {
randNum = getRandomIntInRang(0, 9);
try {
resc[i] = c[randNum];
} catch (Exception e) {
resc[i] = '8';
continue;
}
}
return new String(resc);
}
/**
* 去除空元素后再join
* 和javaScript的数组的join方法作用一样主要用于将数组的元素用指定的连接字符相连成一行字符串
* 放在searchParams中的IN参数中进行查询如["a", "b", 1]→"a,b,1"
*
* @param array
* @param joinStr
* 链接字符串,可以是单个字符,也可以是多个字符的字符串,也可以是空串。
* @return
*/
public static <T> String joinIgnoreEmpty(List<T> array, String joinStr) {
array = removeEmpty(array);
return join(array, joinStr);
}
public static void main(String[] args) {
List<String> s = new ArrayList<String>();
s.add("a");
s.add("b");
s.add("");
s.add("d");
System.out.println(joinIgnoreEmpty(s, ","));
}
/**
* 和javaScript的数组的join方法作用一样主要用于将数组的元素用指定的连接字符相连成一行字符串
* 放在searchParams中的IN参数中进行查询如["a", "b", 1]→"a,b,1"
*
* @param array
* @param joinStr
* 链接字符串,可以是单个字符,也可以是多个字符的字符串,也可以是空串。
* @return
*/
public static <T> String join(List<T> array, String joinStr) {
if (QCUtil.isEmpty(array)) {
return "";
} else {
StringBuffer sb = new StringBuffer("");
for (T o : array) {
String val = "";
if (QCUtil.isNotEmpty(o)) {
val = o.toString();
}
sb.append(val + joinStr);
}
if (QCUtil.isNotEmpty(sb.toString())) {
return sb.toString().substring(0, sb.toString().length() - joinStr.length());
}
}
return "";
}
/**
* 将字符串按照正则匹配分割
*
* */
public static List<String> cut(String str, String regex) {
List<String> list = new ArrayList<String>();
if (QCUtil.isEmpty(regex)) {
return list;
}
String[] ss = str.split(regex);
for (String s : ss) {
list.add(s);
}
return list;
}
/**
* 将字符串按指定分割符切分成多段并转成List
*
* @param string
* @param splitStr
* @return
*/
public static List<String> convertToList(String string, String splitStr) {
List<String> list = new ArrayList<String>();
if (QCUtil.isEmpty(string)) {
return list;
}
String[] strs = string.split(splitStr);
if (QCUtil.isEmpty(strs)) {
return list;
}
for (String str : strs) {
list.add(str);
}
return list;
}
/**
* HTML字符转义
*
* @see 对输入参数中的敏感字符进行过滤替换,防止用户利用JavaScript等方式输入恶意代码
* @see String input = <img src='http://t1.baidu.com/it/fm=0&gp=0.jpg'/>
* @see HtmlUtils.htmlEscape(input); //from spring.jar
* @see StringEscapeUtils.escapeHtml(input); //from commons-lang.jar
* @see 尽管Spring和Apache都提供了字符转义的方法,但Apache的StringEscapeUtils功能要更强大一些
* @see StringEscapeUtils提供了对HTML,Java,JavaScript, SQL ,XML等字符的转义和反转义
* @see 但二者在转义HTML字符时,都不会对单引号和空格进行转义,而本方法则提供了对它们的转义
* @return String 过滤后的字符串
*/
public static String htmlEscape(String input) {
if (isEmpty(input)) {
return input;
}
input = input.replaceAll("&", "&amp;");
input = input.replaceAll("<", "&lt;");
input = input.replaceAll(">", "&gt;");
input = input.replaceAll(" ", "&nbsp;");
input = input.replaceAll("'", "&#39;"); // IE暂不支持单引号的实体名称,而支持单引号的实体编号,故单引号转义成实体编号,其它字符转义成实体名称
input = input.replaceAll("\"", "&quot;"); // 双引号也需要转义,所以加一个斜线对其进行转义
input = input.replaceAll("\n", "<br/>"); // 不能把\n的过滤放在前面因为还要对<和>过滤,这样就会导致<br/>失效了
return input;
}
/**
* Controller端获取searchParams
*
* @param request
* @return
*/
//public static Map<String, Object> getSearchParams(HttpServletRequest request) {
// Map<String, Object> searchParams = WebQCUtil.getParametersStartingWith(request, WebConstant.search);
// return searchParams;
//}
/**
* Controller端获取searchParams (value not empty)
*
* @param request
* @return
*/
//public static Map<String, Object> getSearchParamsNotEmpty(HttpServletRequest request) {
// Map<String, Object> searchParams = getSearchParams(request);
// Map<String, Object> searchParamsCopy = new HashMap<String, Object>(searchParams);
// Set<Entry<String, Object>> entrys = searchParamsCopy.entrySet();
// for (Entry<String, Object> entry : entrys) {
// if (QCUtil.isEmpty(entry.getValue())) {
// searchParams.remove(entry.getKey());
// }
// }
// return searchParams;
//}
/**
* Controller端获取sortParams
*
* @param request
* @return
*/
//public static Map<String, Object> getSortParams(HttpServletRequest request) {
// Map<String, Object> sortParams = WebQCUtil.getParametersStartingWith(request, WebConstant.sort);
// return sortParams;
//}
/**
* Controller端获取sortParams (value not empty)
*
* @param request
* @return
*/
//public static Map<String, Object> getSortParamsNotEmpty(HttpServletRequest request) {
// Map<String, Object> sortParams = getSortParams(request);
// Map<String, Object> sortParamsCopy = new HashMap<String, Object>(sortParams);
// Set<Entry<String, Object>> entrys = sortParamsCopy.entrySet();
// for (Entry<String, Object> entry : entrys) {
// if (QCUtil.isEmpty(entry.getValue())) {
// sortParams.remove(entry.getKey());
// }
// }
// return sortParams;
//}
/**
* java通用下载。如果使用spring mvc框架请用spring mvc的专用下载。
* 将数据写到客户端,供客户下载,比如客户端各种文件附件的下载,以及客户端图片的显示都是用这个方法输出到客户端。
*
* @see #write(String, byte[])
*
* @param response
* @param request
* @param name
* 客户端附件下载的名字
* @param b
* 下载数据
* @throws IOException
* @throws BusinessException
*/
//public static final void write(HttpServletRequest request, HttpServletResponse response, String name, byte[] b)
// throws IOException, BusinessException {
// OutputStream out = null;
// try {
// out = response.getOutputStream();
// response.setContentType("APPLICATION/OCTET-STREAM");
// response.setCharacterEncoding(Constant.ENCODING);
// response.setHeader("Pragma", "public");
// response.setHeader("Cache-Control", "max-age=0");
// String agent = (String) request.getHeader("USER-AGENT");
// if (agent != null && agent.indexOf("MSIE") == -1) {
// // FF
// String enableFileName = "=?" + Constant.ENCODING + "?B?"
// + (new String(Base64.encodeBase64(name.getBytes(Constant.ENCODING)))) + "?=";
// response.setHeader("Content-Disposition", "attachment; filename=" + enableFileName);
// } else {
// // IE
// String enableFileName = new String(name.getBytes("GBK"), "ISO-8859-1");
// response.setHeader("Content-Disposition", "attachment; filename=" + enableFileName);
// }
// out.write(b);
// } catch (Exception e) {
// throw new BusinessException(e);
// } finally {
// IOQCUtil.flush(out);
// IOQCUtil.close(out);
// }
//}
/**
* 从字节数组中的start下标开始包括start)下标获取len个元素返回一个新的数组。
*
* @param b
* @param start
* @param len
* @return
*/
public static byte[] getTargetBytes(byte[] b, int start, int len) {
byte[] newB = new byte[len];
int i = 0;
if (QCUtil.isNotEmpty(b)) {
while (true) {
if (i == len) {
break;
}
newB[i] = b[start];
i++;
start++;
}
}
return newB;
}
/**
* 辅助方法 数组元素 + 前缀 + 分隔符 然后拼接起来 如 参数分别是 [AA,BB,CC], TDD, -- 返回结果是
* TDDAA--TDDBB--TDDCC
*
* @param deviceIds
* @param prefix
* @return
*/
public static <T> String join(List<T> array, String prefix, String joinStr) {
if (array == null || prefix == null || joinStr == null) {
return "";
}
StringBuilder buff = new StringBuilder();
for (int i = 0; i < array.size(); i++) {
if (i == array.size() - 1) {
buff.append(prefix + array.get(i));
} else {
buff.append(prefix + array.get(i) + joinStr);
}
}
return buff.toString();
}
/**
* 拼接sql中的in参数
* @param <T>
* @param array
* @param joinStr
* @return
*/
public static <T> String joinInStr(List<T> array) {
if (QCUtil.isAnyEmpty(array)) {
return "";
}
StringBuilder buff = new StringBuilder();
for (int i = 0; i < array.size(); i++) {
if (QCUtil.isNotEmpty(array.get(i))) {
if (i == array.size() - 1) {
buff.append("'" + array.get(i) + "'");
} else {
buff.append("'" + array.get(i) + "',");
}
}
}
return buff.toString();
}
/**
* 辅助方法 数组元素 + 前缀 然后返回 如 参数分别是 [AA,BB,CC], TDD 返回结果是 [TDDAA,TDDBB,TDDCC]
*
* @param deviceIds
* @param prefix
* @return
*/
@SuppressWarnings("unchecked")
public static <T> List<T> joinPrefix(List<T> array, String prefix) {
if (array == null || prefix == null) {
return new ArrayList<>();
}
List<T> newArray = new ArrayList<T>(array.size());
for (T t : array) {
newArray.add((T) (prefix + t));
}
return newArray;
}
/**
* 从0度开始为正北方
* <p>
* Title: degrees
* </p>
* <p>
* Description:根据角度转化成中文风向16位陆地
* </p>
*
* @param degrees
* @return
* @author dorry
*/
public static String degrees(Double degrees) {
if (348.75 <= degrees && degrees <= 360) {
return "";
} else if (0 <= degrees && degrees <= 11.25) {
return "";
} else if (11.25 < degrees && degrees <= 33.75) {
return "东北偏北";
} else if (33.75 < degrees && degrees <= 56.25) {
return "东北";
} else if (56.25 < degrees && degrees <= 78.75) {
return "东北偏东";
} else if (78.75 < degrees && degrees <= 101.25) {
return "";
} else if (101.25 < degrees && degrees <= 123.75) {
return "东南偏东";
} else if (123.75 < degrees && degrees <= 146.25) {
return "东南";
} else if (146.25 < degrees && degrees <= 168.75) {
return "东南偏南";
} else if (168.75 < degrees && degrees <= 191.25) {
return "";
} else if (191.25 < degrees && degrees <= 213.75) {
return "西南偏南";
} else if (213.75 < degrees && degrees <= 236.25) {
return "西南";
} else if (236.25 < degrees && degrees <= 258.75) {
return "西南偏西";
} else if (258.75 < degrees && degrees <= 281.25) {
return "西";
} else if (281.25 < degrees && degrees <= 303.75) {
return "西北偏西";
} else if (303.75 < degrees && degrees <= 326.25) {
return "西北";
} else if (326.25 < degrees && degrees < 348.75) {
return "西北偏北";
} else {
return "无风";
}
}
/**
* velocity模板得到字符串模板为绝对路径文件
*
* @param data
* @param templateDir
* @return
*/
//public static final String getStringFromVelocityEngineByAbsuluteDir(Map<String, Object> data, String templateDir) {
// File templateFile = new File(templateDir);
// if (!templateFile.exists()) {
// return "";
// }
// VelocityEngine ve = new VelocityEngine();
// Properties p = new Properties();
// p.put(Velocity.FILE_RESOURCE_LOADER_PATH, templateFile.getParent());
// ve.init(p);
// Template t = ve.getTemplate(templateFile.getName(), Constant.ENCODING);
// return getStringFromVelocityEngine(data, t, templateFile);
//}
/**
* velocity模板得到字符串模板为相对路径文件
*
* @param data
* @param templateDir
* @return
*/
//public static final String getStringFromVelocityEngineByRelationDir(Map<String, Object> data, String templateDir) {
// File templateFile = new File(templateDir);
// if (!templateFile.exists()) {
// return "";
// }
// VelocityEngine ve = new VelocityEngine();
// Template t = ve.getTemplate(templateFile.getPath(), Constant.ENCODING);
// return getStringFromVelocityEngine(data, t, templateFile);
//}
/**
* velocity模板得到字符串实现
*
* @param data
* @param t
* @param templateFile
* @return
*/
//private static final String getStringFromVelocityEngine(Map<String, Object> data, Template t, File templateFile) {
// VelocityContext context = new VelocityContext();
// if (!QCUtil.isEmpty(data)) {
// for (Entry<String, Object> e : data.entrySet()) {
// context.put(e.getKey(), e.getValue());
// }
// }
// StringWriter writer = new StringWriter();
// t.merge(context, writer);
// log.debug(String.format("Velocity string generate for template[%s]:\n%s", templateFile.getAbsolutePath(),
// writer.toString()));
// return writer.toString();
//}
/**
* 读取配置文件中的值
* 前提是确认Application.java中读取配置文件的编码是ISO8859-1
* @param env
* @param key
* @return
* @throws UnsupportedEncodingException
*/
public static String getProperty(Environment env, String key) throws UnsupportedEncodingException {
return new String(env.getProperty(key).getBytes("ISO8859-1"), "UTF-8");
}
/**
* 过滤前端参数中的javaScript脚本和html标签防止xss攻击
* @param value
* @return
*/
public static String filterDangerString(String value) {
if (QCUtil.isEmpty(value)) {
return "";
}
value = value.replaceAll("<", "&lt;");
value = value.replaceAll(">", "&gt;");
return value;
}
/**
* 随机生成密钥
*
* @return
*/
public static String getAESRandomKey(int length) {
ArrayList<String> strList = new ArrayList<String>();
int begin = 97;
// 生成小写字母,并加入集合
for (int i = begin; i < begin + 26; i++) {
strList.add((char) i + "");
}
// 生成大写字母,并加入集合
begin = 65;
for (int i = begin; i < begin + 26; i++) {
strList.add((char) i + "");
}
// 将0-9的数字加入集合
for (int i = 0; i < 10; i++) {
strList.add(i + "");
}
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
int size = strList.size();
String randomStr = strList.get(random.nextInt(size));
sb.append(randomStr);
}
return sb.toString();
}
/**
* 将字符串转Integer
* @return
*/
public static Integer getInteger(String val) {
if (QCUtil.isEmpty(val)) {
return 0;
}
val = val.replaceAll("[^\\-0-9]", "");
if (!isNumber(val)) {
return 0;
}
try {
return Integer.parseInt(val);
} catch (Exception e) {
return 0;
}
}
/**
* 判断一个字符串是不是数值型字符串,包括正负小数
* @param content
* @return
*/
public static boolean isNumber(String content) {
if (QCUtil.isEmpty(content)) {
return false;
}
String pattern = "^[\\+\\-]?[\\d]+(\\.[\\d|E]+)?$";
return content.matches(pattern);
}
/**
* 把输入流的内容转化成字符串
*
* @param is
* @return
* @throws IOException
*/
public static String readInputStream(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int length = 0;
byte[] buffer = new byte[1024];
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
is.close();
baos.close();
return baos.toString();
}
}