476 lines
12 KiB
Java
476 lines
12 KiB
Java
|
|
/**
|
|||
|
|
* Copyright © 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
|
|||
|
|
*/
|
|||
|
|
package com.nis.util;
|
|||
|
|
|
|||
|
|
import java.io.UnsupportedEncodingException;
|
|||
|
|
import java.util.List;
|
|||
|
|
import java.util.Locale;
|
|||
|
|
import java.util.regex.Matcher;
|
|||
|
|
import java.util.regex.Pattern;
|
|||
|
|
|
|||
|
|
import javax.servlet.http.HttpServletRequest;
|
|||
|
|
|
|||
|
|
import org.apache.commons.lang3.StringEscapeUtils;
|
|||
|
|
import org.springframework.web.context.request.RequestContextHolder;
|
|||
|
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
|||
|
|
import org.springframework.web.servlet.LocaleResolver;
|
|||
|
|
|
|||
|
|
import com.ckfinder.connector.ServletContextFactory;
|
|||
|
|
import com.google.common.collect.Lists;
|
|||
|
|
import com.nis.web.service.SpringContextHolder;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 字符串工具类, 继承org.apache.commons.lang3.StringUtils类
|
|||
|
|
*
|
|||
|
|
* @author ThinkGem
|
|||
|
|
* @version 2013-05-22
|
|||
|
|
*/
|
|||
|
|
public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
|||
|
|
|
|||
|
|
private static final char SEPARATOR = '_';
|
|||
|
|
private static final String CHARSET_NAME = "UTF-8";
|
|||
|
|
public static final String HASH_ALGORITHM = "SHA-1";
|
|||
|
|
public static final int HASH_INTERATIONS = 1024;
|
|||
|
|
public static final int SALT_SIZE = 8;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 转换为字节数组
|
|||
|
|
*
|
|||
|
|
* @param str
|
|||
|
|
* @return
|
|||
|
|
*/
|
|||
|
|
public static byte[] getBytes(String str) {
|
|||
|
|
if (str != null) {
|
|||
|
|
try {
|
|||
|
|
return str.getBytes(CHARSET_NAME);
|
|||
|
|
} catch (UnsupportedEncodingException e) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 转换为字节数组
|
|||
|
|
*
|
|||
|
|
* @param str
|
|||
|
|
* @return
|
|||
|
|
*/
|
|||
|
|
public static String toString(byte[] bytes) {
|
|||
|
|
try {
|
|||
|
|
return new String(bytes, CHARSET_NAME);
|
|||
|
|
} catch (UnsupportedEncodingException e) {
|
|||
|
|
return EMPTY;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 是否包含字符串
|
|||
|
|
*
|
|||
|
|
* @param str
|
|||
|
|
* 验证字符串
|
|||
|
|
* @param strs
|
|||
|
|
* 字符串组
|
|||
|
|
* @return 包含返回true
|
|||
|
|
*/
|
|||
|
|
public static boolean inString(String str, String... strs) {
|
|||
|
|
if (str != null) {
|
|||
|
|
for (String s : strs) {
|
|||
|
|
if (str.equals(trim(s))) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 替换掉HTML标签方法
|
|||
|
|
*/
|
|||
|
|
public static String replaceHtml(String html) {
|
|||
|
|
if (isBlank(html)) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
String regEx = "<.+?>";
|
|||
|
|
Pattern p = Pattern.compile(regEx);
|
|||
|
|
Matcher m = p.matcher(html);
|
|||
|
|
String s = m.replaceAll("");
|
|||
|
|
return s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 替换为手机识别的HTML,去掉样式及属性,保留回车。
|
|||
|
|
*
|
|||
|
|
* @param html
|
|||
|
|
* @return
|
|||
|
|
*/
|
|||
|
|
public static String replaceMobileHtml(String html) {
|
|||
|
|
if (html == null) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
return html.replaceAll("<([a-z]+?)\\s+?.*?>", "<$1>");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 替换为手机识别的HTML,去掉样式及属性,保留回车。
|
|||
|
|
*
|
|||
|
|
* @param txt
|
|||
|
|
* @return
|
|||
|
|
*/
|
|||
|
|
public static String toHtml(String txt) {
|
|||
|
|
if (txt == null) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
return replace(replace(Encodes.escapeHtml(txt), "\n", "<br/>"), "\t", " ");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 缩略字符串(不区分中英文字符)
|
|||
|
|
*
|
|||
|
|
* @param str
|
|||
|
|
* 目标字符串
|
|||
|
|
* @param length
|
|||
|
|
* 截取长度
|
|||
|
|
* @return
|
|||
|
|
*/
|
|||
|
|
public static String abbr(String str, int length) {
|
|||
|
|
if (str == null) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
StringBuilder sb = new StringBuilder();
|
|||
|
|
int currentLength = 0;
|
|||
|
|
for (char c : replaceHtml(StringEscapeUtils.unescapeHtml4(str)).toCharArray()) {
|
|||
|
|
currentLength += String.valueOf(c).getBytes("GBK").length;
|
|||
|
|
if (currentLength <= length - 3) {
|
|||
|
|
sb.append(c);
|
|||
|
|
} else {
|
|||
|
|
sb.append("...");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return sb.toString();
|
|||
|
|
} catch (UnsupportedEncodingException e) {
|
|||
|
|
e.printStackTrace();
|
|||
|
|
}
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static String abbr2(String param, int length) {
|
|||
|
|
if (param == null) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
StringBuffer result = new StringBuffer();
|
|||
|
|
int n = 0;
|
|||
|
|
char temp;
|
|||
|
|
boolean isCode = false; // 是不是HTML代码
|
|||
|
|
boolean isHTML = false; // 是不是HTML特殊字符,如
|
|||
|
|
for (int i = 0; i < param.length(); i++) {
|
|||
|
|
temp = param.charAt(i);
|
|||
|
|
if (temp == '<') {
|
|||
|
|
isCode = true;
|
|||
|
|
} else if (temp == '&') {
|
|||
|
|
isHTML = true;
|
|||
|
|
} else if (temp == '>' && isCode) {
|
|||
|
|
n = n - 1;
|
|||
|
|
isCode = false;
|
|||
|
|
} else if (temp == ';' && isHTML) {
|
|||
|
|
isHTML = false;
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
if (!isCode && !isHTML) {
|
|||
|
|
n += String.valueOf(temp).getBytes("GBK").length;
|
|||
|
|
}
|
|||
|
|
} catch (UnsupportedEncodingException e) {
|
|||
|
|
e.printStackTrace();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (n <= length - 3) {
|
|||
|
|
result.append(temp);
|
|||
|
|
} else {
|
|||
|
|
result.append("...");
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
// 取出截取字符串中的HTML标记
|
|||
|
|
String temp_result = result.toString().replaceAll("(>)[^<>]*(<?)", "$1$2");
|
|||
|
|
// 去掉不需要结素标记的HTML标记
|
|||
|
|
temp_result = temp_result.replaceAll(
|
|||
|
|
"</?(AREA|BASE|BASEFONT|BODY|BR|COL|COLGROUP|DD|DT|FRAME|HEAD|HR|HTML|IMG|INPUT|ISINDEX|LI|LINK|META|OPTION|P|PARAM|TBODY|TD|TFOOT|TH|THEAD|TR|area|base|basefont|body|br|col|colgroup|dd|dt|frame|head|hr|html|img|input|isindex|li|link|meta|option|p|param|tbody|td|tfoot|th|thead|tr)[^<>]*/?>",
|
|||
|
|
"");
|
|||
|
|
// 去掉成对的HTML标记
|
|||
|
|
temp_result = temp_result.replaceAll("<([a-zA-Z]+)[^<>]*>(.*?)</\\1>", "$2");
|
|||
|
|
// 用正则表达式取出标记
|
|||
|
|
Pattern p = Pattern.compile("<([a-zA-Z]+)[^<>]*>");
|
|||
|
|
Matcher m = p.matcher(temp_result);
|
|||
|
|
List<String> endHTML = Lists.newArrayList();
|
|||
|
|
while (m.find()) {
|
|||
|
|
endHTML.add(m.group(1));
|
|||
|
|
}
|
|||
|
|
// 补全不成对的HTML标记
|
|||
|
|
for (int i = endHTML.size() - 1; i >= 0; i--) {
|
|||
|
|
result.append("</");
|
|||
|
|
result.append(endHTML.get(i));
|
|||
|
|
result.append(">");
|
|||
|
|
}
|
|||
|
|
return result.toString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 转换为Double类型
|
|||
|
|
*/
|
|||
|
|
public static Double toDouble(Object val) {
|
|||
|
|
if (val == null) {
|
|||
|
|
return 0D;
|
|||
|
|
}
|
|||
|
|
try {
|
|||
|
|
return Double.valueOf(trim(val.toString()));
|
|||
|
|
} catch (Exception e) {
|
|||
|
|
return 0D;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 转换为Float类型
|
|||
|
|
*/
|
|||
|
|
public static Float toFloat(Object val) {
|
|||
|
|
return toDouble(val).floatValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 转换为Long类型
|
|||
|
|
*/
|
|||
|
|
public static Long toLong(Object val) {
|
|||
|
|
return toDouble(val).longValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 转换为Integer类型
|
|||
|
|
*/
|
|||
|
|
public static Integer toInteger(Object val) {
|
|||
|
|
return toLong(val).intValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获得i18n字符串
|
|||
|
|
*/
|
|||
|
|
public static String getMessage(String code, Object[] args) {
|
|||
|
|
LocaleResolver localLocaleResolver = (LocaleResolver) SpringContextHolder.getBean(LocaleResolver.class);
|
|||
|
|
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
|
|||
|
|
.getRequest();
|
|||
|
|
Locale localLocale = localLocaleResolver.resolveLocale(request);
|
|||
|
|
return SpringContextHolder.getApplicationContext().getMessage(code, args, localLocale);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获得用户远程地址
|
|||
|
|
*/
|
|||
|
|
public static String getRemoteAddr(HttpServletRequest request) {
|
|||
|
|
String remoteAddr = request.getHeader("X-Real-IP");
|
|||
|
|
if (isNotBlank(remoteAddr)) {
|
|||
|
|
remoteAddr = request.getHeader("X-Forwarded-For");
|
|||
|
|
} else if (isNotBlank(remoteAddr)) {
|
|||
|
|
remoteAddr = request.getHeader("Proxy-Client-IP");
|
|||
|
|
} else if (isNotBlank(remoteAddr)) {
|
|||
|
|
remoteAddr = request.getHeader("WL-Proxy-Client-IP");
|
|||
|
|
}
|
|||
|
|
return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 驼峰命名法工具
|
|||
|
|
*
|
|||
|
|
* @return toCamelCase("hello_world") == "helloWorld"
|
|||
|
|
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
|
|||
|
|
* toUnderScoreCase("helloWorld") = "hello_world"
|
|||
|
|
*/
|
|||
|
|
public static String toCamelCase(String s) {
|
|||
|
|
if (s == null) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
s = s.toLowerCase();
|
|||
|
|
|
|||
|
|
StringBuilder sb = new StringBuilder(s.length());
|
|||
|
|
boolean upperCase = false;
|
|||
|
|
for (int i = 0; i < s.length(); i++) {
|
|||
|
|
char c = s.charAt(i);
|
|||
|
|
|
|||
|
|
if (c == SEPARATOR) {
|
|||
|
|
upperCase = true;
|
|||
|
|
} else if (upperCase) {
|
|||
|
|
sb.append(Character.toUpperCase(c));
|
|||
|
|
upperCase = false;
|
|||
|
|
} else {
|
|||
|
|
sb.append(c);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return sb.toString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 驼峰命名法工具
|
|||
|
|
*
|
|||
|
|
* @return toCamelCase("hello_world") == "helloWorld"
|
|||
|
|
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
|
|||
|
|
* toUnderScoreCase("helloWorld") = "hello_world"
|
|||
|
|
*/
|
|||
|
|
public static String toCapitalizeCamelCase(String s) {
|
|||
|
|
if (s == null) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
s = toCamelCase(s);
|
|||
|
|
return s.substring(0, 1).toUpperCase() + s.substring(1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 驼峰命名法工具
|
|||
|
|
*
|
|||
|
|
* @return toCamelCase("hello_world") == "helloWorld"
|
|||
|
|
* toCapitalizeCamelCase("hello_world") == "HelloWorld"
|
|||
|
|
* toUnderScoreCase("helloWorld") = "hello_world"
|
|||
|
|
*/
|
|||
|
|
public static String toUnderScoreCase(String s) {
|
|||
|
|
if (s == null) {
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
StringBuilder sb = new StringBuilder();
|
|||
|
|
boolean upperCase = false;
|
|||
|
|
for (int i = 0; i < s.length(); i++) {
|
|||
|
|
char c = s.charAt(i);
|
|||
|
|
|
|||
|
|
boolean nextUpperCase = true;
|
|||
|
|
|
|||
|
|
if (i < (s.length() - 1)) {
|
|||
|
|
nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ((i > 0) && Character.isUpperCase(c)) {
|
|||
|
|
if (!upperCase || !nextUpperCase) {
|
|||
|
|
sb.append(SEPARATOR);
|
|||
|
|
}
|
|||
|
|
upperCase = true;
|
|||
|
|
} else {
|
|||
|
|
upperCase = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
sb.append(Character.toLowerCase(c));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return sb.toString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 如果不为空,则设置值
|
|||
|
|
*
|
|||
|
|
* @param target
|
|||
|
|
* @param source
|
|||
|
|
*/
|
|||
|
|
public static void setValueIfNotBlank(String target, String source) {
|
|||
|
|
if (isNotBlank(source)) {
|
|||
|
|
target = source;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 转换为JS获取对象值,生成三目运算返回结果
|
|||
|
|
*
|
|||
|
|
* @param objectString
|
|||
|
|
* 对象串 例如:row.user.id
|
|||
|
|
* 返回:!row?'':!row.user?'':!row.user.id?'':row.user.id
|
|||
|
|
*/
|
|||
|
|
public static String jsGetVal(String objectString) {
|
|||
|
|
StringBuilder result = new StringBuilder();
|
|||
|
|
StringBuilder val = new StringBuilder();
|
|||
|
|
String[] vals = split(objectString, ".");
|
|||
|
|
for (int i = 0; i < vals.length; i++) {
|
|||
|
|
val.append("." + vals[i]);
|
|||
|
|
result.append("!" + (val.substring(1)) + "?'':");
|
|||
|
|
}
|
|||
|
|
result.append(val.substring(1));
|
|||
|
|
return result.toString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 生成安全的密码,生成随机的16位salt并经过1024次 sha-1 hash
|
|||
|
|
*/
|
|||
|
|
public static String entryptPassword(String plainPassword) {
|
|||
|
|
byte[] salt = Digests.generateSalt(SALT_SIZE);
|
|||
|
|
byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
|
|||
|
|
return Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 验证密码
|
|||
|
|
*
|
|||
|
|
* @param plainPassword
|
|||
|
|
* 明文密码
|
|||
|
|
* @param password
|
|||
|
|
* 密文密码
|
|||
|
|
* @return 验证成功返回true
|
|||
|
|
*/
|
|||
|
|
public static boolean validatePassword(String plainPassword, String password) {
|
|||
|
|
byte[] salt = Encodes.decodeHex(password.substring(0, 16));
|
|||
|
|
byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
|
|||
|
|
return password.equals(Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取上传文件的根目录
|
|||
|
|
*
|
|||
|
|
* @return
|
|||
|
|
*/
|
|||
|
|
public static String getUserfilesBaseDir() {
|
|||
|
|
String dir = Configurations.getStringProperty("userfiles.basedir", "");
|
|||
|
|
try {
|
|||
|
|
if (StringUtils.isBlank(dir)) {
|
|||
|
|
dir = ServletContextFactory.getServletContext().getRealPath("/");
|
|||
|
|
} else {
|
|||
|
|
dir = ServletContextFactory.getServletContext().getRealPath("/") + dir;
|
|||
|
|
}
|
|||
|
|
} catch (Exception e) {
|
|||
|
|
return "";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!dir.endsWith("/")) {
|
|||
|
|
dir += "/";
|
|||
|
|
}
|
|||
|
|
return dir;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
*
|
|||
|
|
* <p>
|
|||
|
|
* 判断字符串是否为空. 为空条件:全角\半角\tab 等没有实际意义的字符.
|
|||
|
|
* 具体参看{@link Character#isWhitespace(char)}对空格的定义.
|
|||
|
|
* </p>
|
|||
|
|
*
|
|||
|
|
* <pre>
|
|||
|
|
* StringUtils.isBlank(" ") = true 为半角空格
|
|||
|
|
* StringUtils.isBlank(" ") = true 为全角空格
|
|||
|
|
* StringUtils.isBlank(" ") = true 为tab键
|
|||
|
|
* </pre>
|
|||
|
|
*
|
|||
|
|
* @param str
|
|||
|
|
* 字符串
|
|||
|
|
* @return <code>true<code> 字符串为空 ,<code>false</code> 不为空
|
|||
|
|
*/
|
|||
|
|
public static boolean strIsBlank(String str) {
|
|||
|
|
int strLen;
|
|||
|
|
if (str == null || (strLen = str.length()) == 0) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
for (int i = 0; i < strLen; i++) {
|
|||
|
|
if ((Character.isWhitespace(str.charAt(i)) == false)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|