import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.text.DecimalFormat; import java.text.Format; import java.util.Arrays; 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.BooleanUtils; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.log4j.Logger; import org.springframework.util.DigestUtils; import com.google.common.collect.Lists; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.LocaleResolver; /** * StringTools提供带业务性质的字符串操作 * * @author linxiaoqing * */ @SuppressWarnings("deprecation") public final class StringTools extends org.apache.commons.lang3.StringUtils { private StringTools() { } private static Logger logger = Logger.getLogger(StringTools.class); private static final char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; private static final Format numformat = new DecimalFormat("#.##"); private static final String zeros = "00000000000000000000"; private static final char SEPARATOR = '_'; private static final String CHARSET_NAME = "UTF-8"; /** * 需要进行过滤并替换的sql字符 */ private static final String[][] sqlhandles = { { "'", "''" }, { "\\\\", "\\\\\\\\" } }; /** * 判断某个字符串是否包含在某个数组中。如果数组为null则返回false * * @param str * @param array * @return */ public static boolean isContainsString(String str, String[] array) { if (array == null) { return false; } for (String s : array) { if (s.equals(str)) { return true; } } return false; } public static String listingString(Object data) { return listingString(data, true); } /** * 把对象解析成[1,1,2] 这种格式 * * @param data * 对象数据 * @param snapped * 空值默认是否中断 * @return */ public static String listingString(Object data, boolean snapped) { StringBuilder sb = new StringBuilder(100); sb.append(data.getClass().getSimpleName()).append("["); try { boolean flag = false; boolean isstring = true; Object obj = null; String str = ""; for (java.lang.reflect.Method m : data.getClass().getDeclaredMethods()) { if ((m.getName().startsWith("get") || m.getName().startsWith("is")) && m.getParameterTypes().length == 0) { int l = m.getName().startsWith("get") ? 3 : 2; obj = m.invoke(data); if (snapped && obj == null) continue; isstring = obj instanceof String; if (!isstring && snapped) { if (obj instanceof Number && ((Number) obj).intValue() == 0) continue; if (obj instanceof Boolean && ((Boolean) obj) == false) continue; } str = isstring ? ("\"" + obj + "\"") : String.valueOf(obj); if (flag) sb.append(", "); sb.append(m.getName().substring(l).toLowerCase()).append("=").append(str); flag = true; } } } catch (Exception e) { logger.error(e); } sb.append("]"); return sb.toString(); } /** * 截取前几个字符,超过加……,不足全部截取 * * @param t * @param size * @return */ public static String subString(String t, int size) { if (t == null) return null; int hansize = size * 3 / 2; int len = hansize; if (t.length() > size) { int p = 0; for (int i = 0; i < hansize && i < t.length(); i++) { if (t.charAt(i) > 127) p++; } len -= p * 2 / 3; if (len < size) len = size; if (t.length() <= len) return t; return t.substring(0, len) + "..."; } return t; } /** * 返回全局唯一序列号,模拟Sql Server的newid()函数功能 */ public static String createSequence() { return java.util.UUID.randomUUID().toString().replace("-", ""); } /** * 转换成用B,KB,MB,GB,TB单位来表示的大小 */ public static String formatFileLength(long sizes) { if (sizes < 0) sizes = 0; String str = ""; if (sizes < 1024) { // 小于1KB str += "" + sizes + "B"; } else if (sizes < 1024 * 1024) { // 小于1MB str += "" + numformat.format(sizes / 1024.0) + "K"; } else if (sizes < 1024 * 1024 * 1024) { // 小于1GB str += "" + numformat.format(sizes / (1024 * 1024.0)) + "M"; } else if (sizes < 1024 * 1024 * 1024 * 1024L) { // 小于1TB str += "" + numformat.format(sizes / (1024 * 1024 * 1024.0)) + "G"; } else { // 大于1TB str += "" + numformat.format(sizes / (1024 * 1024 * 1024 * 1024.0)) + "T"; } for (int i = 0; i < 8 - str.length(); i++) { str = " " + str; } return str; } /** * 把指定byte数组转换成16进制的字符串 */ public static String toHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); for (byte b : bytes) { sb.append(hex[((b >> 4) & 0xF)]).append(hex[((b >> 0) & 0xF)]); } return sb.toString(); } /** * 把指定16进制的字符串转换成byte数组 */ public static byte[] hexStringToBytes(String inString) { int fromLen = inString.length(); int toLen = (fromLen + 1) / 2; final byte[] b = new byte[toLen]; for (int i = 0; i < toLen; i++) { b[i] = (byte) hexPairToInt(inString.substring(i * 2, (i + 1) * 2)); } return b; } /** * 将数组进行排序然后再组成字符串 * * @param totalStringList * @return */ public static String ArrayToSortString(List<String> totalStringList) { StringBuffer str = new StringBuffer(""); if (totalStringList != null && totalStringList.size() > 0) { String[] strs = totalStringList.toArray(new String[totalStringList.size()]); Arrays.sort(strs); for (String s : strs) { str.append(s); } } return str.toString(); } /** * 把指定cid字符串转换成byte数组 */ public static byte[] convertStringCid2Bytes(String sCid) { byte[] cid = new byte[20]; for (int i = 0; i < cid.length; i++) { cid[i] = (byte) Integer.parseInt(sCid.substring(i * 2, i * 2 + 2), 16); } return cid; } /** * 在指定字符串数组里查找指定字符串,找到则返回索引号,找不到返回-1 */ public static int search(String no, String[] noes) { for (int i = 0; i < noes.length; i++) { if (no.equals(noes[i])) return i; } return -1; } /** * 计算字符串由多少16进制组成 * * @param inString * @return */ private static int hexPairToInt(String inString) { String digits = "0123456789abcdef"; String s = inString.toLowerCase(); int n = 0; int thisDigit = 0; int sLen = s.length(); if (sLen > 2) sLen = 2; for (int i = 0; i < sLen; i++) { thisDigit = digits.indexOf(s.substring(i, i + 1)); if (thisDigit < 0) throw new NumberFormatException(); if (i == 0) thisDigit *= 0x10; n += thisDigit; } return n; } /** * 输入流转成指定字符集字符串 * * @param in * 输入流 * @param charset * 字符集 * @return * @throws IOException */ public static String read(InputStream in, String charset) throws IOException { int pos = -1; byte[] buf = new byte[1024 * 8]; ByteArrayOutputStream out = new ByteArrayOutputStream(); while ((pos = in.read(buf)) != -1) { out.write(buf, 0, pos); } return (charset == null) ? new String(out.toByteArray()) : new String(out.toByteArray(), charset); } public static String read(InputStream in) throws IOException { return read(in, null); } /** * 转换成js代码 */ public static final String escapeJs(String unicode) { return org.apache.commons.lang.StringEscapeUtils.escapeJavaScript(unicode); } /** * 对字符进行URL编码。客户端使用js的decodeURIComponent进行解码 * * @param str * 字符串源码 * @return URL编码后的字符串 */ public static String encodeURL(String str) { try { return java.net.URLEncoder.encode(str, "utf-8").replaceAll("\\+", "%20"); } catch (Exception ex) { return ""; } } /** * 对url进行解码 * * @param str * @return */ public static String decodeURL(String str) { try { return java.net.URLDecoder.decode(str, "utf-8"); } catch (Exception ex) { return ""; } } /** * 转换成html代码 */ public static final String escapeHtml(String unicode) { return org.apache.commons.lang.StringEscapeUtils.escapeHtml(unicode); } /** * 判断字符串是否为空 */ public static boolean isEmpty(String str) { return str == null || str.trim().isEmpty(); } /** * 判断字符串是否为非空 */ public static boolean isNotEmpty(String str) { return str != null && !str.trim().isEmpty(); } /** * 将字符串中可能包含有非法的sql字符进行过滤,例如过滤'。 * * @param str * 需要进行过滤的字符串 * @return 过滤后的安全字符串 */ public static final String escapeSql(String str) { if (str == null) { return ""; } for (String[] ss : sqlhandles) { str = str.replaceAll(ss[0], ss[1]); } return str; } /** * 将数值转换成特定长度的字符串 * * @param value * @param length * @return */ public static String toLenString(long value, int length) { String val = value + ""; if (val.length() > length) { try { throw new Exception("定义的长度小于数值的长度。"); } catch (Exception e) { logger.error(e); } } if (val.length() < length) { return zeros.substring(0, length - val.length()) + val; } else { return val; } } /** * 将字符串中可能包含有非法的sql字符进行过滤,例如过滤'。 * * @param obj * 过滤对象 * @return 过滤后的安全字符串 */ public static final String escapeSql(Object obj) { if (obj == null) { return ""; } return escapeSql(obj.toString()); } /** * 将对象安全转换成int类型,失败时返回0 * * @param o * 目标对象 * @return int数字 */ public static int safeToInt(Object o) { int rs = 0; try { rs = Integer.parseInt(o.toString()); } catch (Exception ex) { rs = 0; } return rs; } /** * 将对象安全转换成short类型 * * @param o * 目标对象 * @return short数字 */ public static int safeToShort(Object o) { short rs = 0; try { rs = Short.parseShort(o.toString()); } catch (Exception ex) { rs = 0; } return rs; } /** * 将对象安全转换成long类型 * * @param o * 目标对象 * @return long数字 */ public static long safeToLong(Object o) { long rs = 0; try { rs = Long.parseLong(o.toString()); } catch (Exception ex) { rs = 0; } return rs; } /** * 将对象安全转换成double类型 * * @param o * 目标对象 * @return double数字 */ public static double safeToDouble(Object o) { double rs = 0; try { rs = Double.parseDouble(o.toString()); } catch (Exception ex) { rs = 0; } return rs; } /** * 得到系统的时间戳 */ public static String getTradeSn() { return "" + new java.util.Date().getTime(); } /** * 尝试将对象转换成double类型,如果失败时也不抛出异常而返回0 * * @param fieldValue * @return */ public static double tryParseDouble(Object fieldValue) { try { double rs = (Double) fieldValue; return rs; } catch (Exception ex) { try { return Double.parseDouble(fieldValue.toString()); } catch (Exception exx) { return 0; } } } /** * 用md5算法对字符串进行加密 * * @param source * @param key * @return */ public static String encodeByMD5(String source, String key) { if (source == null) return null; try { return DigestUtils.md5DigestAsHex((source + key).getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { return ""; } } /** * 将手机号码中的中间四位转换成* * * @param src * @return */ public static String phoneChange(String src) { if (src == null || src.trim().length() <= 0) { return ""; } StringBuffer tempStr = new StringBuffer(); int srcLength = src.length(); for (int i = 0; i < srcLength; i++) { if (i > 2 && i < 7) { tempStr.append("*"); } else { tempStr.append(src.charAt(i)); } } return tempStr.toString(); } /** * 将银行卡号限前4后3中间用****填充 * * * @param src * @return */ public static String bankNoChange(String src) { if (src == null || src.trim().length() <= 0) { return ""; } return src.substring(0, 4) + "****" + src.substring(src.length() - 3, src.length()); } /** * 将真实姓名限前**后1个名字 * * * @param src * @return */ public static String realNameChange(String src) { if (src == null || src.trim().length() <= 0) { return ""; } return "**" + src.charAt(src.length() - 1); } /** * 将人名按长度前面用**显示 * * @param src * @return */ public static String PayeeNameChange(String src) { if (src == null || src.trim().length() <= 0) { return ""; } StringBuffer mark = new StringBuffer(""); if (src.trim().length() > 7) { for (int i = 0; i < src.trim().length() - 4; i++) { mark.append("*"); } return src.substring(0, 4) + mark; } if (src.trim().length() > 3) { for (int i = 0; i < src.trim().length() - 2; i++) { mark.append("*"); } return src.substring(0, 2) + mark; } if (src.trim().length() > 1) { for (int i = 0; i < src.trim().length() - 1; i++) { mark.append("*"); } return src.substring(0, 1) + mark; } return src.substring(0, 1) + "*"; } /** * 将身份证号限前4后4中间用****填充 * * * @param src * @return */ public static String idCardChange(String src) { if (src == null || src.trim().length() <= 0) { return ""; } return src.substring(0, 4) + "****" + src.substring(src.length() - 4, src.length()); } /** * 将email限前4后4中间用****填充 * * * @param src * @return */ public static String emailChange(String src) { if (src == null || src.trim().length() <= 0) { return ""; } return src.substring(0, 4) + "****" + src.substring(src.length() - 4, src.length()); } /** * 校验E-mail格式是否正确,为空时返回false.<br/> * * @param mail * 要校验的E-mail. * @return true or false . */ public static boolean isEmail(String email) { String regex = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$"; Pattern p = Pattern.compile(regex); Matcher m = p.matcher(email); return m.find(); } /** * 去除html代码(HTML过滤还可以使用jsoup工具包进行处理). * * @param inputString * 含html标签的字符串 . * @return 文本字符串 . */ public static String htmlToText(String inputString) { String htmlStr = inputString; // 含html标签的字符串 try { // 定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script> String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; // 定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style> String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>"; String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式 String patternStr = "\\s+"; // 过滤script标签 Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE); Matcher m_script = p_script.matcher(htmlStr); htmlStr = m_script.replaceAll(""); // 过滤style标签 Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE); Matcher m_style = p_style.matcher(htmlStr); htmlStr = m_style.replaceAll(""); // 过滤html标签 Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE); Matcher m_html = p_html.matcher(htmlStr); htmlStr = m_html.replaceAll(""); // 过滤空格 Pattern p_ba = Pattern.compile(patternStr, Pattern.CASE_INSENSITIVE); Matcher m_ba = p_ba.matcher(htmlStr); htmlStr = m_ba.replaceAll(""); } catch (Exception e) { throw new RuntimeException(e); } return htmlStr; // 返回文本字符串 } /** * 转换为字节数组 * * @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; } } /** * 转换为Boolean类型 'true', 'on', 'y', 't', 'yes' or '1' (case insensitive) will * return true. Otherwise, false is returned. */ public static Boolean toBoolean(final Object val) { if (val == null) { return false; } return BooleanUtils.toBoolean(val.toString()) || "1".equals(val.toString()); } /** * 转换为字节数组 * * @param str * @return */ public static String toString(byte[] bytes) { try { return new String(bytes, CHARSET_NAME); } catch (UnsupportedEncodingException e) { return EMPTY; } } /** * 如果对象为空,则使用defaultVal值 see: ObjectUtils.toString(obj, defaultVal) * * @param obj * @param defaultVal * @return */ public static String toString(final Object obj, final String defaultVal) { return obj == null ? defaultVal : obj.toString(); } /** * 是否包含字符串 * * @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(ZoeEncodeUtils.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(); } /** * 转换为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(); } }