1555 lines
40 KiB
Java
1555 lines
40 KiB
Java
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保留时间,单位秒。负值标识浏览器关闭即删除cookie,0表示马上删除。
|
||
// 这里设置成一年,如果想控制登录超时,可以用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:0,maxRang:5, 如获取5-50的随机数,minRang:5,maxRang: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-z,0-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("&", "&");
|
||
input = input.replaceAll("<", "<");
|
||
input = input.replaceAll(">", ">");
|
||
input = input.replaceAll(" ", " ");
|
||
input = input.replaceAll("'", "'"); // IE暂不支持单引号的实体名称,而支持单引号的实体编号,故单引号转义成实体编号,其它字符转义成实体名称
|
||
input = input.replaceAll("\"", """); // 双引号也需要转义,所以加一个斜线对其进行转义
|
||
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("<", "<");
|
||
value = value.replaceAll(">", ">");
|
||
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();
|
||
}
|
||
|
||
}
|