一. 文件相关
1.1 Excel
-
-
流式导出:
-
调用类:
import com.alibaba.excel.annotation.ExcelProperty; import com.xxx.ExcelUtils; import lombok.Data; import lombok.experimental.Accessors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /** * @author 暗余原创 * @date 2021/9/24 15:07 */ @RestController public class DemoController { @Autowired private ExcelUtils excelUtils; @GetMapping("test") public void exportSbnDailyInventory( HttpServletResponse response) { List<Demo> list = new ArrayList<>(); list.add(new Demo().setName("anyu").setAge(18)); excelUtils.exportXls(response, list, Demo.class); } } @Accessors(chain = true) @Data class Demo implements Serializable { @ExcelProperty(value = "name",index = 0) private String name; @ExcelProperty(value = "age",index = 1) private Integer age; }
-
通用工具类:
import com.alibaba.excel.EasyExcel; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletResponse; import java.net.URLEncoder; import java.util.List; /** * @author 暗余 * @date 2021/8/24 17:14 */ @Component public class ExcelUtils { public void exportXls(HttpServletResponse response, List list, Class clazz) { exportXls(response, "excelData", list, clazz, "Sheet 1"); } public void exportXls(HttpServletResponse response, String fileName, List list, Class clazz, String sheetName) { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); try { fileName = URLEncoder.encode(fileName + "_" + System.currentTimeMillis(), "UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); EasyExcel.write(response.getOutputStream(), clazz) .sheet(sheetName).doWrite(list); } catch (Exception e) { log.error("解析失败",e.getMessage()); } } }
其他需要直接参考官方文档
-
-
1.2 Csv
-
解析:
-
核心代码:
// 数据行 List<String[]> dataList = Lists.newArrayList(); // 解析excel内容 try { BufferedReader reader = new BufferedReader(new FileReader(new File($localPath))); CsvReader csvReader = new CsvReader(reader, ','); // 跳过标题 csvReader.readRecord(); while (csvReader.readRecord()) { dataList.add(csvReader.getValues()); } csvReader.close(); } catch (Exception e) { log.error(e.getMessage()); throw new BizException("parse content fail!"); }
其中new CsvReader(reader, ‘,’); 的逗号表示分隔符,可以根据实际替换,一般默认逗号; $localPath 代表本地文件路径;
-
科学计数法解析:
-
// 判断字符串是否为科学计数法的正则表达式 private static final Pattern pattern = Pattern.compile("[+-]*\\d+\\.?\\d*[Ee]*[+-]*\\d+"); if(StringUtils.isNotBlank($content) && pattern.matcher(sellerPart).matches()){ // 满足条件后将字符串转为数字再转为字符串; String content = new BigDecimal($index).toPlainString() }
利用正则过滤出为科学计数法的长数字串,然后将其转为BigDecimal,然后再toString就可以将科学计数法的字符串转为正常的啦;
使用前: 2.02E+11 解析为 “2.02E+11” ; 使用此方法后:2.02E+11 解析为: “201603000000”
-
-
1.3 Txt
-
解析
-
核心代码:
-
List<String> dataList = Lists.newArrayList(); try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(result.getReadLocalPath())), StandardCharsets.UTF_8))) { // 跳过标题 String total = br.readLine(); dataList.add(total); // 正文 String lineTxt; while ((lineTxt = br.readLine()) != null) { if (StringUtils.isNotBlank(lineTxt)) { dataList.add(lineTxt); } } } catch (Exception e) { log.error(e.getMessage()); // 第一次命名已经解析成功了,如果这次出现解析失败,说明有问题,直接抛出异常 throw new BizException("parse content fail!"); } return dataList; ```
-
-
分页读取内容:
-
public static List<String> getLines (String fileName,int pageNo, int pageSize){ File file = new File(fileName); List<String> lines = new ArrayList<>(); try(BufferedReader reader = new BufferedReader(new FileReader(file)); LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(file))) { int startRow = (pageNo - 1) * pageSize + 1; //计算开始行数 int endRow = pageNo * pageSize; //计算结束行数 lineNumberReader.skip(Long.MAX_VALUE); int lineNumber = lineNumberReader.getLineNumber() + 1; //获取文件里面的总行数 if (endRow >= lineNumber) { endRow = lineNumber; } String tempString = ""; int line = 0; // 一次读入一行,直到读入null为文件结束 while (tempString != null) { line++; tempString = reader.readLine(); if (line >= startRow && line <= endRow) { lines.add(tempString); } } return lines; } catch (IOException e) { e.printStackTrace(); } return null; }
-
-
1.4 XML
import java.io.IOException;
import java.io.StringWriter;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class XmlUtils {
private static XmlMapper xmlMapper = new XmlMapper();
private XmlUtils() {
throw new IllegalStateException("Utility class");
}
static {
// 忽略空Bean转json的错误
xmlMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 忽略 在json字符串中存在,但是在java对象中不存在对应属性的情况。防止错误
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 大小写脱敏
xmlMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
}
public static <T> T string2Obj(String xmlSrc, Class<T> clazz) {
if (null == xmlSrc || clazz == null) {
return null;
}
try {
return xmlMapper.readValue(xmlSrc, clazz);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String obj2String(Object o) {
try {
JAXBContext context = JAXBContext.newInstance(o.getClass());
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter writer = new StringWriter();
marshaller.marshal(o, writer);
return writer.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
二. Spring
2.1 Spring Bean 获取工具类:
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
@Service
public class SpringBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(@NotNull ApplicationContext context) throws BeansException {
applicationContext = context;
}
// 这里使用的是根据class类型来获取bean 当然你可以根据名称或者其他之类的方法 主要是有applicationContext你想怎么弄都可以
public static Object getBeanByClass(Class clazz) {
return applicationContext.getBean(clazz);
}
}
三. 线程
3.1 ThreadLocalUtils
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
* @author 暗余
* @date 2021/7/17 15:44
*/
@SuppressWarnings("unused")
public final class ThreadLocalUtils {
private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL =
ThreadLocal.withInitial(() -> new ConcurrentHashMap<>(16));
/**
* 获取到ThreadLocal中值
*
* @return ThreadLocal存储的是Map
*/
public static Map<String, Object> getThreadLocal() {
return THREAD_LOCAL.get();
}
/**
* 从ThreadLocal中的Map获取值
*
* @param key Map中的key
* @param <T> Map中的value的类型
* @return Map中的value值 可能为空
*/
public static <T> T get(String key) {
return get(key, null);
}
/**
* 从ThreadLocal中的Map获取值
*
* @param key Map中的key
* @param defaultValue Map中的value的为null 是 的默认值
* @param <T> Map中的value的类型
* @return Map中的value值 可能为空
*/
@SuppressWarnings("unchecked")
public static <T> T get(String key, T defaultValue) {
Map<String, Object> map = THREAD_LOCAL.get();
if (MapUtils.isEmpty(map)) {
return null;
}
return (T) Optional.ofNullable(map.get(key)).orElse(defaultValue);
}
/**
* ThreadLocal中的Map设置值
*
* @param key Map中的key
* @param value Map中的value
*/
public static void set(String key, Object value) {
Map<String, Object> map = THREAD_LOCAL.get();
map.put(key, value);
}
/**
* ThreadLocal中的Map 添加Map
*
* @param keyValueMap 参数map
*/
public static void set(Map<String, Object> keyValueMap) {
Map<String, Object> map = THREAD_LOCAL.get();
map.putAll(keyValueMap);
}
/**
* 删除ThreadLocal中的Map 中的value
*
* @param key Map中的key
*/
public static void delete(String key) {
Map<String, Object> map = THREAD_LOCAL.get();
if (MapUtils.isEmpty(map)) {
return;
}
map.remove(key);
}
/**
* 删除ThreadLocal中的Map
*/
public static void remove() {
THREAD_LOCAL.remove();
}
/**
* 从ThreadLocal中的Map获取值 根据可key的前缀
*
* @param prefix key 的前缀
* @param <T> Map中的value的类型
* @return 符合条件的Map
*/
@SuppressWarnings("unchecked")
public static <T> Map<String, T> fetchVarsByPrefix(String prefix) {
Map<String, T> vars = new HashMap<>(16);
if (StringUtils.isBlank(prefix)) {
return vars;
}
Map<String, Object> map = THREAD_LOCAL.get();
if (MapUtils.isEmpty(map)) {
return vars;
}
return map.entrySet().stream().filter(test -> test.getKey().startsWith(prefix))
.collect(Collectors.toMap(Map.Entry::getKey, time -> (T) time.getValue()));
}
/**
* 删除ThreadLocal中的Map 中的Value 按 Map中的Key的前缀
*
* @param prefix Map中的Key的前缀
*/
public static void deleteVarsByPrefix(String prefix) {
if (StringUtils.isBlank(prefix)) {
return;
}
Map<String, Object> map = THREAD_LOCAL.get();
if (MapUtils.isEmpty(map)) {
return;
}
map.keySet().stream().filter(o -> o.startsWith(prefix)).collect(Collectors.toSet()).forEach(map::remove);
}
}
3.2 多线程工具类 ConcurrencyUtils
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* 并发工具包。
* <p>此工具提供一些在多线程编程中场使用到的工具方法。</p>
*
* @author 暗余
* @since 1.2.2 2019-04-16
*/
public class ConcurrencyUtils {
/**
* 获得一个阻塞式的线程池。
* <p>和FixedThreadPool不相同的是,这个线程池在达到核心数量时将会阻塞向里面提交新的线程。</p>
*
* @param poolSize 核心线程数量
* @return 线程池
*/
public static ExecutorService newBlockingThreadPool(int poolSize) {
return new ThreadPoolExecutor(poolSize, poolSize, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(poolSize), Executors.defaultThreadFactory(), new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().put(r);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
}
/**
* 使用Fork/Join执行一个可拆分的大任务。
* <p>这个方法适用于如下描述的场景:
* <ul>
* <li>你的输入数据是一个大的List;</li>
* <li>每一批的运算结果和最终的结果类型是一致的。</li>
* </ul>
* </p>
* <p>ForkJoinPool使用的是{@code commonPool}。
*
* @param <E> 数据集元素的类型
* @param <R> 结果集元素的类型
* @param batchSize 每次的数据量大小
* @param data 数据集
* @param function 每批数据集应该怎么操作
* @param combineFunction 每批数据的运行结果如何合并
* @return 合并后的结果集
*/
public static <E, R> R forkJoinExecute(final int batchSize, final List<E> data, Function<List<E>, R> function, BiFunction<R, R, R> combineFunction) {
return ForkJoinPool.commonPool().invoke(new ForkJoinExecutable<E, R>(function, combineFunction, data, batchSize, 0, data.size()));
}
/**
* 代表一个常规的可拆分的ForkJoin可执行任务。
* <p>
*
* @param <E> 数据集的元素的类型
* @param <R> 结果集的元素的类型
* @author mm92
* @since v19.2.123.0 2019-12-20
*/
private static class ForkJoinExecutable<E, R> extends RecursiveTask<R> {
private static final long serialVersionUID = 1L;
private int threshold;
private List<E> data;
private int start;
private int end;
private Function<List<E>, R> function;
private BiFunction<R, R, R> combineFunction;
public ForkJoinExecutable(Function<List<E>, R> function, BiFunction<R, R, R> combineFunction, List<E> data, int threshold, int start, int end) {
this.threshold = threshold;
this.data = data;
this.start = start;
this.end = end;
this.function = function;
this.combineFunction = combineFunction;
}
@Override
protected R compute() {
if (end - start <= threshold) {
// 如果数据量较小,直接查询
List<E> itemListSplitted = data.subList(start, end);
return function.apply(itemListSplitted);
}
int subTask1End = start + threshold;
ForkJoinExecutable<E, R> subTask1 = new ForkJoinExecutable<>(function, combineFunction, data, threshold, start, subTask1End);
ForkJoinExecutable<E, R> subTask2 = new ForkJoinExecutable<>(function, combineFunction, data, threshold, subTask1End, end);
invokeAll(subTask1, subTask2);
R res1 = subTask1.join();
R res2 = subTask2.join();
// 合并结果
R ret = combineFunction.apply(res1, res2);
return ret;
}
}
public static void main(String[] args) {
List<Integer> data = new ArrayList<>();
for (int i = 0; i < 100; i++) {
data.add(i + 1);
}
List<Integer> res = ConcurrencyUtils.forkJoinExecute(10, data, e -> {
return Arrays.asList(e.get(0)) ;
}, (e1, e2) -> {
ArrayList<Integer> ret = new ArrayList<>();
ret.addAll(e1);
ret.addAll(e2);
return ret;
});
System.out.println(res);
}
}
四. 集合
4.1 List
-
工具类:
-
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; /** * List操作的帮助类 * * @className: ListUtils.java * @since 1.0.0 2020-12-12 15:39:23 */ public class ListUtils { /** * null or empty * * @param t * @return true:null or empty * @since 1.0.0 2020-02-21 16:32:46 */ public static <T> boolean isNullOrEmpty(List<T> t) { return t == null || t.isEmpty(); } /** * 向 sourceList 追加 appendList * <p>注意:有做简单的contains去重复,但是contains底层是基于equals,所以对于对象,如果要去重,请自己重写equals()和hashCode()<p> * * @param sourceList 源数据 * @param appendList 待追加的数据 * @return 追加后的数据 * @since 1.0.0 2020-02-21 13:30:55 */ public static <T> void appendToList(List<T> sourceList, List<T> appendList) { sourceList = sourceList != null ? sourceList : new ArrayList<>(); if (isNullOrEmpty(appendList)) { return; } for (T t : appendList) { if (t == null || sourceList.contains(t)) { continue; } sourceList.add(t); } } /** * 根据 operator函数 删除元素 * * @since 1.0.0 2020-07-18 17:44:52 * * @param t 待操作列表 * @param filter 删除条件Fun */ public static <T> void removeIf(List<T> t, Predicate<? super T> filter) { if(isNullOrEmpty(t)) { return; } final Iterator<T> iterator = t.iterator(); while (iterator.hasNext()) { if (filter.test(iterator.next())) { iterator.remove(); } } } /** * 根据字段去重复 * * @since 1.0.0 2020-07-03 10:03:40 * * @param t 待操作列表 * @param keyExtractor 去重字段 * @return */ public static <T> List<T> distinct(List<T> t, Function<? super T, ?> keyExtractor) { if(isNullOrEmpty(t)) { return t; } Predicate<? super T> distinctPre = distinctPre(keyExtractor); return t.stream().filter(distinctPre).collect(Collectors.toList()); } /** * 构造去重复的条件 * * @since 1.0.0 2020-07-03 10:03:59 * * @param keyExtractor 去重字段 * @return */ private static <T> Predicate<T> distinctPre(Function<? super T, ?> keyExtractor) { Set<Object> seen = ConcurrentHashMap.newKeySet(); return t -> seen.add(keyExtractor.apply(t)); } /** * 判断是否存在 * * @since 1.0.0 2020-07-07 16:08:37 * * @param t * @param predicate * @return */ public static <T> boolean exists(List<T> t, Predicate<T> predicate) { if(isNullOrEmpty(t)) { return false; } for (T i : t) { if(i == null) { return false; } if (predicate.test(i)) { return true; } } return false; } /** * 从一个集合中查找符合要求的第一个元素(面对Stream.filter()查找元素,请优先使用这个方法,这个方法效率高得多)。 * <p> * * @param <T> 元素类型 * @param t 集合 * @param predicate 验证器 * @return 如果找到则返回头一个匹配的元素,否则返回null */ public static <T> T find(List<T> t, Predicate<? super T> predicate) { if(isNullOrEmpty(t)) { return null; } for (T i : t) { if (i != null && predicate.test(i)) { return i; } } return null; } /** * 从一个集合中查找符合要求的第一个元素(面对Stream.filter()查找元素,请优先使用这个方法,这个方法效率高得多)。 * <p> * * @param <T> 元素类型 * @param <R> 转化后的类型 * @param t 集合 * @param predicate 验证器 * @param mapper 转换器 * @return 如果找到则通过转换器返回头一个匹配的元素,否则返回null */ public static <T,R> R find(List<T> t, Predicate<? super T> predicate, Function<? super T, ? extends R> mapper) { T i = find(t, predicate); if(i == null) { return null; } return mapper.apply(i); } /** * 从一个集合中查找符合要求的集合 * * @since 1.0.0 2020-08-07 13:49:06 * * @param <T> 元素类型 * @param t 集合 * @param predicate 验证器 * @return 如果找到则返回匹配的元素集合,否则返回null */ public static <T> List<T> findList(List<T> t, Predicate<? super T> predicate) { if(isNullOrEmpty(t)) { return null; } return t.stream().filter(i -> i != null && predicate.test(i)).collect(Collectors.toList()); } /** * 从一个集合中查找符合要求的集合,并转换成一个新的集合 * * @since 1.0.0 2020-12-12 16:10:56 * * @param <T> 元素类型 * @param <R> 转化后的类型 * @param t 集合 * @param predicate 验证器 * @param mapper 转换器 * @return 如果找到匹配的元素集合,则根据转换器转换类型后返回元素集合,否则返回null */ public static <T,R> List<R> findList(List<T> t, Predicate<? super T> predicate, Function<? super T, ? extends R> mapper) { if(isNullOrEmpty(t)) { return null; } return t .stream() .filter(i -> i != null && predicate.test(i)) //find the source list that meets the predicate condition .map(i -> mapper.apply(i)) //convert:source -> target .collect(Collectors.toList()); } }
-
五. 网络
5.1 https访问
- 工具类:
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class SSLClient extends DefaultHttpClient {
public SSLClient() throws Exception {
super();
//传输协议需要根据自己的判断
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{
tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = this.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));
}
}
-
调用示例:
HttpPost httpPost = new HttpPost($url); httpPost.addHeader("Content-Type", "application/json;charset=UTF-8"); httpPost.setEntity(new StringEntity($req, StandardCharsets.UTF_8)); httpClient.execute(httpPost);
$url 表示https 开头的远程地址 $req 表示具体要传的Body的json参数;