Commit 8bdd2e20 by xupeng

init project

parent 60d8f5e5
...@@ -2,4 +2,47 @@ ...@@ -2,4 +2,47 @@
main/info.log main/info.log
main/test.go main/test.go
main/suggest-task main/suggest-task
main/suggest-task.exe main/suggest-task.exe
\ No newline at end of file
# Compiled class file
**/target
**/*.class
**/.classpath
**/.settings
**/.project
**/.idea
**/.vscode
**/*.iml
**/.DS_Store
**/node_modules
**/dist
*.suo
*.ntvs*
*.njsproj
*.sln
*.sublime-project
*.sublime-workspace
**/coverage
**/test/unit/coverage/
**/test/e2e/reports/
# Log file
*.log
**/*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
**/hs_err_pid*
\ No newline at end of file
<assembly>
<id>dependency</id>
<formats>
<format>jar</format>
</formats>
<!-- 压缩包下是否生成和项目名相同的根目录-->
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<!-- 是否把当前项目的输出jar包并使用,true则会把当前项目输出为jar包到输出目录,false不输出 -->
<useProjectArtifact>false</useProjectArtifact>
<!-- 是否解压依赖包 -->
<unpack>true</unpack>
<scope>system</scope>
</dependencySet>
<dependencySet>
<!-- 是否解压依赖包 -->
<unpack>true</unpack>
<!-- 将scope为runtime的依赖包打包 -->
<scope>runtime</scope>
<excludes>
</excludes>
<includes>
</includes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>
\ No newline at end of file
#!/usr/bin/env bash
java -cp so-suggest-task-1.0-SNAPSHOT.jar com.secoo.so.suggest.task.SuggestTask
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.secoo.so</groupId>
<artifactId>so-suggest-task</artifactId>
<version>1.0-SNAPSHOT</version>
<name>so-suggest-task</name>
<profiles>
<profile>
<id>prod</id>
<build>
<resources>
<resource>
<directory>src/main/profiles/prod</directory>
</resource>
</resources>
</build>
</profile>
<profile>
<id>test</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<resources>
<resource>
<directory>src/main/profiles/test</directory>
</resource>
</resources>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>com.secoo.search.third-patry</groupId>
<artifactId>third-patry-jpinyin</artifactId>
<version>1.1.8</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- 打成 withDependencies jar 包-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<!-- not append assembly id in release file name -->
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package com.secoo.so.suggest.config;
import com.alibaba.fastjson.JSON;
import com.secoo.so.suggest.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@Slf4j
public class ConfigUtil {
private static final String CONFIG_FILE = "config.properties";
private static ConfigUtil INST;
private Properties prop;
private ConfigUtil() {
prop = load();
}
public synchronized static void init() {
ConfigUtil configUtil = new ConfigUtil();
INST = configUtil;
}
private Properties load() {
Properties tmp = new Properties();
try {
log.info(this.getClass().getClassLoader().getResource(CONFIG_FILE).getPath());
tmp.load(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream(CONFIG_FILE), "UTF-8"));
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return tmp;
}
public static void printAll() {
if (INST == null) {
init();
}
log.info("[" + CONFIG_FILE + "] =============== start print config properties ===============");
if (INST != null && INST.prop != null) {
for (Map.Entry<Object, Object> entry : INST.prop.entrySet()) {
log.info("[" + CONFIG_FILE + "] " + entry.getKey() + "=" + entry.getValue());
}
}
log.info("[" + CONFIG_FILE + "] =============== end print config properties ===============");
}
public static String getString(String key) {
if (INST == null) {
init();
}
return INST.prop.getProperty(key);
}
public static String getString(String key, String defaultValue) {
String val = getString(key);
if (val == null) {
return defaultValue;
}
return val;
}
public static int getInt(String key, int defaultValue) {
String val = getString(key);
if (val != null) {
try {
return Integer.parseInt(val);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
return defaultValue;
}
private static List<String> prefixFilterList = null;
public static List<String> getPrefixFilterList() {
if (prefixFilterList == null) {
String val = getString("prefix_filter_list");
if (StringUtils.isNotBlank(val)) {
prefixFilterList = JSON.parseArray(val, String.class);
}
prefixFilterList = new ArrayList<>();
}
return prefixFilterList;
}
}
package com.secoo.so.suggest.db;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbcp.BasicDataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
@Slf4j
public class DwDataSource {
private DwDataSource() {
}
private static class DataSourceHolder {
private static BasicDataSource dataSource = new BasicDataSource();
static {
Properties prop = new Properties();
try {
prop.load(DwDataSource.class.getClassLoader().getResourceAsStream("db.properties"));
} catch (IOException e) {
log.error("init config error", e);
}
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(prop.getProperty("dw.read.url"));
dataSource.setUsername(prop.getProperty("dw.read.user"));
dataSource.setPassword(prop.getProperty("dw.read.password"));
dataSource.setTestWhileIdle(true);
dataSource.setTestOnReturn(true);
dataSource.setTimeBetweenEvictionRunsMillis(30000);
dataSource.setMaxActive(30);
dataSource.setTestOnBorrow(true);
dataSource.setValidationQuery("select 1 from dual");
}
}
public static Connection getConnection() {
try {
return DataSourceHolder.dataSource.getConnection();
} catch (SQLException e) {
log.error("获取链接异常", e);
throw new RuntimeException("获取链接异常:" + e.getMessage(), e);
}
}
public static void close() {
try {
DataSourceHolder.dataSource.close();
} catch (SQLException e) {
log.error("close error", e);
}
}
}
package com.secoo.so.suggest.db;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbcp.BasicDataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
@Slf4j
public class ErpDataSource {
private ErpDataSource() {
}
private static class DataSourceHolder {
private static BasicDataSource dataSource = new BasicDataSource();
static {
Properties prop = new Properties();
try {
prop.load(ErpDataSource.class.getClassLoader().getResourceAsStream("db.properties"));
} catch (IOException e) {
log.error("init config error", e);
}
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(prop.getProperty("erp.read.url"));
dataSource.setUsername(prop.getProperty("erp.read.user"));
dataSource.setPassword(prop.getProperty("erp.read.password"));
dataSource.setTestWhileIdle(true);
dataSource.setTestOnReturn(true);
dataSource.setTimeBetweenEvictionRunsMillis(30000);
dataSource.setMaxActive(30);
dataSource.setTestOnBorrow(true);
dataSource.setValidationQuery("select 1 from dual");
}
}
public static Connection getConnection() {
try {
return DataSourceHolder.dataSource.getConnection();
} catch (SQLException e) {
log.error("获取链接异常", e);
throw new RuntimeException("获取链接异常:" + e.getMessage(), e);
}
}
public static void close() {
try {
DataSourceHolder.dataSource.close();
} catch (SQLException e) {
log.error("close error", e);
}
}
}
package com.secoo.so.suggest.db;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.dbcp.BasicDataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
@Slf4j
public class SeoDataSource {
private SeoDataSource() {
}
private static class DataSourceHolder {
private static BasicDataSource dataSource = new BasicDataSource();
static {
Properties prop = new Properties();
try {
prop.load(ErpDataSource.class.getClassLoader().getResourceAsStream("db.properties"));
} catch (IOException e) {
log.error("init config error", e);
}
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl(prop.getProperty("seo.read.url"));
dataSource.setUsername(prop.getProperty("seo.read.user"));
dataSource.setPassword(prop.getProperty("seo.read.password"));
dataSource.setTestWhileIdle(true);
dataSource.setTestOnReturn(true);
dataSource.setTimeBetweenEvictionRunsMillis(30000);
dataSource.setMaxActive(30);
dataSource.setTestOnBorrow(true);
dataSource.setValidationQuery("select 1 from dual");
}
}
public static Connection getConnection() {
try {
return DataSourceHolder.dataSource.getConnection();
} catch (SQLException e) {
log.error("获取链接异常", e);
throw new RuntimeException("获取链接异常:" + e.getMessage(), e);
}
}
public static void close() {
try {
DataSourceHolder.dataSource.close();
} catch (SQLException e) {
log.error("close error", e);
}
}
}
package com.secoo.so.suggest.db;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SuggestTaskDao {
private static final Logger log = LoggerFactory.getLogger(SuggestTaskDao.class);
/**
* 查询
*/
// public static List<SearchRelateHotWordInfo> querySearchRelateInfo(SearchRelateHotWordInfo relateHotWordInfo){
// List<SearchRelateHotWordInfo> searchRelateHotWordInfoList = Lists.newArrayList();
// if (relateHotWordInfo == null){
// return searchRelateHotWordInfoList;
// }
// String brandCategoryId = relateHotWordInfo.getBrandCategoryId();
// if (StringUtils.isBlank(brandCategoryId)){
// return searchRelateHotWordInfoList;
// }
// Connection conn = SEODataSource.getConnection();
// PreparedStatement stmt = null;
// ResultSet rs = null;
// String sql = "SELECT category_code,category_code_name,brand_id,brand_name,brand_category_id FROM secooSeoDB.t_search_relate_hot_word WHERE brand_category_id =? and is_del = 0";
// try {
// stmt = conn.prepareStatement(sql);
// stmt.setString(1, brandCategoryId);
// rs = stmt.executeQuery();
// while (rs.next()){
// SearchRelateHotWordInfo searchRelateHotWordInfo = new SearchRelateHotWordInfo();
// String brandCategoryIdStr = rs.getString("brand_category_id");
// if (StringUtils.isBlank(brandCategoryIdStr)){
// continue;
// }
// searchRelateHotWordInfo.setBrandCategoryId(brandCategoryIdStr);
// searchRelateHotWordInfoList.add(searchRelateHotWordInfo);
// }
// }catch (Exception e){
// log.error("querySearchRelateInfo select exception", e);
// }finally {
// DBConnection.close(conn, stmt, rs);
// }
// return searchRelateHotWordInfoList;
// }
}
package com.secoo.so.suggest.helper;
import com.secoo.so.suggest.db.ErpDataSource;
import com.secoo.so.suggest.util.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Set;
/**
* 加载敏感词汇
*/
public class AdvWordsHelper {
private static final Logger LOG = LoggerFactory.getLogger(AdvWordsHelper.class);
/**
* 敏感词key
*/
public static final String ADV_WORDS = "so.advWords";
/**
* 汉字匹配
*/
public static final String regEx1 = "[\\u4e00-\\u9fa5]";
private static final String SENSITIVE_SQL = "SELECT sensitive_words FROM t_sensitive_info WHERE status=1 and del_flag=0";
/**
* 获取敏感词
*/
public static String getAdvWords() {
Connection conn = ErpDataSource.getConnection();
Statement stmt = null;
ResultSet rs = null;
Set<String> advWordSet = new HashSet<>();
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(SENSITIVE_SQL);
while (rs.next()) {
String sensitiveWord = rs.getString(1);
if (StringUtils.isNotEmpty(sensitiveWord.trim())) {
advWordSet.add(sensitiveWord);
}
}
} catch (Exception e) {
LOG.error("获取敏感词异常: " + e.getMessage(), e);
} finally {
ObjectUtils.safeClose(conn, stmt, rs);
}
if (advWordSet.size() > 0) {
return StringUtils.join(advWordSet, ",");
}
return null;
}
}
package com.secoo.so.suggest.task;
import com.secoo.so.suggest.config.ConfigUtil;
import lombok.extern.slf4j.Slf4j;
/**
* 初始化suggest搜索词到es索引
*/
@Slf4j
public class SuggestTask {
public static void main(String[] args) {
long start = System.currentTimeMillis();
log.info(">>>>>>>>>>>> start run SuggestTask");
// 初始化配置信息
ConfigUtil.init();
ConfigUtil.printAll();
log.info("<<<<<<<<<<<< end run SuggestTask, cost: {}ms", (System.currentTimeMillis() - start));
}
}
package com.secoo.so.suggest.util;
import java.util.*;
/**
* Created with IntelliJ IDEA. User: Administrator Date: 13-11-11 Time: 下午12:24
* To change this template use File | Settings | File Templates.
*/
public abstract class CollectionUtils {
/**
* Return <code>true</code> if the supplied Collection is <code>null</code>
* or empty. Otherwise, return <code>false</code>.
*
* @param collection the Collection to check
* @return whether the given Collection is empty
*/
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Collection collection) {
return (collection == null || collection.isEmpty());
}
@SuppressWarnings("rawtypes")
public static boolean isNotEmpty(Collection collection) {
return (collection != null && !collection.isEmpty());
}
/**
* Return <code>true</code> if the supplied Map is <code>null</code> or
* empty. Otherwise, return <code>false</code>.
*
* @param map the Map to check
* @return whether the given Map is empty
*/
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Map map) {
return (map == null || map.isEmpty());
}
@SuppressWarnings("rawtypes")
public static boolean isNotEmpty(Map map) {
return (map != null && !map.isEmpty());
}
/**
* Convert the supplied array into a List. A primitive array gets converted
* into a List of the appropriate wrapper type.
* <p>
* A <code>null</code> source value will be converted to an empty List.
*
* @param source the (potentially primitive) array
* @return the converted List result
*/
@SuppressWarnings("rawtypes")
public static List arrayToList(Object source) {
return Arrays.asList(ObjectUtils.toObjectArray(source));
}
/**
* Merge the given array into the given Collection.
*
* @param array the array to merge (may be <code>null</code>)
* @param collection the target Collection to merge the array into
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static void mergeArrayIntoCollection(Object array, Collection collection) {
if (collection == null) {
throw new IllegalArgumentException("Collection must not be null");
}
Object[] arr = ObjectUtils.toObjectArray(array);
for (Object elem : arr) {
collection.add(elem);
}
}
/**
* Merge the given Properties instance into the given Map, copying all
* properties (key-value pairs) over.
* <p>
* Uses <code>Properties.propertyNames()</code> to even catch default
* properties linked into the original Properties instance.
*
* @param props the Properties instance to merge (may be <code>null</code>)
* @param map the target Map to merge the properties into
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public static void mergePropertiesIntoMap(Properties props, Map map) {
if (map == null) {
throw new IllegalArgumentException("Map must not be null");
}
if (props != null) {
for (Enumeration en = props.propertyNames(); en.hasMoreElements(); ) {
String key = (String) en.nextElement();
Object value = props.getProperty(key);
if (value == null) {
// Potentially a non-String value...
value = props.get(key);
}
map.put(key, value);
}
}
}
/**
* Check whether the given Iterator contains the given element.
*
* @param iterator the Iterator to check
* @param element the element to look for
* @return <code>true</code> if found, <code>false</code> else
*/
@SuppressWarnings("rawtypes")
public static boolean contains(Iterator iterator, Object element) {
if (iterator != null) {
while (iterator.hasNext()) {
Object candidate = iterator.next();
if (ObjectUtils.nullSafeEquals(candidate, element)) {
return true;
}
}
}
return false;
}
/**
* Check whether the given Enumeration contains the given element.
*
* @param enumeration the Enumeration to check
* @param element the element to look for
* @return <code>true</code> if found, <code>false</code> else
*/
@SuppressWarnings("rawtypes")
public static boolean contains(Enumeration enumeration, Object element) {
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
Object candidate = enumeration.nextElement();
if (ObjectUtils.nullSafeEquals(candidate, element)) {
return true;
}
}
}
return false;
}
/**
* Check whether the given Collection contains the given element instance.
* <p>
* Enforces the given instance to be present, rather than returning
* <code>true</code> for an equal element as well.
*
* @param collection the Collection to check
* @param element the element to look for
* @return <code>true</code> if found, <code>false</code> else
*/
@SuppressWarnings("rawtypes")
public static boolean containsInstance(Collection collection, Object element) {
if (collection != null) {
for (Object candidate : collection) {
if (candidate == element) {
return true;
}
}
}
return false;
}
/**
* Return <code>true</code> if any element in '<code>candidates</code>' is
* contained in ' <code>source</code>'; otherwise returns
* <code>false</code>.
*
* @param source the source Collection
* @param candidates the candidates to search for
* @return whether any of the candidates has been found
*/
@SuppressWarnings("rawtypes")
public static boolean containsAny(Collection source, Collection candidates) {
if (isEmpty(source) || isEmpty(candidates)) {
return false;
}
for (Object candidate : candidates) {
if (source.contains(candidate)) {
return true;
}
}
return false;
}
/**
* Return the first element in '<code>candidates</code>' that is contained
* in '<code>source</code> '. If no element in '<code>candidates</code>' is
* present in '<code>source</code>' returns <code>null</code>. Iteration
* order is {@link Collection} implementation specific.
*
* @param source the source Collection
* @param candidates the candidates to search for
* @return the first present object, or <code>null</code> if not found
*/
@SuppressWarnings("rawtypes")
public static Object findFirstMatch(Collection source, Collection candidates) {
if (isEmpty(source) || isEmpty(candidates)) {
return null;
}
for (Object candidate : candidates) {
if (source.contains(candidate)) {
return candidate;
}
}
return null;
}
/**
* Find a single value of the given type in the given Collection.
*
* @param collection the Collection to search
* @param type the type to look for
* @return a value of the given type found if there is a clear match, or
* <code>null</code> if none or more than one such value found
*/
@SuppressWarnings("unchecked")
public static <T> T findValueOfType(Collection<?> collection, Class<T> type) {
if (isEmpty(collection)) {
return null;
}
T value = null;
for (Object element : collection) {
if (type == null || type.isInstance(element)) {
if (value != null) {
// More than one value found... no clear single value.
return null;
}
value = (T) element;
}
}
return value;
}
/**
* Find a single value of one of the given types in the given Collection:
* searching the Collection for a value of the first type, then searching
* for a value of the second type, etc.
*
* @param collection the collection to search
* @param types the types to look for, in prioritized order
* @return a value of one of the given types found if there is a clear
* match, or <code>null</code> if none or more than one such value
* found
*/
public static Object findValueOfType(Collection<?> collection, Class<?>[] types) {
if (isEmpty(collection) || ObjectUtils.isEmpty(types)) {
return null;
}
for (Class<?> type : types) {
Object value = findValueOfType(collection, type);
if (value != null) {
return value;
}
}
return null;
}
/**
* Determine whether the given Collection only contains a single unique
* object.
*
* @param collection the Collection to check
* @return <code>true</code> if the collection contains a single reference
* or multiple references to the same instance, <code>false</code>
* else
*/
@SuppressWarnings("rawtypes")
public static boolean hasUniqueObject(Collection collection) {
if (isEmpty(collection)) {
return false;
}
boolean hasCandidate = false;
Object candidate = null;
for (Object elem : collection) {
if (!hasCandidate) {
hasCandidate = true;
candidate = elem;
} else if (candidate != elem) {
return false;
}
}
return true;
}
/**
* Find the common element type of the given Collection, if any.
*
* @param collection the Collection to check
* @return the common element type, or <code>null</code> if no clear common
* type has been found (or the collection was empty)
*/
@SuppressWarnings("rawtypes")
public static Class<?> findCommonElementType(Collection collection) {
if (isEmpty(collection)) {
return null;
}
Class<?> candidate = null;
for (Object val : collection) {
if (val != null) {
if (candidate == null) {
candidate = val.getClass();
} else if (candidate != val.getClass()) {
return null;
}
}
}
return candidate;
}
/**
* Marshal the elements from the given enumeration into an array of the
* given type. Enumeration elements must be assignable to the type of the
* given array. The array returned will be a different instance than the
* array given.
*/
public static <A, E extends A> A[] toArray(Enumeration<E> enumeration, A[] array) {
ArrayList<A> elements = new ArrayList<A>();
while (enumeration.hasMoreElements()) {
elements.add(enumeration.nextElement());
}
return elements.toArray(array);
}
/**
* 将值放到V=List的Map中
*
* @param result
* @param key
* @param t
* @param <T> List的对象
* @param <A> key的对象
*/
public static <T, A> void putValueToMapWithList(Map<A, List<T>> result, A key, T t, boolean checkValueExistsInList) {
if (result.containsKey(key)) {
List<T> list = result.get(key);
if(checkValueExistsInList){
if(list.contains(t)){
return;
}
}
list.add(t);
} else {
List<T> tmps = new ArrayList<>();
tmps.add(t);
result.put(key, tmps);
}
}
public static <T, A> void putValueToMapWithList(Map<A, List<T>> result, A key, T t) {
putValueToMapWithList(result, key, t, false);
}
/**
* 当Key在Map中不存在的时候,将值添加到Map中
*
* @param result
* @param key
* @param t
* @param <T>
* @param <A>
*/
public static <T, A> void putValueToMapIfNotExists(Map<A, T> result, A key, T t) {
if (result.containsKey(key)) {
return;
}
result.put(key, t);
}
/**
* 将列表值放到V=List的Map中
*
* @param result
* @param key
* @param ts
* @param <T>
*/
public static <T> void putValuesToMapWithList(Map<String, List<T>> result, String key, List<T> ts) {
if (result.containsKey(key)) {
result.get(key).addAll(ts);
} else {
result.put(key, ts);
}
}
/**
* 根据指定长度切割集合
*
* @param datas
* @param count
* @param <T>
* @return
*/
public static <T> List<List<T>> splitList(List<T> datas, int count) {
if (isEmpty(datas)) {
return Collections.EMPTY_LIST;
}
List<List<T>> result = new ArrayList<>();
int dataCount = datas.size();
if (dataCount <= count || count == 0) {
result.add(datas);
return result;
}
List<T> tmps = new ArrayList<>();
for (int i = 0; i < dataCount; i++) {
tmps.add(datas.get(i));
if ((i + 1) % count == 0) {
result.add(tmps);
tmps = new ArrayList<>();
}
}
if (isNotEmpty(tmps)) {
result.add(tmps);
}
return result;
}
/**
* 切割set
*
* @param datas
* @param count
* @param <T>
* @return
*/
public static <T> List<Set<T>> splitSet(Set<T> datas, int count) {
if (isEmpty(datas)) {
return Collections.EMPTY_LIST;
}
List<Set<T>> result = new ArrayList<>();
int dataCount = datas.size();
if (dataCount <= count || count == 0) {
result.add(datas);
return result;
}
Set<T> tmps = new HashSet<>();
Iterator<T> iterator = datas.iterator();
int i = 0;
while (iterator.hasNext()) {
tmps.add(iterator.next());
if ((i + 1) % count == 0) {
result.add(tmps);
tmps = new HashSet<>();
}
i++;
}
if (isNotEmpty(tmps)) {
result.add(tmps);
}
return result;
}
public static void main(String[] args) {
}
}
package com.secoo.so.suggest.util;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.concurrent.*;
public class FeiShuUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(FeiShuUtil.class);
private static CloseableHttpClient client = HttpClientBuilder.create().build();
private static final URI FEI_SHU_URL = URI.create("http://matrix-inform.secoolocal.com/user/sendToUser");
/**
* 单线程的线程池发送消息,避免阻塞主线程
*/
private static ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1024), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());
public static void sendMessage(String title, String message, List<String> phones) {
if (StringUtils.isBlank(message)) {
return;
}
if (StringUtils.isBlank(title)) {
title = "异常通知";
}
final Map<String, Object> params = new HashMap<>(16);
params.put("title", title);
params.put("body", Collections.singletonList(message));
params.put("phones", phones);
final String fTitle = title;
final String fMessage = message;
final String fPhones = StringUtils.join(phones, ",");
Runnable runnable = new Runnable() {
@Override
public void run() {
CloseableHttpResponse res;
try {
HttpPost post = new HttpPost();
post.setURI(FEI_SHU_URL);
post.setEntity(new StringEntity(JSON.toJSON(params).toString(), ContentType.APPLICATION_JSON));
res = client.execute(post);
if (res == null || res.getEntity() == null) {
LOGGER.error("发送飞书消息失败: title:{}, message:{}, phones:{}", fTitle, fMessage, fPhones);
return;
}
if (res.getStatusLine() == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
LOGGER.error("发送飞书消息失败,title:{}, message:{}, phones:{}, res:{}", fTitle, fMessage, fPhones, EntityUtils.toString(res.getEntity()));
return;
}
} catch (IOException e) {
LOGGER.error("发送飞书消息失败: title:{}, message:{}, phones:{}", fTitle, fMessage, fPhones, e);
}
}
};
executor.submit(runnable);
}
public static void waitForFinish() throws InterruptedException {
executor.shutdown();
executor.awaitTermination(5, TimeUnit.MINUTES);
}
public static void main(String[] args) throws InterruptedException {
FeiShuUtil.sendMessage("测试", "hello wolrd", Arrays.asList("13426233960"));
FeiShuUtil.waitForFinish();
}
}
\ No newline at end of file
package com.secoo.so.suggest.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.*;
import java.lang.reflect.*;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* change this template use File | Settings | File Templates.
*/
public final class ObjectUtils {
private static final Logger logger = LoggerFactory.getLogger(ObjectUtils.class);
private static final int INITIAL_HASH = 7;
private static final int MULTIPLIER = 31;
private static final String EMPTY_STRING = "";
private static final String NULL_STRING = "null";
private static final String ARRAY_START = "{";
private static final String ARRAY_END = "}";
private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END;
private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
@SuppressWarnings("rawtypes")
public static Boolean isWrapClass(Class clazz) {
try {
return ((Class) clazz.getField("TYPE").get(null)).isPrimitive();
} catch (Exception e) {
return false;
}
}
/**
* 对象克隆,支持单个对象,数组与集合
*
* @param src
* @return
*/
public static Object byteClone(Object src) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(baos);
out.writeObject(src);
out.close();
ByteArrayInputStream bin = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
Object clone = in.readObject();
in.close();
return (clone);
} catch (ClassNotFoundException e) {
throw new InternalError(e.toString());
} catch (StreamCorruptedException e) {
throw new InternalError(e.toString());
} catch (IOException e) {
throw new InternalError(e.toString());
}
}
public static <T> T mapToObject(Map<String, Object> map, Class<T> beanClass) throws Exception {
if (map == null) {
return null;
}
T obj = beanClass.newInstance();
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
Method setter = property.getWriteMethod();
if (setter != null && map.containsKey(property.getName())) {
try {
setter.invoke(obj, map.get(property.getName()));
} catch (Exception e) {
logger.error(property.getName() + " value " + map.get(property.getName()) + " type not match", e);
}
}
}
return obj;
}
public static Map<String, Object> objectToMap(Object obj) throws Exception {
if (obj == null) {
return null;
}
Map<String, Object> map = new HashMap<String, Object>();
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
if (key.compareToIgnoreCase("class") == 0) {
continue;
}
Method getter = property.getReadMethod();
Object value = getter != null ? getter.invoke(obj) : null;
map.put(key, value);
}
return map;
}
public static boolean isEmpty(Object obj) {
return obj == null;
}
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Collection objects) {
return objects == null || objects.size() == 0;
}
/**
* Return whether the given throwable is a checked exception: that is,
* neither a RuntimeException nor an Error.
*
* @param ex the throwable to check
* @return whether the throwable is a checked exception
* @see Exception
* @see RuntimeException
* @see Error
*/
public static boolean isCheckedException(Throwable ex) {
return !(ex instanceof RuntimeException || ex instanceof Error);
}
/**
* Check whether the given exception is compatible with the exceptions
* declared in a throws clause.
*
* @param ex the exception to checked
* @param declaredExceptions the exceptions declared in the throws clause
* @return whether the given exception is compatible
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static boolean isCompatibleWithThrowsClause(Throwable ex, Class[] declaredExceptions) {
if (!isCheckedException(ex)) {
return true;
}
if (declaredExceptions != null) {
int i = 0;
while (i < declaredExceptions.length) {
if (declaredExceptions[i].isAssignableFrom(ex.getClass())) {
return true;
}
i++;
}
}
return false;
}
/**
* Determine whether the given object is an array: either an Object array or
* a primitive array.
*
* @param obj the object to check
*/
public static boolean isArray(Object obj) {
return (obj != null && obj.getClass().isArray());
}
/**
* Determine whether the given array is empty: i.e. <code>null</code> or of
* zero length.
*
* @param array the array to check
*/
public static boolean isEmpty(Object[] array) {
return (array == null || array.length == 0);
}
/**
* Check whether the given array contains the given element.
*
* @param array the array to check (may be <code>null</code>, in which case
* the return value will always be <code>false</code>)
* @param element the element to check for
* @return whether the element has been found in the given array
*/
public static boolean containsElement(Object[] array, Object element) {
if (array == null) {
return false;
}
for (Object arrayEle : array) {
if (nullSafeEquals(arrayEle, element)) {
return true;
}
}
return false;
}
/**
* Check whether the given array of enum constants contains a constant with
* the given name, ignoring case when determining a match.
*
* @param enumValues the enum values to check, typically the reports of a call to
* MyEnum.values()
* @param constant the constant name to find (must not be null or empty string)
* @return whether the constant has been found in the given array
*/
public static boolean containsConstant(Enum<?>[] enumValues, String constant) {
return containsConstant(enumValues, constant, false);
}
/**
* Check whether the given array of enum constants contains a constant with
* the given name.
*
* @param enumValues the enum values to check, typically the reports of a call to
* MyEnum.values()
* @param constant the constant name to find (must not be null or empty string)
* @param caseSensitive whether case is significant in determining a match
* @return whether the constant has been found in the given array
*/
public static boolean containsConstant(Enum<?>[] enumValues, String constant, boolean caseSensitive) {
for (Enum<?> candidate : enumValues) {
if (caseSensitive ? candidate.toString().equals(constant)
: candidate.toString().equalsIgnoreCase(constant)) {
return true;
}
}
return false;
}
/**
* Case insensitive alternative to {@link Enum#valueOf(Class, String)}.
*
* @param <E> the concrete Enum type
* @param enumValues the array of all Enum constants in question, usually per
* Enum.values()
* @param constant the constant to get the enum value of
* @throws IllegalArgumentException if the given constant is not found in the given array of enum
* values. Use {@link #containsConstant(Enum[], String)} as a
* guard to avoid this exception.
*/
public static <E extends Enum<?>> E caseInsensitiveValueOf(E[] enumValues, String constant) {
for (E candidate : enumValues) {
if (candidate.toString().equalsIgnoreCase(constant)) {
return candidate;
}
}
throw new IllegalArgumentException(String.format("constant [%s] does not exist in enum type %s", constant,
enumValues.getClass().getComponentType().getName()));
}
/**
* Append the given object to the given array, returning a new array
* consisting of the input array contents plus the given object.
*
* @param array the array to append to (can be <code>null</code>)
* @param obj the object to append
* @return the new array (of the same component type; never
* <code>null</code>)
*/
public static <A, O extends A> A[] addObjectToArray(A[] array, O obj) {
Class<?> compType = Object.class;
if (array != null) {
compType = array.getClass().getComponentType();
} else if (obj != null) {
compType = obj.getClass();
}
int newArrLength = (array != null ? array.length + 1 : 1);
@SuppressWarnings("unchecked")
A[] newArr = (A[]) Array.newInstance(compType, newArrLength);
if (array != null) {
System.arraycopy(array, 0, newArr, 0, array.length);
}
newArr[newArr.length - 1] = obj;
return newArr;
}
/**
* Convert the given array (which may be a primitive array) to an object
* array (if necessary of primitive wrapper objects).
* <p>
* A <code>null</code> source value will be converted to an empty Object
* array.
*
* @param source the (potentially primitive) array
* @return the corresponding object array (never <code>null</code>)
* @throws IllegalArgumentException if the parameter is not an array
*/
@SuppressWarnings("rawtypes")
public static Object[] toObjectArray(Object source) {
if (source instanceof Object[]) {
return (Object[]) source;
}
if (source == null) {
return new Object[0];
}
if (!source.getClass().isArray()) {
throw new IllegalArgumentException("Source is not an array: " + source);
}
int length = Array.getLength(source);
if (length == 0) {
return new Object[0];
}
Class wrapperType = Array.get(source, 0).getClass();
Object[] newArray = (Object[]) Array.newInstance(wrapperType, length);
for (int i = 0; i < length; i++) {
newArray[i] = Array.get(source, i);
}
return newArray;
}
// ---------------------------------------------------------------------
// Convenience methods for content-based equality/hash-code handling
// ---------------------------------------------------------------------
/**
* Determine if the given objects are equal, returning <code>true</code> if
* both are <code>null</code> or <code>false</code> if only one is
* <code>null</code>.
* <p>
* Compares arrays with <code>Arrays.equals</code>, performing an equality
* check based on the array elements rather than the array reference.
*
* @param o1 first Object to compare
* @param o2 second Object to compare
* @return whether the given objects are equal
* @see Arrays#equals
*/
public static boolean nullSafeEquals(Object o1, Object o2) {
if (o1 == o2) {
return true;
}
if (o1 == null || o2 == null) {
return false;
}
if (o1.equals(o2)) {
return true;
}
if (o1.getClass().isArray() && o2.getClass().isArray()) {
if (o1 instanceof Object[] && o2 instanceof Object[]) {
return Arrays.equals((Object[]) o1, (Object[]) o2);
}
if (o1 instanceof boolean[] && o2 instanceof boolean[]) {
return Arrays.equals((boolean[]) o1, (boolean[]) o2);
}
if (o1 instanceof byte[] && o2 instanceof byte[]) {
return Arrays.equals((byte[]) o1, (byte[]) o2);
}
if (o1 instanceof char[] && o2 instanceof char[]) {
return Arrays.equals((char[]) o1, (char[]) o2);
}
if (o1 instanceof double[] && o2 instanceof double[]) {
return Arrays.equals((double[]) o1, (double[]) o2);
}
if (o1 instanceof float[] && o2 instanceof float[]) {
return Arrays.equals((float[]) o1, (float[]) o2);
}
if (o1 instanceof int[] && o2 instanceof int[]) {
return Arrays.equals((int[]) o1, (int[]) o2);
}
if (o1 instanceof long[] && o2 instanceof long[]) {
return Arrays.equals((long[]) o1, (long[]) o2);
}
if (o1 instanceof short[] && o2 instanceof short[]) {
return Arrays.equals((short[]) o1, (short[]) o2);
}
}
return false;
}
/**
* Return as hash code for the given object; typically the value of
* <code>{@link Object#hashCode()}</code>. If the object is an array, this
* method will delegate to any of the <code>nullSafeHashCode</code> methods
* for arrays in this class. If the object is <code>null</code>, this method
* returns 0.
*
* @see #nullSafeHashCode(Object[])
* @see #nullSafeHashCode(boolean[])
* @see #nullSafeHashCode(byte[])
* @see #nullSafeHashCode(char[])
* @see #nullSafeHashCode(double[])
* @see #nullSafeHashCode(float[])
* @see #nullSafeHashCode(int[])
* @see #nullSafeHashCode(long[])
* @see #nullSafeHashCode(short[])
*/
public static int nullSafeHashCode(Object obj) {
if (obj == null) {
return 0;
}
if (obj.getClass().isArray()) {
if (obj instanceof Object[]) {
return nullSafeHashCode((Object[]) obj);
}
if (obj instanceof boolean[]) {
return nullSafeHashCode((boolean[]) obj);
}
if (obj instanceof byte[]) {
return nullSafeHashCode((byte[]) obj);
}
if (obj instanceof char[]) {
return nullSafeHashCode((char[]) obj);
}
if (obj instanceof double[]) {
return nullSafeHashCode((double[]) obj);
}
if (obj instanceof float[]) {
return nullSafeHashCode((float[]) obj);
}
if (obj instanceof int[]) {
return nullSafeHashCode((int[]) obj);
}
if (obj instanceof long[]) {
return nullSafeHashCode((long[]) obj);
}
if (obj instanceof short[]) {
return nullSafeHashCode((short[]) obj);
}
}
return obj.hashCode();
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
public static int nullSafeHashCode(Object[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + nullSafeHashCode(array[i]);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
public static int nullSafeHashCode(boolean[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + hashCode(array[i]);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
public static int nullSafeHashCode(byte[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + array[i];
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
public static int nullSafeHashCode(char[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int i = 0; i < arraySize; i++) {
hash = MULTIPLIER * hash + array[i];
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
@SuppressWarnings("unused")
public static int nullSafeHashCode(double[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (double anArray : array) {
hash = MULTIPLIER * hash + hashCode(anArray);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
@SuppressWarnings("unused")
public static int nullSafeHashCode(float[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (float anArray : array) {
hash = MULTIPLIER * hash + hashCode(anArray);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
@SuppressWarnings("unused")
public static int nullSafeHashCode(int[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (int anArray : array) {
hash = MULTIPLIER * hash + anArray;
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
@SuppressWarnings("unused")
public static int nullSafeHashCode(long[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (long anArray : array) {
hash = MULTIPLIER * hash + hashCode(anArray);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array. If
* <code>array</code> is <code>null</code>, this method returns 0.
*/
@SuppressWarnings("unused")
public static int nullSafeHashCode(short[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
int arraySize = array.length;
for (short anArray : array) {
hash = MULTIPLIER * hash + anArray;
}
return hash;
}
/**
* Return the same value as <code>{@link Boolean#hashCode()}</code>.
*
* @see Boolean#hashCode()
*/
public static int hashCode(boolean bool) {
return bool ? 1231 : 1237;
}
/**
* Return the same value as <code>{@link Double#hashCode()}</code>.
*
* @see Double#hashCode()
*/
public static int hashCode(double dbl) {
long bits = Double.doubleToLongBits(dbl);
return hashCode(bits);
}
/**
* Return the same value as <code>{@link Float#hashCode()}</code>.
*
* @see Float#hashCode()
*/
public static int hashCode(float flt) {
return Float.floatToIntBits(flt);
}
/**
* Return the same value as <code>{@link Long#hashCode()}</code>.
*
* @see Long#hashCode()
*/
public static int hashCode(long lng) {
return (int) (lng ^ (lng >>> 32));
}
// ---------------------------------------------------------------------
// Convenience methods for toString output
// ---------------------------------------------------------------------
/**
* Return a String representation of an object's overall identity.
*
* @param obj the object (may be <code>null</code>)
* @return the object's identity as String representation, or an empty
* String if the object was <code>null</code>
*/
public static String identityToString(Object obj) {
if (obj == null) {
return EMPTY_STRING;
}
return obj.getClass().getName() + "@" + getIdentityHexString(obj);
}
/**
* Return a hex String form of an object's identity hash code.
*
* @param obj the object
* @return the object's identity code in hex notation
*/
public static String getIdentityHexString(Object obj) {
return Integer.toHexString(System.identityHashCode(obj));
}
/**
* Return a content-based String representation if <code>obj</code> is not
* <code>null</code>; otherwise returns an empty String.
* <p>
* Differs from {@link #nullSafeToString(Object)} in that it returns an
* empty String rather than "null" for a <code>null</code> value.
*
* @param obj the object to build a display String for
* @return a display String representation of <code>obj</code>
* @see #nullSafeToString(Object)
*/
public static String getDisplayString(Object obj) {
if (obj == null) {
return EMPTY_STRING;
}
return nullSafeToString(obj);
}
/**
* Determine the class name for the given object.
* <p>
* Returns <code>"null"</code> if <code>obj</code> is <code>null</code>.
*
* @param obj the object to introspect (may be <code>null</code>)
* @return the corresponding class name
*/
public static String nullSafeClassName(Object obj) {
return (obj != null ? obj.getClass().getName() : NULL_STRING);
}
/**
* Return a String representation of the specified Object.
* <p>
* Builds a String representation of the contents in case of an array.
* Returns <code>"null"</code> if <code>obj</code> is <code>null</code>.
*
* @param obj the object to build a String representation for
* @return a String representation of <code>obj</code>
*/
public static String nullSafeToString(Object obj) {
if (obj == null) {
return NULL_STRING;
}
if (obj instanceof String) {
return (String) obj;
}
if (obj instanceof Object[]) {
return nullSafeToString((Object[]) obj);
}
if (obj instanceof boolean[]) {
return nullSafeToString((boolean[]) obj);
}
if (obj instanceof byte[]) {
return nullSafeToString((byte[]) obj);
}
if (obj instanceof char[]) {
return nullSafeToString((char[]) obj);
}
if (obj instanceof double[]) {
return nullSafeToString((double[]) obj);
}
if (obj instanceof float[]) {
return nullSafeToString((float[]) obj);
}
if (obj instanceof int[]) {
return nullSafeToString((int[]) obj);
}
if (obj instanceof long[]) {
return nullSafeToString((long[]) obj);
}
if (obj instanceof short[]) {
return nullSafeToString((short[]) obj);
}
String str = obj.toString();
return (str != null ? str : EMPTY_STRING);
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(Object[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(boolean[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(byte[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(char[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append("'").append(array[i]).append("'");
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(double[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(float[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(int[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(long[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>
* The String representation consists of a list of the array's elements,
* enclosed in curly braces (<code>"{}"</code>). Adjacent elements are
* separated by the characters <code>", "</code> (a comma followed by a
* space). Returns <code>"null"</code> if <code>array</code> is
* <code>null</code>.
*
* @param array the array to build a String representation for
* @return a String representation of <code>array</code>
*/
public static String nullSafeToString(short[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
} else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* 公共的销毁对象方法,用于内存回收
*/
public static void destroy(Object obj) {
obj = null;
}
/**
* 安全关闭流
*/
public static void safeClose(Object... objects) {
boolean debugEnabled = logger.isDebugEnabled();
if (objects == null || objects.length == 0) {
logger.info("safeClose(...) was invoked with null or empty array: {}", objects);
return;
}
for (Object obj : objects) {
if (obj != null) {
if (debugEnabled) {
logger.debug("Trying to safely close {}", obj);
}
if (obj instanceof Flushable) {
try {
((Flushable) obj).flush();
} catch (Exception e) {
if (debugEnabled) {
logger.debug("Flushing Flushable failed", e);
}
}
}
if (obj instanceof Closeable) {
try {
((Closeable) obj).close();
} catch (IOException e) {
if (debugEnabled) {
logger.debug("Closing Closeable failed", e);
}
}
} else if (obj instanceof Connection) {
try {
((Connection) obj).close();
} catch (Exception e) {
if (debugEnabled) {
logger.debug("Closing Connection failed", e);
}
}
} else if (obj instanceof Statement) {
try {
((Statement) obj).close();
} catch (Exception e) {
if (debugEnabled) {
logger.debug("Closing Statement failed", e);
}
}
} else if (obj instanceof ResultSet) {
try {
((ResultSet) obj).close();
} catch (Exception e) {
if (debugEnabled) {
logger.debug("Closing ResultSet failed", e);
}
}
} else {
logger.info("obj was neither Closeable, Connection, Statement or ResultSet.");
try {
Method method = obj.getClass().getMethod("close");
if (method == null) {
logger.info("obj did not have a close() method, ignoring");
} else {
method.setAccessible(true);
method.invoke(obj);
}
} catch (InvocationTargetException e) {
logger.warn("Invoking close() by reflection threw exception", e);
} catch (Exception e) {
logger.warn("Could not invoke close() by reflection", e);
}
}
}
}
}
@SuppressWarnings("rawtypes")
public static List<Field> getDeclaredFieldsIncludeSupper(Class clazz) {
List<Field> fieldList = new ArrayList<>();
Class tempClass = clazz;
while (tempClass != null) {// 当父类为null的时候说明到达了最上层的父类(Object类).
fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
tempClass = tempClass.getSuperclass(); // 得到父类,然后赋给自己
}
return fieldList.stream().filter(e -> !Modifier.isStatic(e.getModifiers()))
.collect(Collectors.toList());
}
@SuppressWarnings("rawtypes")
public static Field getDeclaredField(Class clazz, String fieldName) throws NoSuchFieldException {
return getDeclaredField(clazz, fieldName, true);
}
@SuppressWarnings("rawtypes")
public static Field getDeclaredField(Class clazz, String fieldName, boolean throwException)
throws NoSuchFieldException {
Field field = null;
try {
field = clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
if (throwException) {
throw new NoSuchFieldException(fieldName + " of " + clazz.getName());
}
}
return field;
}
@SuppressWarnings("rawtypes")
public static Field getDeclaredFieldIncludeSupper(Class clazz, String fieldName) throws NoSuchFieldException {
Field field = null;
field = getDeclaredField(clazz, fieldName, false);
Class parentClass = clazz.getSuperclass(); // 得到父类,然后赋给自己
while (field == null && parentClass != null) {
field = getDeclaredField(parentClass, fieldName, false);
parentClass = parentClass.getSuperclass();
}
if (field == null) {
throw new NoSuchFieldException(fieldName + " of " + clazz.getName());
}
return field;
}
public static <T> Object getFieldValue(T t, Field field) {
Object value = null;
if (field != null) {
try {
boolean fieldAccessible = field.isAccessible();
field.setAccessible(true);// 打开javabean的访问权限
value = field.get(t);
field.setAccessible(fieldAccessible);// 恢复字段访问权限
} catch (IllegalArgumentException | IllegalAccessException e) {
logger.warn("get field<{}> of object<{}> error", field.getName(), JSON.toJSONString(t), e);
}
}
return value;
}
public static <T> void setFieldValue(T t, Class<T> clazz, String fieldName, Object fieldValue) {
Field field;
try {
field = getDeclaredFieldIncludeSupper(clazz, fieldName);
setFieldValue(t, clazz, field, fieldValue);
} catch (Exception e) {
logger.warn("set field<{}> value<{}> error", fieldName, JSON.toJSONString(fieldValue), e);
}
}
public static <T> void setFieldValue(T t, Class<T> clazz, Field field, Object fieldValue) {
if (field == null || fieldValue == null) {
return;
}
try {
boolean fieldAccessible = field.isAccessible();
field.setAccessible(true);// 打开javabean的访问权限
field.set(t, fieldValue);
field.setAccessible(fieldAccessible);// 恢复字段访问权限
} catch (Exception e) {
logger.warn("set field<{}> value<{}> error", field.getName(), JSON.toJSONString(fieldValue), e);
}
}
/**
* 根据数据类型设置字段值<br>
* TODO: 目前只支持部分数据类型
*
* @date: 2018-12-05
* @author xupeng
*/
public static <T> void setFieldValueByDataType(T t, Class<T> clazz, String fieldName, String fieldValue) {
if (StringUtils.isBlank(fieldName) || fieldValue == null) {
return;
}
Field field = null;
try {
field = getDeclaredFieldIncludeSupper(clazz, fieldName);
setFieldValueByDataType(t, clazz, field, fieldValue);
} catch (Exception e) {
logger.warn("set field<{}> value<{}> error", fieldName, JSON.toJSONString(fieldValue), e);
}
}
/**
* 根据数据类型设置字段值<br>
* TODO: 目前只支持部分数据类型
*
* @date: 2018-12-05
* @author xupeng
*/
public static <T> void setFieldValueByDataType(T t, Class<T> clazz, Field field, String fieldValue) {
if (field == null || fieldValue == null) {
return;
}
try {
boolean fieldAccessible = field.isAccessible();
field.setAccessible(true);// 打开javabean的访问权限
String dataType = field.getType().getName();
// 不是字符串类型的话先trim
if (!dataType.equals(String.class.getName())) {
fieldValue = fieldValue.trim();
}
// 根据类型设置属性值
if (dataType.equals(String.class.getName())) {
field.set(t, fieldValue);
} else if (dataType.equals(Integer.class.getName())) {
field.set(t, StringUtils.isNotBlank(fieldValue) ? Integer.valueOf(fieldValue) : null);
} else if (dataType.equals(Long.class.getName())) {
field.set(t, StringUtils.isNotBlank(fieldValue) ? Long.valueOf(fieldValue) : null);
} else if (dataType.equals(Boolean.class.getName())) {
field.set(t, StringUtils.isNotBlank(fieldValue) ? Boolean.valueOf(fieldValue) : null);
} else if (dataType.equals(Double.class.getName())) {
field.set(t, StringUtils.isNotBlank(fieldValue) ? Double.valueOf(fieldValue) : null);
} else if (dataType.equals(Float.class.getName())) {
field.set(t, StringUtils.isNotBlank(fieldValue) ? Float.valueOf(fieldValue) : null);
} else if (dataType.equals(BigDecimal.class.getName())) {
field.set(t, StringUtils.isNotBlank(fieldValue) ? new BigDecimal(fieldValue) : null);
} else if (dataType.equals(BigDecimal.class.getName())) {
field.set(t, StringUtils.isNotBlank(fieldValue) ? new BigDecimal(fieldValue) : null);
} else {
field.set(t, fieldValue);
}
field.setAccessible(fieldAccessible);// 恢复字段访问权限
} catch (Exception e) {
logger.warn("set field<{}> value<{}> error", field.getName(), JSON.toJSONString(fieldValue), e);
}
}
/**
* 将json字符串转换为绝对路径key的map,不支持数组
*
* @date: 2018-12-07
* @author xupeng
*/
public static Map<String, String> parseJsonStrToAbsolutePathKeyMap(String json) {
Map<String, String> map = new HashMap<>();
if (StringUtils.isNotBlank(json)) {
try {
JSONObject jsonObj = JSON.parseObject(json);
map = parseJsonObjectToAbsolutePathKeyMap("", jsonObj, map);
} catch (Exception e) {
logger.error("parseJsonStrToAbsolutePathKeyMap error", e);
}
}
return map;
}
/**
* 将jsonObject转换为绝对路径key的map,不支持数组
*
* @date: 2018-12-07
* @author xupeng
*/
public static Map<String, String> parseJsonObjectToAbsolutePathKeyMap(String preKey, JSONObject jsonObj,
Map<String, String> map) {
if (jsonObj != null && !jsonObj.isEmpty()) {
try {
for (String key : jsonObj.keySet()) {
Object valueObj = jsonObj.get(key);
String currentKey = key;
if (StringUtils.isNotBlank(preKey)) {
currentKey = preKey + "." + key;
}
if (valueObj instanceof JSONObject) {
parseJsonObjectToAbsolutePathKeyMap(currentKey, (JSONObject) valueObj, map);
} else {
map.put(currentKey, jsonObj.getString(key));
}
}
} catch (Exception e) {
logger.error("parseJsonObjectToAbsolutePathKeyMap error", e);
}
}
return map;
}
/**
* Map转换成以叶子节点为key,叶子节点对应的绝对路径为value
* <p>
* 要使用该方法,必须要保证map中所有层级的key都不会重复
*
* @param preKey
* @param source
* @param pathMap
*/
public static void parseMapLeafNodeWithAbsolutePathKeyMap(String preKey, Map<String, Object> source,
Map<String, String> pathMap) {
if (CollectionUtils.isEmpty(source)) {
return;
}
for (Map.Entry<String, Object> s : source.entrySet()) {
Object v = s.getValue();
String currentKey = s.getKey();
String absoluteKey = null;
if (StringUtils.isNotBlank(preKey)) {
absoluteKey = preKey + "." + currentKey;
} else {
absoluteKey = currentKey;
}
if (v instanceof Map) {
parseMapLeafNodeWithAbsolutePathKeyMap(currentKey, (Map<String, Object>) v, pathMap);
} else {
pathMap.put(currentKey, absoluteKey);
}
}
}
/**
* 把Map的所有叶子节点key设置给leafNodeKeys
* 支持多层级的Map,但不支持List
*
* @param leafNodeKeys
* @param source
* @param levelLimit 层级控制 -1为不限制
*/
public static void parseMapLeafNodeKeys(Set<String> leafNodeKeys, Map<String, Object> source, int levelLimit) {
if (CollectionUtils.isEmpty(source)) {
return;
}
for (Map.Entry<String, Object> s : source.entrySet()) {
Object v = s.getValue();
if (v instanceof Map && levelLimit != 0) {
parseMapLeafNodeKeys(leafNodeKeys, (Map<String, Object>) v, levelLimit - 1);
} else {
leafNodeKeys.add(s.getKey());
}
}
}
/**
* 以叶子节点去Map中找到对应的值
*
* @param source
* @param leafNodeKey
* @param levelLimit 控制取数的层级
* @return
*/
public static Object findValueWithLeafNodeKey(Map<String, Object> source, String leafNodeKey, int levelLimit) {
if (CollectionUtils.isEmpty(source)) {
return null;
}
//先直接查看一下本层级是否存在叶子节点的值
if (source.containsKey(leafNodeKey)) {
Object value = source.get(leafNodeKey);
if (value instanceof Map || value instanceof List) {
return JSON.toJSONString(value);
} else {
return value;
}
}
if (levelLimit == 0) {
return null;
}
for (Map.Entry<String, Object> s : source.entrySet()) {
Object v = s.getValue();
//只对map进一步进行处理
if (v instanceof Map) {
Object value = findValueWithLeafNodeKey((Map<String, Object>) v, leafNodeKey, levelLimit - 1);
if (null == value) {
continue;
} else {
return value;
}
}
}
return null;
}
/**
* 根据路径去找到map中的对应数据
*
* @param source
* @param path
* @param type
* @param <T>
* @return
*/
public static <T> T findValueWithPath(Map<String, Object> source, String path, Class<T> type) {
if (CollectionUtils.isEmpty(source) || StringUtils.isBlank(path)) {
return null;
}
int firstIndex = path.indexOf(".");
if (firstIndex == -1) {
return findValueWithKey(source, path, type);
}
String firstKey = path.substring(0, firstIndex);
String lastKey = path.substring(firstIndex + 1, path.length());
Object nextData = source.get(firstKey);
if (null == nextData || !(nextData instanceof Map)) {
return null;
}
return findValueWithPath((Map<String, Object>) nextData, lastKey, type);
}
public static <T> T findValueWithKey(Map<String, Object> source, String key, Class<T> type) {
Object data = source.get(key);
if (null == data) {
return null;
}
return type.cast(data);
}
public static boolean sleep(Number timeout, TimeUnit timeUnit) {
try {
timeUnit.sleep(timeout.longValue());
return true;
} catch (InterruptedException var3) {
return false;
}
}
public static boolean sleep(Number millis) {
if (millis == null) {
return true;
} else {
try {
Thread.sleep(millis.longValue());
return true;
} catch (InterruptedException var2) {
return false;
}
}
}
public static boolean safeSleep(Number millis) {
long millisLong = millis.longValue();
long before;
long after;
for (long done = 0L; done < millisLong; done += after - before) {
before = System.currentTimeMillis();
if (!sleep(millisLong - done)) {
return false;
}
after = System.currentTimeMillis();
}
return true;
}
public static void main(String[] args) {
/*String json = "{\"name\":\"TMev344\",\"cluster_name\":\"elasticsearch\",\"cluster_uuid\":\"cRwLaMCuRkmZvpnYrcQ6mQ\",\"version\":{\"number\":\"6.5.0\",\"build_flavor\":\"default\",\"build_type\":\"zip\",\"build_hash\":\"816e6f6\",\"build_date\":\"2018-11-09T18:58:36.352602Z\",\"build_snapshot\":false,\"lucene_version\":\"7.5.0\",\"minimum_wire_compatibility_version\":\"5.6.0\",\"minimum_index_compatibility_version\":\"5.0.0\"},\"tagline\":\"You Know, for Search\"}";
Map<String, String> paramMap = parseJsonStrToAbsolutePathKeyMap(json);
System.out.println(paramMap);
String str = "http:www.baidu.com?name=${name}&cn=${cluster_name}&vn=${version.number}";
System.out.println(StringUtils.replaceParam(str, paramMap));*/
String json = "{\"a\":{\"b\":{\"c\":\"d\"}},\"e\":{\"f\":\"1\",\"g\":\"2\"}}";
Map<String, Object> map = JSON.parseObject(json, new TypeReference<Map<String, Object>>() {
});
Set<String> keys = new HashSet<>();
parseMapLeafNodeKeys(keys, map, 1);
System.out.println(keys);
for (String key : keys) {
Object v = findValueWithLeafNodeKey(map, key, 1);
System.out.println(v);
}
}
}
package com.secoo.so.suggest.util;
import com.github.stuxuhai.jpinyin.ChineseHelper;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class PinYinUtils {
/**
* 简体转换为繁体
*/
public static String convertToTraditionalChinese(String str) {
String tempStr = null;
try {
tempStr = ChineseHelper.convertToTraditionalChinese(str);
} catch (Exception e) {
tempStr = str;
log.error("convertToTraditionalChinese error", e);
}
return tempStr;
}
/**
* 繁体转换为简体
*/
public static String convertToSimplifiedChinese(String str) {
String tempStr = null;
try {
tempStr = ChineseHelper.convertToSimplifiedChinese(str);
} catch (Exception e) {
tempStr = str;
log.error("convertToSimplifiedChinese error", e);
}
return tempStr;
}
}
package com.secoo.so.suggest.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created with IntelliJ IDEA. User: Administrator Date: 13-11-11 Time: 下午12:20
* To change this template use File | Settings | File Templates.
*/
public abstract class StringUtils {
private static final String FOLDER_SEPARATOR = "/";
private static final String WINDOWS_FOLDER_SEPARATOR = "\\";
private static final String TOP_PATH = "..";
private static final String CURRENT_PATH = ".";
private static final char EXTENSION_SEPARATOR = '.';
// ---------------------------------------------------------------------
// General convenience methods for working with Strings
// ---------------------------------------------------------------------
/**
* Check that the given CharSequence is neither <code>null</code> nor of
* length 0. Note: Will return <code>true</code> for a CharSequence that
* purely consists of whitespace.
* <p>
*
* <pre>
* StringUtil.hasLength(null) = false
* StringUtil.hasLength("") = false
* StringUtil.hasLength(" ") = true
* StringUtil.hasLength("Hello") = true
* </pre>
*
* @param str the CharSequence to check (may be <code>null</code>)
* @return <code>true</code> if the CharSequence is not null and has length
* @see #hasText(String)
*/
public static boolean hasLength(CharSequence str) {
return (str != null && str.length() > 0);
}
/**
* Check that the given String is neither <code>null</code> nor of length 0.
* Note: Will return <code>true</code> for a String that purely consists of
* whitespace.
*
* @param str the String to check (may be <code>null</code>)
* @return <code>true</code> if the String is not null and has length
* @see #hasLength(CharSequence)
*/
public static boolean hasLength(String str) {
return hasLength((CharSequence) str);
}
/**
* Check whether the given CharSequence has actual text. More specifically,
* returns <code>true</code> if the string not <code>null</code>, its length
* is greater than 0, and it contains at least one non-whitespace character.
* <p>
*
* <pre>
* StringUtil.hasText(null) = false
* StringUtil.hasText("") = false
* StringUtil.hasText(" ") = false
* StringUtil.hasText("12345") = true
* StringUtil.hasText(" 12345 ") = true
* </pre>
*
* @param str the CharSequence to check (may be <code>null</code>)
* @return <code>true</code> if the CharSequence is not <code>null</code>,
* its length is greater than 0, and it does not contain whitespace
* only
* @see Character#isWhitespace
*/
public static boolean hasText(CharSequence str) {
if (!hasLength(str)) {
return false;
}
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return true;
}
}
return false;
}
/**
* Check whether the given String has actual text. More specifically,
* returns <code>true</code> if the string not <code>null</code>, its length
* is greater than 0, and it contains at least one non-whitespace character.
*
* @param str the String to check (may be <code>null</code>)
* @return <code>true</code> if the String is not <code>null</code>, its
* length is greater than 0, and it does not contain whitespace only
* @see #hasText(CharSequence)
*/
public static boolean hasText(String str) {
return hasText((CharSequence) str);
}
/**
* Check whether the given CharSequence contains any whitespace characters.
*
* @param str the CharSequence to check (may be <code>null</code>)
* @return <code>true</code> if the CharSequence is not empty and contains
* at least 1 whitespace character
* @see Character#isWhitespace
*/
public static boolean containsWhitespace(CharSequence str) {
if (!hasLength(str)) {
return false;
}
int strLen = str.length();
for (int i = 0; i < strLen; i++) {
if (Character.isWhitespace(str.charAt(i))) {
return true;
}
}
return false;
}
/**
* Check whether the given String contains any whitespace characters.
*
* @param str the String to check (may be <code>null</code>)
* @return <code>true</code> if the String is not empty and contains at
* least 1 whitespace character
* @see #containsWhitespace(CharSequence)
*/
public static boolean containsWhitespace(String str) {
return containsWhitespace((CharSequence) str);
}
/**
* Trim leading and trailing whitespace from the given String.
*
* @param str the String to check
* @return the trimmed String
* @see Character#isWhitespace
*/
public static String trimWhitespace(String str) {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
}
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
/**
* Trim <i>all</i> whitespace from the given String: leading, trailing, and
* inbetween characters.
*
* @param str the String to check
* @return the trimmed String
* @see Character#isWhitespace
*/
public static String trimAllWhitespace(String str) {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
int index = 0;
while (sb.length() > index) {
if (Character.isWhitespace(sb.charAt(index))) {
sb.deleteCharAt(index);
} else {
index++;
}
}
return sb.toString();
}
/**
* Trim leading whitespace from the given String.
*
* @param str the String to check
* @return the trimmed String
* @see Character#isWhitespace
*/
public static String trimLeadingWhitespace(String str) {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
}
return sb.toString();
}
/**
* Trim trailing whitespace from the given String.
*
* @param str the String to check
* @return the trimmed String
* @see Character#isWhitespace
*/
public static String trimTrailingWhitespace(String str) {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
/**
* Trim all occurences of the supplied leading character from the given
* String.
*
* @param str the String to check
* @param leadingCharacter the leading character to be trimmed
* @return the trimmed String
*/
public static String trimLeadingCharacter(String str, char leadingCharacter) {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && sb.charAt(0) == leadingCharacter) {
sb.deleteCharAt(0);
}
return sb.toString();
}
/**
* Trim all occurences of the supplied trailing character from the given
* String.
*
* @param str the String to check
* @param trailingCharacter the trailing character to be trimmed
* @return the trimmed String
*/
public static String trimTrailingCharacter(String str, char trailingCharacter) {
if (!hasLength(str)) {
return str;
}
StringBuilder sb = new StringBuilder(str);
while (sb.length() > 0 && sb.charAt(sb.length() - 1) == trailingCharacter) {
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
/**
* Test if the given String starts with the specified prefix, ignoring
* upper/lower case.
*
* @param str the String to check
* @param prefix the prefix to look for
* @see String#startsWith
*/
public static boolean startsWithIgnoreCase(String str, String prefix) {
if (str == null || prefix == null) {
return false;
}
if (str.startsWith(prefix)) {
return true;
}
if (str.length() < prefix.length()) {
return false;
}
String lcStr = str.substring(0, prefix.length()).toLowerCase();
String lcPrefix = prefix.toLowerCase();
return lcStr.equals(lcPrefix);
}
/**
* Test if the given String ends with the specified suffix, ignoring
* upper/lower case.
*
* @param str the String to check
* @param suffix the suffix to look for
* @see String#endsWith
*/
public static boolean endsWithIgnoreCase(String str, String suffix) {
if (str == null || suffix == null) {
return false;
}
if (str.endsWith(suffix)) {
return true;
}
if (str.length() < suffix.length()) {
return false;
}
String lcStr = str.substring(str.length() - suffix.length()).toLowerCase();
String lcSuffix = suffix.toLowerCase();
return lcStr.equals(lcSuffix);
}
/**
* Test whether the given string matches the given substring at the given
* index.
*
* @param str the original string (or StringBuilder)
* @param index the index in the original string to start matching against
* @param substring the substring to match at the given index
*/
public static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
for (int j = 0; j < substring.length(); j++) {
int i = index + j;
if (i >= str.length() || str.charAt(i) != substring.charAt(j)) {
return false;
}
}
return true;
}
/**
* Count the occurrences of the substring in string s.
*
* @param str string to search in. Return 0 if this is null.
* @param sub string to search for. Return 0 if this is null.
*/
public static int countOccurrencesOf(String str, String sub) {
if (str == null || sub == null || str.length() == 0 || sub.length() == 0) {
return 0;
}
int count = 0;
int pos = 0;
int idx;
while ((idx = str.indexOf(sub, pos)) != -1) {
++count;
pos = idx + sub.length();
}
return count;
}
/**
* Replace all occurences of a substring within a string with another
* string.
*
* @param inString String to examine
* @param oldPattern String to replace
* @param newPattern String to insert
* @return a String with the replacements
*/
public static String replace(String inString, String oldPattern, String newPattern) {
if (!hasLength(inString) || !hasLength(oldPattern) || newPattern == null) {
return inString;
}
StringBuilder sb = new StringBuilder();
int pos = 0; // our position in the old string
int index = inString.indexOf(oldPattern);
// the index of an occurrence we've found, or -1
int patLen = oldPattern.length();
while (index >= 0) {
sb.append(inString.substring(pos, index));
sb.append(newPattern);
pos = index + patLen;
index = inString.indexOf(oldPattern, pos);
}
sb.append(inString.substring(pos));
// remember to append any characters to the right of a match
return sb.toString();
}
/**
* Delete all occurrences of the given substring.
*
* @param inString the original String
* @param pattern the pattern to delete all occurrences of
* @return the resulting String
*/
public static String delete(String inString, String pattern) {
return replace(inString, pattern, "");
}
/**
* Delete any character in a given String.
*
* @param inString the original String
* @param charsToDelete a set of characters to delete. E.g. "az\n" will delete 'a's,
* 'z's and new lines.
* @return the resulting String
*/
public static String deleteAny(String inString, String charsToDelete) {
if (!hasLength(inString) || !hasLength(charsToDelete)) {
return inString;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < inString.length(); i++) {
char c = inString.charAt(i);
if (charsToDelete.indexOf(c) == -1) {
sb.append(c);
}
}
return sb.toString();
}
// ---------------------------------------------------------------------
// Convenience methods for working with formatted Strings
// ---------------------------------------------------------------------
/**
* Quote the given String with single quotes.
*
* @param str the input String (e.g. "myString")
* @return the quoted String (e.g. "'myString'"), or
* <code>null<code> if the input was <code>null</code>
*/
public static String quote(String str) {
return (str != null ? "'" + str + "'" : null);
}
/**
* Turn the given Object into a String with single quotes if it is a String;
* keeping the Object as-is else.
*
* @param obj the input Object (e.g. "myString")
* @return the quoted String (e.g. "'myString'"), or the input object as-is
* if not a String
*/
public static Object quoteIfString(Object obj) {
return (obj instanceof String ? quote((String) obj) : obj);
}
/**
* Unqualify a string qualified by a '.' dot character. For example,
* "this.name.is.qualified", returns "qualified".
*
* @param qualifiedName the qualified name
*/
public static String unqualify(String qualifiedName) {
return unqualify(qualifiedName, '.');
}
/**
* Unqualify a string qualified by a separator character. For example,
* "this:name:is:qualified" returns "qualified" if using a ':' separator.
*
* @param qualifiedName the qualified name
* @param separator the separator
*/
public static String unqualify(String qualifiedName, char separator) {
return qualifiedName.substring(qualifiedName.lastIndexOf(separator) + 1);
}
/**
* Capitalize a <code>String</code>, changing the first letter to upper case
* as per {@link Character#toUpperCase(char)}. No other letters are changed.
*
* @param str the String to capitalize, may be <code>null</code>
* @return the capitalized String, <code>null</code> if null
*/
public static String capitalize(String str) {
return changeFirstCharacterCase(str, true);
}
/**
* Uncapitalize a <code>String</code>, changing the first letter to lower
* case as per {@link Character#toLowerCase(char)}. No other letters are
* changed.
*
* @param str the String to uncapitalize, may be <code>null</code>
* @return the uncapitalized String, <code>null</code> if null
*/
public static String uncapitalize(String str) {
return changeFirstCharacterCase(str, false);
}
private static String changeFirstCharacterCase(String str, boolean capitalize) {
if (str == null || str.length() == 0) {
return str;
}
StringBuilder sb = new StringBuilder(str.length());
if (capitalize) {
sb.append(Character.toUpperCase(str.charAt(0)));
} else {
sb.append(Character.toLowerCase(str.charAt(0)));
}
sb.append(str.substring(1));
return sb.toString();
}
/**
* Extract the filename from the given path, e.g. "mypath/myfile.txt" ->
* "myfile.txt".
*
* @param path the file path (may be <code>null</code>)
* @return the extracted filename, or <code>null</code> if none
*/
public static String getFilename(String path) {
if (path == null) {
return null;
}
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path);
}
/**
* Extract the filename extension from the given path, e.g.
* "mypath/myfile.txt" -> "txt".
*
* @param path the file path (may be <code>null</code>)
* @return the extracted filename extension, or <code>null</code> if none
*/
public static String getFilenameExtension(String path) {
if (path == null) {
return null;
}
int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
if (extIndex == -1) {
return null;
}
int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
if (folderIndex > extIndex) {
return null;
}
return path.substring(extIndex + 1);
}
/**
* Strip the filename extension from the given path, e.g.
* "mypath/myfile.txt" -> "mypath/myfile".
*
* @param path the file path (may be <code>null</code>)
* @return the path with stripped filename extension, or <code>null</code>
* if none
*/
public static String stripFilenameExtension(String path) {
if (path == null) {
return null;
}
int extIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
if (extIndex == -1) {
return path;
}
int folderIndex = path.lastIndexOf(FOLDER_SEPARATOR);
if (folderIndex > extIndex) {
return path;
}
return path.substring(0, extIndex);
}
/**
* Apply the given relative path to the given path, assuming standard Java
* folder separation (i.e. "/" separators).
*
* @param path the path to start from (usually a full file path)
* @param relativePath the relative path to apply (relative to the full file path
* above)
* @return the full file path that results from applying the relative path
*/
public static String applyRelativePath(String path, String relativePath) {
int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
if (separatorIndex != -1) {
String newPath = path.substring(0, separatorIndex);
if (!relativePath.startsWith(FOLDER_SEPARATOR)) {
newPath += FOLDER_SEPARATOR;
}
return newPath + relativePath;
} else {
return relativePath;
}
}
/**
* Normalize the path by suppressing sequences like "path/.." and inner
* simple dots.
* <p>
* The result is convenient for path comparison. For other uses, notice that
* Windows separators ("\") are replaced by simple slashes.
*
* @param path the original path
* @return the normalized path
*/
public static String cleanPath(String path) {
if (path == null) {
return null;
}
String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);
// Strip prefix from path to analyze, to not treat it as part of the
// first path element. This is necessary to correctly parse paths like
// "file:core/../core/io/Resource.class", where the ".." should just
// strip the first "core" directory while keeping the "file:" prefix.
int prefixIndex = pathToUse.indexOf(":");
String prefix = "";
if (prefixIndex != -1) {
prefix = pathToUse.substring(0, prefixIndex + 1);
pathToUse = pathToUse.substring(prefixIndex + 1);
}
if (pathToUse.startsWith(FOLDER_SEPARATOR)) {
prefix = prefix + FOLDER_SEPARATOR;
pathToUse = pathToUse.substring(1);
}
String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR);
List<String> pathElements = new LinkedList<String>();
int tops = 0;
for (int i = pathArray.length - 1; i >= 0; i--) {
String element = pathArray[i];
if (CURRENT_PATH.equals(element)) {
// Points to current directory - drop it.
} else if (TOP_PATH.equals(element)) {
// Registering top path found.
tops++;
} else {
if (tops > 0) {
// Merging path element with element corresponding to top
// path.
tops--;
} else {
// Normal path element found.
pathElements.add(0, element);
}
}
}
// Remaining top paths need to be retained.
for (int i = 0; i < tops; i++) {
pathElements.add(0, TOP_PATH);
}
return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR);
}
/**
* Compare two paths after normalization of them.
*
* @param path1 first path for comparison
* @param path2 second path for comparison
* @return whether the two paths are equivalent after normalization
*/
public static boolean pathEquals(String path1, String path2) {
return cleanPath(path1).equals(cleanPath(path2));
}
/**
* Parse the given <code>localeString</code> value into a
* {@link Locale}.
* <p>
* This is the inverse operation of {@link Locale#toString
* Locale's toString}.
*
* @param localeString the locale string, following <code>Locale's</code>
* <code>toString()</code> format ("en", "en_UK", etc); also
* accepts spaces as separators, as an alternative to underscores
* @return a corresponding <code>Locale</code> instance
*/
public static Locale parseLocaleString(String localeString) {
String[] parts = tokenizeToStringArray(localeString, "_ ", false, false);
String language = (parts.length > 0 ? parts[0] : "");
String country = (parts.length > 1 ? parts[1] : "");
validateLocalePart(language);
validateLocalePart(country);
String variant = "";
if (parts.length >= 2) {
// There is definitely a variant, and it is everything after the
// country
// code sans the separator between the country code and the variant.
int endIndexOfCountryCode = localeString.indexOf(country) + country.length();
// Strip off any leading '_' and whitespace, what's left is the
// variant.
variant = trimLeadingWhitespace(localeString.substring(endIndexOfCountryCode));
if (variant.startsWith("_")) {
variant = trimLeadingCharacter(variant, '_');
}
}
return (language.length() > 0 ? new Locale(language, country, variant) : null);
}
private static void validateLocalePart(String localePart) {
for (int i = 0; i < localePart.length(); i++) {
char ch = localePart.charAt(i);
if (ch != '_' && ch != ' ' && !Character.isLetterOrDigit(ch)) {
throw new IllegalArgumentException("Locale part \"" + localePart + "\" contains invalid characters");
}
}
}
/**
* Determine the RFC 3066 compliant language tag, as used for the HTTP
* "Accept-Language" header.
*
* @param locale the Locale to transform to a language tag
* @return the RFC 3066 compliant language tag as String
*/
public static String toLanguageTag(Locale locale) {
return locale.getLanguage() + (hasText(locale.getCountry()) ? "-" + locale.getCountry() : "");
}
// ---------------------------------------------------------------------
// Convenience methods for working with String arrays
// ---------------------------------------------------------------------
/**
* Append the given String to the given String array, returning a new array
* consisting of the input array contents plus the given String.
*
* @param array the array to append to (can be <code>null</code>)
* @param str the String to append
* @return the new array (never <code>null</code>)
*/
public static String[] addStringToArray(String[] array, String str) {
if (ObjectUtils.isEmpty(array)) {
return new String[]{str};
}
String[] newArr = new String[array.length + 1];
System.arraycopy(array, 0, newArr, 0, array.length);
newArr[array.length] = str;
return newArr;
}
/**
* Concatenate the given String arrays into one, with overlapping array
* elements included twice.
* <p>
* The order of elements in the original arrays is preserved.
*
* @param array1 the first array (can be <code>null</code>)
* @param array2 the second array (can be <code>null</code>)
* @return the new array (<code>null</code> if both given arrays were
* <code>null</code>)
*/
public static String[] concatenateStringArrays(String[] array1, String[] array2) {
if (ObjectUtils.isEmpty(array1)) {
return array2;
}
if (ObjectUtils.isEmpty(array2)) {
return array1;
}
String[] newArr = new String[array1.length + array2.length];
System.arraycopy(array1, 0, newArr, 0, array1.length);
System.arraycopy(array2, 0, newArr, array1.length, array2.length);
return newArr;
}
/**
* Merge the given String arrays into one, with overlapping array elements
* only included once.
* <p>
* The order of elements in the original arrays is preserved (with the
* exception of overlapping elements, which are only included on their first
* occurrence).
*
* @param array1 the first array (can be <code>null</code>)
* @param array2 the second array (can be <code>null</code>)
* @return the new array (<code>null</code> if both given arrays were
* <code>null</code>)
*/
public static String[] mergeStringArrays(String[] array1, String[] array2) {
if (ObjectUtils.isEmpty(array1)) {
return array2;
}
if (ObjectUtils.isEmpty(array2)) {
return array1;
}
List<String> result = new ArrayList<String>();
result.addAll(Arrays.asList(array1));
for (String str : array2) {
if (!result.contains(str)) {
result.add(str);
}
}
return toStringArray(result);
}
/**
* Turn given source String array into sorted array.
*
* @param array the source array
* @return the sorted array (never <code>null</code>)
*/
public static String[] sortStringArray(String[] array) {
if (ObjectUtils.isEmpty(array)) {
return new String[0];
}
Arrays.sort(array);
return array;
}
/**
* Copy the given Collection into a String array. The Collection must
* contain String elements only.
*
* @param collection the Collection to copy
* @return the String array (<code>null</code> if the passed-in Collection
* was <code>null</code>)
*/
public static String[] toStringArray(Collection<String> collection) {
if (collection == null) {
return null;
}
return collection.toArray(new String[collection.size()]);
}
/**
* Copy the given Enumeration into a String array. The Enumeration must
* contain String elements only.
*
* @param enumeration the Enumeration to copy
* @return the String array (<code>null</code> if the passed-in Enumeration
* was <code>null</code>)
*/
public static String[] toStringArray(Enumeration<String> enumeration) {
if (enumeration == null) {
return null;
}
List<String> list = Collections.list(enumeration);
return list.toArray(new String[list.size()]);
}
/**
* Trim the elements of the given String array, calling
* <code>String.trim()</code> on each of them.
*
* @param array the original String array
* @return the resulting array (of the same size) with trimmed elements
*/
public static String[] trimArrayElements(String[] array) {
if (ObjectUtils.isEmpty(array)) {
return new String[0];
}
String[] result = new String[array.length];
for (int i = 0; i < array.length; i++) {
String element = array[i];
result[i] = (element != null ? element.trim() : null);
}
return result;
}
/**
* Remove duplicate Strings from the given array. Also sorts the array, as
* it uses a TreeSet.
*
* @param array the String array
* @return an array without duplicates, in natural sort order
*/
public static String[] removeDuplicateStrings(String[] array) {
if (ObjectUtils.isEmpty(array)) {
return array;
}
Set<String> set = new TreeSet<String>();
for (String element : array) {
set.add(element);
}
return toStringArray(set);
}
/**
* Split a String at the first occurrence of the delimiter. Does not include
* the delimiter in the result.
*
* @param toSplit the string to split
* @param delimiter to split the string up with
* @return a two element array with index 0 being before the delimiter, and
* index 1 being after the delimiter (neither element includes the
* delimiter); or <code>null</code> if the delimiter wasn't found in
* the given input String
*/
public static String[] split(String toSplit, String delimiter) {
if (!hasLength(toSplit) || !hasLength(delimiter)) {
return null;
}
int offset = toSplit.indexOf(delimiter);
if (offset < 0) {
return null;
}
String beforeDelimiter = toSplit.substring(0, offset);
String afterDelimiter = toSplit.substring(offset + delimiter.length());
return new String[]{beforeDelimiter, afterDelimiter};
}
public static List<String> splitToList(String toSplit, String delimiterRegex) {
List<String> strList = null;
if (!hasLength(toSplit) || !hasLength(delimiterRegex)) {
return strList;
}
String[] strs = toSplit.split(delimiterRegex);
strList = new ArrayList<String>();
for (String str : strs) {
strList.add(str);
}
return strList;
}
/**
* Take an array Strings and split each element based on the given
* delimiter. A <code>Properties</code> instance is then generated, with the
* left of the delimiter providing the key, and the right of the delimiter
* providing the value.
* <p>
* Will trim both the key and value before adding them to the
* <code>Properties</code> instance.
*
* @param array the array to process
* @param delimiter to split each element using (typically the equals symbol)
* @return a <code>Properties</code> instance representing the array
* contents, or <code>null</code> if the array to process was null
* or empty
*/
public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter) {
return splitArrayElementsIntoProperties(array, delimiter, null);
}
/**
* Take an array Strings and split each element based on the given
* delimiter. A <code>Properties</code> instance is then generated, with the
* left of the delimiter providing the key, and the right of the delimiter
* providing the value.
* <p>
* Will trim both the key and value before adding them to the
* <code>Properties</code> instance.
*
* @param array the array to process
* @param delimiter to split each element using (typically the equals symbol)
* @param charsToDelete one or more characters to remove from each element prior to
* attempting the split operation (typically the quotation mark
* symbol), or <code>null</code> if no removal should occur
* @return a <code>Properties</code> instance representing the array
* contents, or <code>null</code> if the array to process was
* <code>null</code> or empty
*/
public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter, String charsToDelete) {
if (ObjectUtils.isEmpty(array)) {
return null;
}
Properties result = new Properties();
for (String element : array) {
if (charsToDelete != null) {
element = deleteAny(element, charsToDelete);
}
String[] splittedElement = split(element, delimiter);
if (splittedElement == null) {
continue;
}
result.setProperty(splittedElement[0].trim(), splittedElement[1].trim());
}
return result;
}
/**
* Tokenize the given String into a String array via a StringTokenizer.
* Trims tokens and omits empty tokens.
* <p>
* The given delimiters string is supposed to consist of any number of
* delimiter characters. Each of those characters can be used to separate
* tokens. A delimiter is always a single character; for multi-character
* delimiters, consider using <code>delimitedListToStringArray</code>
*
* @param str the String to tokenize
* @param delimiters the delimiter characters, assembled as String (each of those
* characters is individually considered as delimiter).
* @return an array of the tokens
* @see StringTokenizer
* @see String#trim()
* @see #delimitedListToStringArray
*/
public static String[] tokenizeToStringArray(String str, String delimiters) {
return tokenizeToStringArray(str, delimiters, true, true);
}
/**
* Tokenize the given String into a String array via a StringTokenizer.
* <p>
* The given delimiters string is supposed to consist of any number of
* delimiter characters. Each of those characters can be used to separate
* tokens. A delimiter is always a single character; for multi-character
* delimiters, consider using <code>delimitedListToStringArray</code>
*
* @param str the String to tokenize
* @param delimiters the delimiter characters, assembled as String (each of those
* characters is individually considered as delimiter)
* @param trimTokens trim the tokens via String's <code>trim</code>
* @param ignoreEmptyTokens omit empty tokens from the result array (only applies to
* tokens that are empty after trimming; StringTokenizer will not
* consider subsequent delimiters as token in the first place).
* @return an array of the tokens (<code>null</code> if the input String was
* <code>null</code>)
* @see StringTokenizer
* @see String#trim()
* @see #delimitedListToStringArray
*/
public static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens,
boolean ignoreEmptyTokens) {
if (str == null) {
return null;
}
StringTokenizer st = new StringTokenizer(str, delimiters);
List<String> tokens = new ArrayList<String>();
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (trimTokens) {
token = token.trim();
}
if (!ignoreEmptyTokens || token.length() > 0) {
tokens.add(token);
}
}
return toStringArray(tokens);
}
/**
* Take a String which is a delimited list and convert it to a String array.
* <p>
* A single delimiter can consists of more than one character: It will still
* be considered as single delimiter string, rather than as bunch of
* potential delimiter characters - in contrast to
* <code>tokenizeToStringArray</code>.
*
* @param str the input String
* @param delimiter the delimiter between elements (this is a single delimiter,
* rather than a bunch individual delimiter characters)
* @return an array of the tokens in the list
* @see #tokenizeToStringArray
*/
public static String[] delimitedListToStringArray(String str, String delimiter) {
return delimitedListToStringArray(str, delimiter, null);
}
/**
* Take a String which is a delimited list and convert it to a String array.
* <p>
* A single delimiter can consists of more than one character: It will still
* be considered as single delimiter string, rather than as bunch of
* potential delimiter characters - in contrast to
* <code>tokenizeToStringArray</code>.
*
* @param str the input String
* @param delimiter the delimiter between elements (this is a single delimiter,
* rather than a bunch individual delimiter characters)
* @param charsToDelete a set of characters to delete. Useful for deleting unwanted
* line breaks: e.g. "\r\n\f" will delete all new lines and line
* feeds in a String.
* @return an array of the tokens in the list
* @see #tokenizeToStringArray
*/
public static String[] delimitedListToStringArray(String str, String delimiter, String charsToDelete) {
if (str == null) {
return new String[0];
}
if (delimiter == null) {
return new String[]{str};
}
List<String> result = new ArrayList<String>();
if ("".equals(delimiter)) {
for (int i = 0; i < str.length(); i++) {
result.add(deleteAny(str.substring(i, i + 1), charsToDelete));
}
} else {
int pos = 0;
int delPos;
while ((delPos = str.indexOf(delimiter, pos)) != -1) {
result.add(deleteAny(str.substring(pos, delPos), charsToDelete));
pos = delPos + delimiter.length();
}
if (str.length() > 0 && pos <= str.length()) {
// Add rest of String, but not in case of empty input.
result.add(deleteAny(str.substring(pos), charsToDelete));
}
}
return toStringArray(result);
}
/**
* Convert a CSV list into an array of Strings.
*
* @param str the input String
* @return an array of Strings, or the empty array in case of empty input
*/
public static String[] commaDelimitedListToStringArray(String str) {
return delimitedListToStringArray(str, ",");
}
/**
* Convenience method to convert a CSV string list to a set. Note that this
* will suppress duplicates.
*
* @param str the input String
* @return a Set of String entries in the list
*/
public static Set<String> commaDelimitedListToSet(String str) {
Set<String> set = new TreeSet<String>();
String[] tokens = commaDelimitedListToStringArray(str);
for (String token : tokens) {
set.add(token);
}
return set;
}
/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for <code>toString()</code> implementations.
*
* @param coll the Collection to display
* @param delim the delimiter to use (probably a ",")
* @param prefix the String to start each element with
* @param suffix the String to end each element with
* @return the delimited String
*/
public static String collectionToDelimitedString(Collection<?> coll, String delim, String prefix, String suffix) {
if (CollectionUtils.isEmpty(coll)) {
return "";
}
StringBuilder sb = new StringBuilder();
Iterator<?> it = coll.iterator();
while (it.hasNext()) {
sb.append(prefix).append(it.next()).append(suffix);
if (it.hasNext()) {
sb.append(delim);
}
}
return sb.toString();
}
/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for <code>toString()</code> implementations.
*
* @param coll the Collection to display
* @param delim the delimiter to use (probably a ",")
* @return the delimited String
*/
public static String collectionToDelimitedString(Collection<?> coll, String delim) {
return collectionToDelimitedString(coll, delim, "", "");
}
/**
* Convenience method to return a Collection as a CSV String. E.g. useful
* for <code>toString()</code> implementations.
*
* @param coll the Collection to display
* @return the delimited String
*/
public static String collectionToCommaDelimitedString(Collection<?> coll) {
return collectionToDelimitedString(coll, ",");
}
/**
* Convenience method to return a String array as a delimited (e.g. CSV)
* String. E.g. useful for <code>toString()</code> implementations.
*
* @param arr the array to display
* @param delim the delimiter to use (probably a ",")
* @return the delimited String
*/
public static String arrayToDelimitedString(Object[] arr, String delim) {
if (ObjectUtils.isEmpty(arr)) {
return "";
}
if (arr.length == 1) {
return ObjectUtils.nullSafeToString(arr[0]);
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (i > 0) {
sb.append(delim);
}
sb.append(arr[i]);
}
return sb.toString();
}
/**
* Convenience method to return a String array as a CSV String. E.g. useful
* for <code>toString()</code> implementations.
*
* @param arr the array to display
* @return the delimited String
*/
public static String arrayToCommaDelimitedString(Object[] arr) {
return arrayToDelimitedString(arr, ",");
}
public static String[] getMiddle(String uri) {
String[] temp = uri.split(FOLDER_SEPARATOR);
return temp;
}
/**
* @param s
* @return 如果<tt>s</tt>为<tt>null</tt>或空白字符串返回<tt>true</tt>
*/
public static boolean isBlank(String s) {
return s == null || s.trim().length() == 0;
}
public static boolean isNotBlank(String... strs) {
boolean isNotNull = true;
if (strs.length == 0) {
return false;
}
for (String str : strs) {
if (StringUtils.isBlank(str)) {
isNotNull = false;
break;
}
}
return isNotNull;
}
/**
* 截取字符串,按照系统默认的字符集,截取后的后缀为“...”
*
* @param target 被截取的原字符串,此方法执行前会先<tt>trim</tt>
* @param maxBytes 截取后字符串的最大<tt>byte</tt>数,包括截取后的字符串的后缀
* @return
* @see #substring(String, String, int, String)
*/
public static String substring(String target, int maxBytes) {
return substring(target.trim(), Charset.defaultCharset().name(), maxBytes, "...");
}
/**
* 截取字符串
*
* @param target 被截取的原字符串
* @param charset 字符串的字符集
* @param maxBytes 截取后字符串的最大<tt>byte</tt>数,包括截取后的字符串的后缀
* @param append 字符串被截去后的后缀
* @return
*/
public static String substring(String target, String charset, int maxBytes, String append) {
try {
int count = getBytes(target, charset).length;
if (count <= maxBytes) {
return target;
} else {
int bytesCount = 0;
char[] replace = new char[getBytes(append, charset).length];
int j = 0;
int bound = maxBytes - getBytes(append, charset).length;
for (int i = 0; i < target.length(); i++) {
char c = target.charAt(i);
bytesCount = c > 255 ? bytesCount + 2 : bytesCount + 1;
if (bytesCount > maxBytes) {
return target.substring(0, i - j).concat(append);
}
if (bytesCount > bound) {
replace[j++] = c;
}
}
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
throw new RuntimeException("Unreachable!");
}
public static String substring(String src, int start_idx, int end_idx) {
byte[] b = src.getBytes();
String tgt = "";
for (int i = start_idx; i <= end_idx; i++) {
tgt += (char) b[i];
}
return tgt;
}
private static byte[] getBytes(String s, String charset) throws UnsupportedEncodingException {
return s.getBytes(charset);
}
public static String GBKToUTF(String str) {
String utfStr = null;
try {
utfStr = new String(str.getBytes("GBK"), StandardCharsets.UTF_8);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return utfStr;
}
public static String UTFToGBK(String str) {
String utfStr = null;
try {
utfStr = new String(str.getBytes(StandardCharsets.UTF_8), "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return utfStr;
}
public static String ISOToGBK(String str) {
String utfStr = null;
try {
utfStr = new String(str.getBytes("ISO8859_1"), "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return utfStr;
}
// public static String getPasWordStr(String password) {
// String passStr = "";
// MessageDigest digester = null;
// try {
// digester = MessageDigest.getInstance("SHA");
// digester.update(password.getBytes("utf-8"));
// byte[] bytes = digester.digest();
// passStr = new String(Hex.encodeHex(bytes));
// } catch (Exception e) {
// e.printStackTrace();
// }
// return passStr;
// }
/**
* 将字符转换成map {row:20000,pageno:1,startdate:2008-9-10,enddate:2008-10-1}
*
* @return
* @author hudaowan
* @date Nov 3, 2008 10:03:26 AM
*/
public static Map<String, String> strToMap(String str) {
Map<String, String> map = new HashMap<String, String>();
if (!isBlank(str)) {
String strObj = str.substring(1, str.length() - 1);
String[] obj = strObj.split(",");
for (String value : obj) {
String[] key = value.split(":");
map.put(key[0], key[1]);
}
}
return map;
}
/**
* 将map转换成字符
*
* @param map
* @return
* @author hudaowan
* @date Nov 3, 2008 10:21:31 AM
*/
public static String mapToStr(Map<String, String> map) {
String str = "";
if (map != null) {
for (Map.Entry<String, String> obj : map.entrySet()) {
String key = obj.getKey();
String value = obj.getValue();
str += key + ":" + value + ",";
}
}
if (str.length() > 0) {
str = "{" + str.substring(0, str.length() - 1) + "}";
}
return str;
}
/**
* 用<tt>seperator</tt>连接字符串,例如将数组{"a","b","c"}使用';'连接,得到"a;b;c",忽略
* <tt>null<tt>和空白字符串
* <p>
* &#64;see #join(String[], String, boolean, boolean)
* &#64;param s 需要连接的字符串数组
* &#64;param seperator 分隔符
* &#64;return 连接好的字符串或""
*
* @throws NullPointerException 如果<tt>s</tt>或<tt>seperator</tt>为<tt>null</tt>
*/
public static String join(String[] s, String seperator) {
return join(s, seperator, true, true);
}
/**
* 用<tt>seperator</tt>连接字符串,例如将字符串列表使用','连接,得到"a,b,c",忽略 <tt>null<tt>和空白字符串
* <p>
* &#64;see #join(List<String>, String, boolean, boolean)
* &#64;param strList 需要连接的字符串列表
* &#64;param seperator 分隔符
* &#64;return 连接好的字符串或""
*
* @throws NullPointerException 如果<tt>strList</tt>或<tt>seperator</tt>为<tt>null</tt>
*/
public static String join(List<String> strList, String seperator) {
return join(strList, seperator, true, true);
}
/**
* 用<tt>seperator</tt>连接字符串,例如将数组{"a","b","c"}使用';'连接,得到"a;b;c"
*
* @param s 需要连接的字符串数组
* @param seperator 分隔符
* @param ignoreBlank 是否忽略空字符串,通过<tt>String.trim().length() == 0</tt>判断空字符串
* @param ignoreNull 是否忽略<tt>null</tt>
* @return 连接好的字符串或""
* @throws NullPointerException 如果<tt>s</tt>或<tt>seperator</tt>为<tt>null</tt>
*/
public static String join(String[] s, String seperator, boolean ignoreBlank, boolean ignoreNull) {
if (s == null || seperator == null)
throw new NullPointerException();
StringBuilder result = new StringBuilder(256);
for (String s_ : s) {
if (ignoreNull && s_ == null)
continue;
else if (ignoreBlank && s_.trim().length() == 0)
continue;
result.append(s_);
result.append(seperator);
}
int i = result.length();
if (i > 0)
return result.substring(0, i - seperator.length());
else
return "";
}
/**
* 用<tt>seperator</tt>连接字符串,例如将字符串列表使用','连接,得到"a,b,c",忽略
*
* @param strList 需要连接的字符串数组
* @param seperator 分隔符
* @param ignoreBlank 是否忽略空字符串,通过<tt>String.trim().length() == 0</tt>判断空字符串
* @param ignoreNull 是否忽略<tt>null</tt>
* @return 连接好的字符串或""
* @throws NullPointerException 如果<tt>s</tt>或<tt>seperator</tt>为<tt>null</tt>
*/
public static String join(List<String> strList, String seperator, boolean ignoreBlank, boolean ignoreNull) {
if (strList == null || seperator == null)
throw new NullPointerException();
StringBuilder result = new StringBuilder(256);
for (String s_ : strList) {
if (ignoreNull && s_ == null)
continue;
else if (ignoreBlank && s_.trim().length() == 0)
continue;
result.append(s_);
result.append(seperator);
}
int i = result.length();
if (i > 0)
return result.substring(0, i - seperator.length());
else
return "";
}
public static <T> String join(Collection<T> list, String seperator) {
if (list == null || seperator == null)
throw new NullPointerException();
StringBuilder result = new StringBuilder(256);
for (T t : list) {
if (t == null)
continue;
else if (t instanceof String && ((String) t).trim().length() == 0)
continue;
result.append(t);
result.append(seperator);
}
int i = result.length();
if (i > 0)
return result.substring(0, i - seperator.length());
else
return "";
}
/**
* 给列表中每个元素的前后增加一样的指定字符
*
* @param list
* @param speChar
* @return
*/
public static List<String> concatSpeChar(Collection<String> list, String speChar) {
return concatSpeChar(list, speChar, speChar);
}
/**
* 给列表中每个元素的前后增加指定字符
*
* @param list
* @param beforChar
* @param endChar
* @return
*/
public static List<String> concatSpeChar(Collection<String> list, String beforChar, String endChar) {
if (null == list) {
return Collections.EMPTY_LIST;
}
List<String> result = new ArrayList<>();
for (String s : list) {
result.add(beforChar + s + endChar);
}
return result;
}
/**
* 将CamelCase(驼峰)转换成大写字母,以“_”为间隔,例如abcFoo转换成ABC_FOO
*
* @param s
* @return
*/
public static String camelToUnderlineUpper(String s) {
final String pattern = "[A-Z]*[a-z0-9]+|[A-Z0-9]+";
Pattern p = Pattern.compile(pattern); // the expression
Matcher m = p.matcher(s); // the source
String r = null;
while (m.find()) {
if (r != null) {
r = r + "_" + m.group().toUpperCase();
} else {
r = m.group().toUpperCase();
}
}
return r;
}
/**
* 将CamelCase(驼峰)转换成小写字母,以“_”为间隔,例如abcFoo转换成abc_foo
*
* @param s
* @return
*/
public static String camelToUnderlineLower(String s) {
String r = camelToUnderlineUpper(s);
return r != null ? r.toLowerCase() : null;
}
/**
* 将下划线分隔字母转换成CamelCase,以“_”为间隔,例如ABC_FOO转换成abcFoo
*
* @param s
* @return
*/
public static String underlineToCamel(String s) {
String[] tokens = s.split("_");
String r = tokens[0].toLowerCase();
for (int i = 1; i < tokens.length; i++) {
r += (tokens[i].substring(0, 1).toUpperCase() + tokens[i].substring(1).toLowerCase());
}
return r;
}
public static String trim(String str) {
str = str.replace(' ', ' ');
return str.trim();
}
public static Object convertStringToDataType(String value, String dataType) {
// 如果结果返回null,向上也返回null,不要返回0,因为0也是一个值不同于null
if ("INTEGER".equals(dataType)) {
return Integer.valueOf(value);
} else if ("LONG".equals(dataType)) {
return Long.valueOf(value);
} else if ("DOUBLE".equals(dataType) || "FLOAT".equals(dataType) || "PERCENT".equals(dataType)
|| "CURRENCY".equals(dataType) || "TIME".equals(dataType)) {
BigDecimal fixValue = new BigDecimal(value);
return fixValue.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); // 四舍五入,保留两位小数
} else {
return value;
}
}
/**
* 根据数字生成excel列表头,最大到zz
*
* @param i
* @return
*/
public static String i2s(int i) {
String s = "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";
String[] sArray = s.split(" ");
if (i < 1)
return "";
if ((i / 26) == 0)
return sArray[i % 26 - 1];
else {
if (i % 26 == 0)
return (i2s((i / 26) - 1)) + sArray[26 - 1];
else
return sArray[(i / 26) - 1] + sArray[i % 26 - 1];
}
}
/**
* 根据数字生成excel列表头,最大受int最大值限制
*
* @param num
* @return
*/
public static String getExcelColumnLabel(int num) {
String temp = "";
double i = Math.floor(Math.log(25.0 * (num) / 26.0 + 1) / Math.log(26)) + 1;
if (i > 1) {
double sub = num - 26 * (Math.pow(26, i - 1) - 1) / 25;
for (double j = i; j > 0; j--) {
temp = temp + (char) (sub / Math.pow(26, j - 1) + 65);
sub = sub % Math.pow(26, j - 1);
}
} else {
temp = temp + (char) (num + 65);
}
return temp;
}
public static String firstChartoUpperCase(String str) {
return str.replaceFirst(str.substring(0, 1), str.substring(0, 1).toUpperCase());
}
/**
* 科学技术法转为正常数字,例如:1.24E7转为12400000
*
* @param str
* @return
*/
public static String kxjsConvert(String str) {
if (isKxjs(str)) {
BigDecimal db = new BigDecimal(str);
return db.toPlainString();
} else {
return str;
}
}
/**
* 验证当前字符串是否是科学计数法
*
* @param str
* @return
*/
public static boolean isKxjs(String str) {
return str != null && str.matches("^((-?\\d+\\.?\\d+)[Ee]{1}([-+]?\\d+))$");
}
public static boolean isNumber(String str) {
return StringUtils.isNotBlank(str) && str.matches("^(\\-|\\+)?\\d+(\\.\\d+)?$");
}
public static boolean isBigDecimal(Object value) {
try {
if (value != null) {
new BigDecimal(String.valueOf(value));
return true;
}
} catch (Exception e) {
}
return false;
}
public static boolean isDateStr(String str, String dateFormat) {
boolean convertSuccess = true;
SimpleDateFormat format = new SimpleDateFormat(dateFormat, Locale.US);
try {
format.setLenient(false);// 设置lenient为false.
// 否则SimpleDateFormat会比较宽松地验证日期,比如2007/02/29会被接受,并转换成2007/03/01
format.parse(str);
} catch (Exception e) {
convertSuccess = false;
}
return convertSuccess;
}
/**
* 转义字符串中的正则表达式使用的特殊字符
*
* @param str
* @return
* @date: 2016年7月23日
* @author peng.xu
*/
public static String escapeRegexp(String str) {
if (StringUtils.isNotBlank(str)) {
String[] charArray = new String[]{"\\", "*", ".", "?", "+", "$", "^", "[", "]", "(", ")", "{", "}", "|",
"!"};
for (String s : charArray) {
str = str.replace(s, "\\" + s);
}
}
return str;
}
/**
* 获取json字符串中对应属性的值
*
* @param jsonStr
* @param key
* @param jsonRegex json对应的正则表达式规则, 如果不为空则需要校验正则匹配
* @return
* @date: 2016年8月15日
* @author peng.xu
*/
public static String getValueOfJson(String jsonStr, String key, String jsonRegex) {
String value = null;
if (StringUtils.isNotBlank(jsonStr) && StringUtils.isNotBlank(key)) {
if (StringUtils.isBlank(jsonRegex) || (StringUtils.isNotBlank(jsonRegex) && jsonStr.matches(jsonRegex))) {
try {
Object valueObj = JSON.parseObject(jsonStr).get(key);
if (valueObj != null) {
value = valueObj.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
return value;
}
/**
* 比较字符串大小,优先按照字母序,再按照大小写排序
*/
public static int compareStringIgnoreCase(String str1, String str2) {
int result = 0;
if (StringUtils.isBlank(str1)) {
result = StringUtils.isBlank(str2) ? 0 : -1;
} else if (StringUtils.isBlank(str2)) {
result = 1;
} else {
result = str1.toUpperCase().compareToIgnoreCase(str2);
if (result == 0) {
result = str1.compareTo(str2);
}
}
return result;
}
/**
* 根据指定长度 分隔字符串
*
* @param str 需要处理的字符串
* @param length 分隔长度
* @return 字符串集合
*/
public static List<String> splitString(String str, int length) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < str.length(); i += length) {
int endIndex = i + length;
if (endIndex <= str.length()) {
list.add(str.substring(i, i + length));
} else {
list.add(str.substring(i, str.length() - 1));
}
}
return list;
}
/**
* 使用map中值替换字符串中的${key}参数
*
* @date: 2018-12-07
* @author xupeng
*/
public static String replaceParam(String str, Map<String, ?> paramMap) {
if (StringUtils.isNotBlank(str) && CollectionUtils.isNotEmpty(paramMap)) {
for (Map.Entry<String, ?> entry : paramMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue() != null ? String.valueOf(entry.getValue()) : null;
if (StringUtils.isNotBlank(value)) {
value = Matcher.quoteReplacement(value);
str = str.replaceAll("\\$\\{" + key + "\\}", value);
}
}
}
return str;
}
/**
* 替换掉所有控制字符,范围[\x00-\x1F\x7F]即ASCII码字符0-31加127共33个字符
*
* @author xupeng
* @date: 2019-01-25
*/
public static String replaceControlChar(String str) {
return str != null ? str.replaceAll("\\p{Cntrl}", "") : null;
}
/**
* 按照正则提取字符串
*
* @param regex
* @param source
* @param index
* @return
*/
public static String getMatcher(String regex, String source, int index) {
String result = "";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(source);
while (matcher.find()) {
result = matcher.group(index);
}
return result;
}
public static String replaceMysql(String content) {
if (isBlank(content)) {
return content;
}
content = content.replace("\\", "\\\\");
content = content.replace("'", "\\'");
content = content.replace("\"", "\\\"");
return content;
}
/**
* 首字母大写
*
* @param var
* @return
*/
public static String captureName(String var) {
if (isBlank(var)) {
return var;
}
char[] cs = var.toCharArray();
char first = cs[0];
//只有在 a-z的范围内才做转换
if (first >= 97 && first <= 122) {
cs[0] -= 32;
return String.valueOf(cs);
}
return var;
}
public static List<String> getImgs(String content) {
String img = "";
Pattern p_image;
Matcher m_image;
List<String> images = new ArrayList<>();
String regEx_img = "(<img.*src\\s*=\\s*(.*?)[^>]*?>)";
p_image = Pattern.compile(regEx_img, Pattern.CASE_INSENSITIVE);
m_image = p_image.matcher(content);
while (m_image.find()) {
img = m_image.group();
Matcher m = Pattern.compile("src\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(img);
while (m.find()) {
images.add(m.group(1));
}
}
return images;
}
public static JSONObject safeParseJSONObject(String json) {
try {
return JSON.parseObject(json);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> T safeParseObject(String json, Class<T> clazz) {
try {
return JSON.parseObject(json, clazz);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> List<T> safeParseObjectList(String json, Class<T> clazz) {
try {
return JSON.parseArray(json, clazz);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static final Map<String, String> ChCharToEnMapping = new HashMap() {{
put(",", ",");
put(":", ":");
put("。", ".");
put("!", "!");
put("?", "?");
put("【", "[");
put("】", "]");
put("(", "(");
put(")", ")");
put("‘", "'");
put("’", "'");
put("“", "\"");
put("”", "\"");
}};
/**
* 全角转半角
*/
public static String dbc2Sbc(String str) {
StringBuilder buf = new StringBuilder();
if (StringUtils.isNotBlank(str)) {
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch == 12288) { // 全角空格
ch = 32; // 半角空格
} else {
ch -= 65248; // 全角半角转换间隔
}
String chStr = String.valueOf(ch);
if (ChCharToEnMapping.containsKey(chStr)) { // 中文字符转英文字符
buf.append(ChCharToEnMapping.get(chStr));
} else if (ch >= 32 && ch <= 126) {
buf.append(chStr);
} else {
buf.append(str.charAt(i));
}
}
}
return buf.toString();
}
public static int str2Int(String str) {
if (StringUtils.isNumber(str)) {
return Integer.parseInt(str);
}
return 0;
}
private static Set<Character> special = new HashSet<Character>() {{
add(' ');
add(',');
add(',');
add('!');
add('@');
add('#');
add('$');
add('%');
add('^');
add('&');
add('*');
add('(');
add(')');
add('!');
add('@');
add('#');
add('¥');
add('%');
add('*');
add('(');
add(')');
add('‘');
add('[');
add(']');
add('{');
add('}');
add('?');
add('?');
add(',');
add('。');
add('、');
add('《');
add('》');
add(';');
add('<');
add('>');
add('|');
add('.');
add('-');
add('_');
add('—');
add('·');
add('\ufffc'); // 在实现textView的富文本时,如果添加一张图片后,如果直接发送textView的内容时,图片会被字符串“\U0000fffc”替换
}};
/**
* 判断一个字符是否是特殊字符(special 里面的字符)
*/
private static boolean isSpecialCharacter(Character c) {
if (special.contains(c)) {
return false;
}
return true;
}
/**
* 把一个字符里面的特殊字符剔除掉
*/
public static String removeSpecialChar(String word) {
if (word == null) {
return word;
}
StringBuffer sb = new StringBuffer();
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (isSpecialCharacter(chars[i])) {
sb.append(chars[i]);
}
}
return sb.toString();
}
/**
* 逗号等分隔符转空格,去两边空格,中间多个空格转一个空格
*/
public static String cleanStr(String str) {
// 去两边空格,转小写,中间多个空格转一个空格
if (str != null) {
String clean = str
.replaceAll(",|,|、|;|;", " ")
.trim()
.replaceAll("\\s{1,}", " ");
return clean;
}
return null;
}
/**
* 判断是否是英文字符传你
*/
public static boolean isEnStr(String word) {
boolean result = word.matches("[a-zA-Z]+");
return result;
}
/**
* 判断是否包含中文
*/
public static boolean isContainChStr(String word) {
Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
Matcher m = p.matcher(word);
if (m.find()) {
return true;
}
return false;
}
}
sqp.service.name=sqb4j
sqp.service.version=1.4
sqp.service.level=product
sqp.zookeeper.hosts=center1.secoo-inc.com:2181,center2.secoo-inc.com:2181,center3.secoo-inc.com:2181
image.delete.url=http://10.16.9.28:8080
image.update.url=http://10.16.8.44:8080
prefixFilterList=["https://", "http://", "dg", "d & g", "dolce&gabbana","dolce & gabbana", "\u675C\u5609\u73ED\u7EB3", "\u907F\u5B55", "\u60C5\u8DA3", "cucci", "\u4E52\u4E53\u7403", "cuccl", "gucii","tod's","iwc7"]
ManualFolder=/data/pssmaster/corpus_set/suggest_corpus/manual
SensitiveFolder=/data/pssmaster/corpus_set/suggest_corpus/sensitive
EuropeWordFolder=/data/pssmaster/corpus_set/suggest_corpus/europe_word
erp.read.url=jdbc:mysql://192.168.50.40:3306/secooErpDB?useUnicode=true&amp;characterEncoding=utf8&amp;noAccessToProcedureBodies=true&amp;zeroDateTimeBehavior=convertToNull&amp;allowMultiQueries=true
erp.read.user=so_Erp_R
erp.read.password=5RgzudyyFlApTmve
seo.read.url=jdbc:mysql://secooSeoDB.master.com:3307/secooSeoDB?useUnicode=true&amp;characterEncoding=utf8&amp;zeroDateTimeBehavior=convertToNull
seo.read.user=sem_Seo_W
seo.read.password=C2IiHfNKYpT1onsR
dw.read.url=jdbc:mysql://secooDataWarehouse.slave.com:3306/secooDataWarehouse?useUnicode=true&amp;characterEncoding=utf8&amp;zeroDateTimeBehavior=convertToNull
dw.read.user=Search_DataWar_R
dw.read.password=pY1P9zUj9x1M65ot5szo
\ No newline at end of file
sqp.service.name=sqb4j
sqp.service.version=1.4
sqp.service.level=product
sqp.zookeeper.hosts=center1.secoo-inc.com:2181,center2.secoo-inc.com:2181,center3.secoo-inc.com:2181
image.delete.url=http://192.168.70.141:8080
\ No newline at end of file
erp.read.url=jdbc:mysql://10.4.3.223:3306/secooErpDB?useUnicode=true&amp;characterEncoding=utf8&amp;noAccessToProcedureBodies=true&amp;zeroDateTimeBehavior=convertToNull&amp;allowMultiQueries=true
erp.read.user=3306_test
erp.read.password=iS6CXpYqgZ8Mhjui
seo.read.url=jdbc:mysql://10.4.3.223:3306/secooSeoDB?useUnicode=true&amp;characterEncoding=utf8&amp;zeroDateTimeBehavior=convertToNull
seo.read.user=SeoDB_test
seo.read.password=Cxkfq57huej0fTpK
\ No newline at end of file
log4j.rootLogger=INFO, FILE
# logger
log4j.logger.com.secoo.so.mysql.binlog=INFO
log4j.logger.org.apache.zookeeper=WARN
log4j.logger.com.alibaba.dubbo=WARN
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=logs/service.log
log4j.appender.FILE.MaxFileSize=100MB
log4j.appender.FILE.MaxBackupIndex=5
log4j.appender.FILE.Threshold=INFO
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}]%.8t %-5p %c:%L %m%n
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment