Commit 10a09dd1 authored by wux's avatar wux

添加okhttp请求依赖和请求封装

parent 3e0355a2
......@@ -21,6 +21,7 @@
<knife4j.version>3.0.2</knife4j.version>
<swagger-annotations.version>1.5.22</swagger-annotations.version>
<servlet.versoin>2.5</servlet.versoin>
<okhttp.version>4.9.3</okhttp.version>
<!-- DB 相关 -->
<mysql.version>5.1.46</mysql.version>
<druid.version>1.2.9</druid.version>
......@@ -436,6 +437,12 @@
<artifactId>ueditor-spring-boot-starter</artifactId>
<version>${ueditor.version}</version>
</dependency>
<!-- okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
package cn.iocoder.yudao.framework.http.collection;
import java.util.Collection;
/**
* 集合工具类
* @author Wenyi Feng
* @since 2018-10-15
*/
public class CollectionUtils {
/**
* 如果集合为{@code null}或者空,则返回{@code true}。
* 否则,返回{@code false}
*
* @param collection 待检查的集合
* @return 集合是否为空
*/
public static boolean isEmpty(Collection<?> collection) {
return collection == null || collection.isEmpty();
}
/**
* 判断数组是空数组
*
* @param array 待判断的数据
* @return true:空 / false:非空
*/
public static boolean isEmpty(String[] array) {
return array == null || array.length == 0;
}
/**
* 如果集合不为{@code null}或者空,则返回{@code true}。
* 否则,返回{@code false}
*
* @param collection 待检查的集合
* @return 集合是否不为空
*/
public static boolean isNotEmpty(Collection<?> collection) {
return !isEmpty(collection);
}
/**
* 判断数组不是空数组
*
* @param array 待判断的数据
* @return true:非空 / false:空
*/
public static boolean isNotEmpty(String[] array) {
return !isEmpty(array);
}
}
package cn.iocoder.yudao.framework.http.collection;
import java.util.Map;
/**
* Map工具类
* <ul>
* <li>判断Map是否为空</li>
* <li>判断Map是否不为空</li>
* </ul>
*
* @author Wenyi Feng
* @since 2018-11-17
*/
public class MapUtils {
/**
* 判断Map是否为空
*
* @param map 待判断的Map
* @return 是否为空,true:空;false:不为空
*/
public static boolean isEmpty(Map<?, ?> map) {
if (map == null){
return true;
}
return map.isEmpty();
}
/**
* 判断Map是否不为空
*
* @param map 待判断的Map
* @return 是否不为空,true:不为空;false:空
*/
public static boolean isNotEmpty(Map<?, ?> map) {
return !isEmpty(map);
}
}
package cn.iocoder.yudao.framework.http.convert;
import cn.iocoder.yudao.framework.http.util.StrUtils;
/**
* 进制转换工具类
* @author Wenyi Feng.
*/
public class HexUtils {
/**
* 二进制转十六进制
*
* @param bytes [ellipsis]
* @return [ellipsis]
*/
public static String bin2Hex(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
StringBuilder sb = new StringBuilder();
for (byte aByte : bytes) {
String hex = Integer.toHexString(aByte & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 16进制转化为 2进制
*
* @param hexStr 16进制字符串
* @return byte[]
*/
public static byte[] hex2Bin(String hexStr) {
if (StrUtils.isBlank(hexStr)) {
return null;
}
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}
\ No newline at end of file
package cn.iocoder.yudao.framework.http.convert;
import cn.iocoder.yudao.framework.http.util.StrUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* 参数处理工具类
* @author Wenyi Feng
* @since 2018-10-28
*/
public class ParamUtils {
/**
* 将Map型转为请求参数型
*
* @param data Map类型的参数
* @return url请求的参数
* @throws UnsupportedEncodingException 异常
*/
public static String getUrlParamsByMap(Map<String, String> data) throws UnsupportedEncodingException {
if (data == null || data.isEmpty()) {
return null;
}
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> i : data.entrySet()) {
sb.append(i.getKey())
.append("=")
.append(URLEncoder.encode(i.getValue(), StandardCharsets.UTF_8.toString()))
.append("&");
}
String str = sb.toString();
return str.substring(0, str.length() - 1);
}
/**
* 将url参数转换成map
* @param param [ellipsis]
* @return 参数Map
*/
public static Map<String, String> getUrlParams(String param) {
Map<String, String> map = new HashMap<>();
if (StrUtils.isBlank(param)) {
return map;
}
String[] params = param.split("&");
for (String s : params) {
String[] p = s.split("=");
if (p.length == 2) {
map.put(p[0], p[1]);
}
}
return map;
}
}
package cn.iocoder.yudao.framework.http.convert;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
/**
* XML转换工具类
*
* @author Erwin Feng
* @since 2020-08-13
*/
public class XmlUtils {
private static final XmlMapper MAPPER = new XmlMapper();
static {
configure(MAPPER);
}
public static void configure(XmlMapper mapper) {
//枚举输出成字符串
//WRITE_ENUMS_USING_INDEX:输出索引
mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
//空对象不要抛出异常:
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
//Date、Calendar等序列化为时间格式的字符串(如果不执行以下设置,就会序列化成时间戳格式):
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//反序列化时,遇到未知属性不要抛出异常:
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//反序列化时,遇到忽略属性不要抛出异常:
mapper.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
//反序列化时,空字符串对于的实例属性为null:
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
// 采用字段,不使用 Getter
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
// jackson xml
JacksonXmlModule jacksonXmlModule = new JacksonXmlModule();
mapper.registerModule(jacksonXmlModule);
// java.time
JavaTimeModule javaTimeModule = new JavaTimeModule();
mapper.registerModule(javaTimeModule);
}
/**
* 将对象转换成XML格式的字符串
*
* @param value 待转换的对象
* @param <T> 对象的类型
* @return 返回转换后的XML格式的字符串
*/
public static <T> String string(T value) {
try {
return MAPPER.writeValueAsString(value);
} catch (JsonProcessingException e) {
// PrintUtils.error(ExceptionUtils.getStackTrace(e));
return null;
}
}
/**
* 将XML格式的字符串转换成对象
*
* @param value 待转换的XML格式的字符串
* @param valueType 转换后的对象的class
* @param <T> 对象的类型
* @return 返回转换后的对象
*/
public static <T> T object(String value, Class<T> valueType) {
try {
return MAPPER.readValue(value, valueType);
} catch (JsonProcessingException e) {
// PrintUtils.error(ExceptionUtils.getStackTrace(e));
return null;
}
}
/**
* 将XML格式的字符串转换成对象
*
* @param value 待转换的XML格式的字符串
* @param valueType {@link TypeReference}
* @param <T> 对象的类型
* @return 返回转换后的对象
*/
public static <T> T object(String value, TypeReference<T> valueType) {
try {
return MAPPER.readValue(value, valueType);
} catch (JsonProcessingException e) {
// PrintUtils.error(ExceptionUtils.getStackTrace(e));
return null;
}
}
}
package cn.iocoder.yudao.framework.http.core;
import cn.iocoder.yudao.framework.http.collection.MapUtils;
import cn.iocoder.yudao.framework.http.util.StrUtils;
import lombok.Getter;
import lombok.Setter;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import java.io.File;
import java.util.*;
/**
* 请求所需要参数
*
* @author Erwin Feng
* @since 2022-11-18
*/
@Getter
@Setter
public class Request {
private static final String PARAM_DEFAULT_KEY = "__default__";
/**
* 请求地址
*/
private String url;
/**
* 请求方式
*/
private Method method;
/**
* 请求参数
*/
@Getter
private Map<String, Object> param;
private ParamFormat paramFormat = ParamFormat.STRING;
private List<FileBo> fileList;
/**
* 请求工具
*/
private Util util = Util.OkHttp;
public enum ParamFormat {
STRING, FORM, JSON
}
/**
* 请求方法枚举
*/
public enum Method {
GET, POST, PUT, PATCH, DELETE
}
/**
* 请求工具枚举
*/
public enum Util {
// JDK,
OkHttp,
// AsyncHttpClient
}
/**
* 日志级别枚举
*/
public enum LogLevel {
DEBUG, INFO, ERROR
}
/**
* 创建 Request
*
* @param url 请求地址
* @param method 请求方法
* @param param 请求参数
* @return Request
*/
public static Request create(String url, Method method, String param) {
Request request = new Request();
request.setUrl(url);
request.setMethod(method);
request.setParam(param);
return request;
}
/**
* 创建 Request
*
* @param url 请求地址
* @param method 请求方法
* @param param 请求参数
* @return Request
*/
public static Request create(String url, Method method, Map<String, Object> param) {
Request request = new Request();
request.setUrl(url);
request.setMethod(method);
request.setParam(param);
return request;
}
/**
* 请求可选参数
*/
@Getter
@Setter
public static class Option {
/**
* 连接超时时间,秒,默认5秒
*/
private Integer connectTimeoutSecond = 5;
/**
* 读取超时时间,秒,默认45秒
*/
private Integer readTimeoutSecond = 45;
/**
* 请求头
*/
private Map<String, String> headers = new HashMap<>();
/**
* ssl
*/
private SSLSocketFactory sslContextFactory;
/**
* HostnameVerifier
*/
private HostnameVerifier hostnameVerifier;
/**
* 日志级别
*/
private LogLevel logLevel;
/**
* 创建 Request.Option
*
* @param connectTimeoutSecond 连接超时时间,秒
* @param readTimeoutSecond 读取超时时间,秒
* @return Request.Option
*/
public static Option create(Integer connectTimeoutSecond, Integer readTimeoutSecond) {
Option option = new Option();
Optional.ofNullable(connectTimeoutSecond).ifPresent(option::setConnectTimeoutSecond);
Optional.ofNullable(readTimeoutSecond).ifPresent(option::setReadTimeoutSecond);
return option;
}
/**
* 创建 Request.Option
*
* @param connectTimeoutSecond 连接超时时间,秒
* @param readTimeoutSecond 读取超时时间,秒
* @param headers http headers
* @return Request.Option
*/
public static Option create(Integer connectTimeoutSecond, Integer readTimeoutSecond, Map<String, String> headers) {
Option option = new Option();
Optional.ofNullable(connectTimeoutSecond).ifPresent(option::setConnectTimeoutSecond);
Optional.ofNullable(readTimeoutSecond).ifPresent(option::setReadTimeoutSecond);
Optional.ofNullable(headers).ifPresent(option::setHeaders);
return option;
}
}
public Request setParam(String param) {
if (StrUtils.isNotBlank(param)) {
Map<String, Object> map = new HashMap<>();
map.put(PARAM_DEFAULT_KEY, param);
this.param = map;
}
return this;
}
public Request setParam(Map<String, Object> map) {
this.param = map;
return this;
}
public Request bak(Map<String, Object> map) {
if (MapUtils.isEmpty(map)) {
return this;
}
StringJoiner stringJoiner = new StringJoiner("&", "", "");
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (StrUtils.isNotBlank(entry.getKey())) {
stringJoiner.add(entry.getKey() + "=" + entry.getValue());
}
}
String param = stringJoiner.toString();
return setParam(param);
}
public static class MediaConstant {
/**
* application/json
*/
public static final String APPLICATION_JSON_VALUE = "application/json";
/**
* application/...form...
*/
public static final String APPLICATION_FORM_VALUE = "application/x-www-form-urlencoded";
}
@Getter
@Setter
public static class FileBo {
private String paramName = "file";
private String fileName;
private File file;
}
}
\ No newline at end of file
package cn.iocoder.yudao.framework.http.core;
import lombok.Getter;
import lombok.Setter;
/**
* @author Erwin Feng
* @since 2022-11-24
*/
@Getter
@Setter
public class Response {
private int code;
private String msg;
private String body;
}
package cn.iocoder.yudao.framework.http.core.client;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import java.io.IOException;
import java.util.Objects;
/**
* HTTP 请求客户端 接口
*
* @author Erwin Feng
* @since 2022-11-24
*/
public interface HttpClient {
String PARAM_DEFAULT_KEY = "__default__";
/**
* 执行 http 请求
*
* @param request 请求
* @param option http 可选配置
* @return http 响应结果
* @throws IOException IO 异常
*/
Response execute(Request request, Request.Option option) throws IOException;
default Integer getTimeoutSecond(Integer timeoutSecond) {
if (Objects.nonNull(timeoutSecond) && timeoutSecond > 0) {
return timeoutSecond;
}
return null;
}
}
package cn.iocoder.yudao.framework.http.core.client;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.client.impl.OkHttpClient;
/**
* HTTP CLIENT 工厂
*
* @author Erwin Feng
* @since 2022-11-24
*/
public class HttpClientFactory {
/**
* 获取 http client
*
* @param httpUtil http 工具
* @return http client 实现
*/
public static HttpClient get(Request.Util httpUtil) {
if (Request.Util.OkHttp == httpUtil) {
return new OkHttpClient();
} else {
throw new RuntimeException("not find http util: " + httpUtil.name());
}
}
}
package cn.iocoder.yudao.framework.http.example;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.core.client.HttpClient;
import cn.iocoder.yudao.framework.http.core.client.HttpClientFactory;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
/**
* @author wuxian
* @since 2024-10-23
**/
public class SendchampHttp {
private static final String SMS_URL="https://api.sendchamp.com/api/v1/sms/send";
public void postReq(Map<String,Object> param,Map<String, String> header){
HttpClient client = HttpClientFactory.get(Request.Util.OkHttp);
Request req = Request.create(SMS_URL,Request.Method.POST,param);
req.setParamFormat(Request.ParamFormat.JSON);
try {
Response res = client.execute(req,Request.Option.create(0,0,header));
System.out.println("response code ---------------------------->"+res.getCode());
System.out.println("response content is --------------------》"+res.getBody());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@NotNull
private static Map<String , String> setHeader(String apiKey){
Map<String,String> header = new HashMap<>();
header.put("Accept","application/json,text/plain,*/*");
header.put("Content-Type", "application/json");
header.put("Authorization", apiKey);
return header;
}
@NotNull
private static Map<String, Object> setParams(String to,String message,String senderName) {
Map<String,Object> param = new HashMap<>();
param.put("to",to);
param.put("message",message);
param.put("sender_name",senderName);
param.put("route","dnd");
return param;
}
public static void main(String[] args){
SendchampHttp test = new SendchampHttp();
String to = "2348140352000";
String senderName = "Sendchamp";
//信息如果超过200字符,需要拆成多条短信,多次发送
String message = "Good day!This is E&C logistics(ship from China to Nigeria),It has been a while since we last worked together, and we would like to reestablish our partnership. Our main service: GROUPAGE/FULL CONTAINE";
Map<String, Object> param = setParams(to,message,senderName);
String apiKey = "Bearer sendchamp_live_$2a$10$vQPdaDjl96Ybc5tzFmZYg.nqGirXuJBGDqJArthZnFR8P9mM5Z/JO";
Map<String,String> header = setHeader(apiKey);
test.postReq(param,header);
}
}
package cn.iocoder.yudao.framework.http.example;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.core.client.HttpClient;
import cn.iocoder.yudao.framework.http.core.client.HttpClientFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author wuxian
* @since 2024-10-23
**/
public class WhisperClientHttp {
public void testPost(){
// HttpResponse<String> response = Unirest.post("https://whispersms.xyz/api/send_message/")
// .header("Authorization", "Api_key gAAAAABl5ZDpoKnKVaK0scmWo7GQeKDA1sn3OZBeMXUz211vZv5QqSEtr7_LD5ISTqSD0PnWLRWavYmJ3nQJiutT-sgp0dyHR2HIL6FYEhD3t2CNuoHJoSIOia5ffo_rjfxW_pk8co0i7UMTYANNGxsRNJLQTu_Alw==")
// //.header("Authorization","Token 0371a29044432d36cc2508b7ce51e70f466c7d95")
// .header("Content-Type", "application/json")
// .body("{\"contacts\": [\"8618102810628\"],\"sender_id\": \"EC\",\"message\": \"say hello everybody.\",\"priority_route\": False,\"campaign_name\": \"mytest\"}")
// .asString();
// System.out.println("response is ------------------------>"+response.getBody());;
}
public void postReq(List<String> phonenums, String message){
HttpClient client = HttpClientFactory.get(Request.Util.OkHttp);
String sendUrl = "https://whispersms.xyz/whisper/send_message/";
//String sendUrl = "https://whispersms.xyz/api/send_message/";
Map<String, Object> param = new HashMap<>();
param.put("contacts",phonenums);
param.put("message",message);
param.put("sender_id","EC");
param.put("priority_route","False");
param.put("campaign_name","EClogistics");
Map<String, String> header = new HashMap<>();
//header.put("Accept","application/json,text/plain,*/*");
header.put("Content-Type", "application/json");
header.put("Authorization","Token 0371a29044432d36cc2508b7ce51e70f466c7d95");
//header.put("Authorization", "Api_key gAAAAABl5ZDpoKnKVaK0scmWo7GQeKDA1sn3OZBeMXUz211vZv5QqSEtr7_LD5ISTqSD0PnWLRWavYmJ3nQJiutT-sgp0dyHR2HIL6FYEhD3t2CNuoHJoSIOia5ffo_rjfxW_pk8co0i7UMTYANNGxsRNJLQTu_Alw==");
Request req = Request.create(sendUrl,Request.Method.POST,param);
req.setParamFormat(Request.ParamFormat.JSON);
try {
Response res = client.execute(req,Request.Option.create(0,0,header));
System.out.println("response code ---------------------------->"+res.getCode());
System.out.println("response content is --------------------》"+res.getBody());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args){
WhisperClientHttp test = new WhisperClientHttp();
//test.testPost();
List<String> phonenums = new ArrayList<>();
phonenums.add("8618102810628");
phonenums.add("2348140352000");
String message = "Good day !This is E&C logistics(ship from China to Nigeria) ,It has been a while since we last worked together, and we would like to reestablish our partnership. " +
"Our main service: GROUPAGE/FULL CONTAINER/AIR CARGO/COMPRESSING/CONSOLITAION ." +
"We value your business and would appreciate the opportunity to serve you once again." +
"Have a Nice day! My wa :+8615920356527";
test.postReq(phonenums,message);
//test.testPost();
}
}
package cn.iocoder.yudao.framework.http.example;
import cn.iocoder.yudao.framework.http.core.Request;
import cn.iocoder.yudao.framework.http.core.Response;
import cn.iocoder.yudao.framework.http.core.client.HttpClient;
import cn.iocoder.yudao.framework.http.core.client.HttpClientFactory;
import lombok.SneakyThrows;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author wuxian
* @since 2024-10-30
**/
public class YCloudWhatsappHttp {
private HttpClient client = null;
//请求地址
private static final String WA_URL="https://api.ycloud.com/v2/whatsapp/messages/sendDirectly";
public YCloudWhatsappHttp() {
init();
}
private void init(){
client = HttpClientFactory.get(Request.Util.OkHttp);
}
@SneakyThrows
public void postWhatsapp(Map<String, String> header,Map<String,Object> param){
Request req = Request.create(WA_URL,Request.Method.POST,param);
req.setParamFormat(Request.ParamFormat.JSON);
Response res = client.execute(req,Request.Option.create(0,0,header));
System.out.println("response code ---------------------------->"+res.getCode());
System.out.println("response content is --------------------》"+res.getBody());
}
/**
*
* @param code 验证码
* @param templateName 模板名称
* @param lanCode 语言编号
* @return 参数
*/
private Map<String,Object> setParams(String code,String templateName,String lanCode){
Map<String, Object> template = new HashMap<>();
Map<String, String> language = new HashMap<>();
Components components = new Components();
Parameters parameters = new Parameters();
Button button = new Button();
button.setIndex("0");
button.setType("button");
button.setSub_type("url");
//模板包含语言(language)、组件(components),组件包含参数(parameters)
parameters.setType("text");
parameters.setText(code);
List<Object> list1 = new ArrayList<>();
list1.add(parameters);
//构建json中的组件
components.setType("body");
components.setParameters(list1);
button.setParameters(list1);
List<Object> list2 = new ArrayList<>();
list2.add(components);
list2.add(button);
language.put("code",lanCode);
language.put("policy","deterministic");
template.put("language",language);
template.put("name",templateName);
template.put("components",list2);
//构建最终requestBody的json
Map<String, Object> param = new HashMap<>();
param.put("from","8618022485824");
param.put("to","8618102810628");
param.put("type","template");
param.put("template",template);
return param;
}
//构建http请求的头
private Map<String,String> setHeader(String apiKey){
Map<String,String> header = new HashMap<>();
header.put("Accept","application/json");
header.put("Content-Type", "application/json");
header.put("X-API-Key", apiKey);
return header;
}
public static void main(String[] args){
YCloudWhatsappHttp test = new YCloudWhatsappHttp();
String apiKey = "9dbd912f56c101e53b23cb7b758ffda8";
String code = "8888";
String templateName ="ec_verification";
String lanCode ="en";
test.postWhatsapp(test.setHeader(apiKey),test.setParams(code,templateName,lanCode));
}
}
@lombok.Setter
@lombok.Getter
class Parameters{
private String type;
private String text;
}
@lombok.Setter
@lombok.Getter
class Components {
private String type;
private List<Object> parameters = null;
}
@lombok.Setter
@lombok.Getter
class Button {
private String type;
private String sub_type;
private String index;
private List<Object> parameters= null;
}
package cn.iocoder.yudao.framework.http.exception;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* 异常工具类
*
* @author Erwin Feng
* @since 2020/8/13
*/
public class ExceptionUtils {
/**
* 获取异常栈信息
*
* @param throwable 异常
* @return 异常信息
*/
public static String getStackTrace(Throwable throwable) {
if (throwable == null) {
return "";
}
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, Boolean.TRUE);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
}
package cn.iocoder.yudao.framework.http.util;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.regex.Pattern;
/**
* 字符串工具类
* <ul>
* <li>字符串判空</li>
* <li>字符串判非空</li>
* </ul>
*
* @author Erwin Feng
*/
public class StrUtils {
/**
* 空的字符串("")
*/
public static final String BLANK = "";
/**
* 判断字符串是否为空
*
* <ul>
* <li>null - true</li>
* <li>"" - true</li>
* <li>" " - true</li>
* <li>"null" - true</li>
* <li>" null " - true</li>
* </ul>
*
* @param str 待判断的字符串
* @return 是否是空字符串,true:空字符串;false:非空字符串
*/
public static boolean isBlank(String str) {
if (Objects.isNull(str)) {
return true;
}
str = str.trim();
if (str.isEmpty()) {
return true;
}
if ("null".equalsIgnoreCase(str)) {
return true;
}
return str.length() == 0;
}
/**
* 判断字符串是否不为空
*
* @param str 待判断的字符串
* @return 是否是空字符串,true:非空字符串;false:空字符串
*/
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
/**
* 自动填充。比如,待填充是:11,填充长度:10,则填充后的字符串为:0000000011
*
* @param source 待填充
* @param length 填充长度
* @return 填充后的字符串
*/
public static String autoFill(Integer source, Integer length) {
if (source == null || length == null || (source + "").length() >= length){
return source + "";
}
return String.format("%0" + length + "d", source);
}
/**
* 自动填充
* <p>
* 比如:待填充字符串:Dd,用x在其左侧填充成10位的字符串,
* 则为:xxxxxxxxDd
* </p>
* <p>
* 如果待字符串is null,则返回null。
* 如果填充长度is null,或者小于原长度,则返回原待填充字符串。
* 例如:待填充字符串:Dd,用x在其左侧填充成10位的字符串,则仍然为:Dd
* </p>
* <p>
* 如果你有指定填充字符串,或者填充方向,我们会进行默认。
* 填充字符串默认为:0,方向为:左。
* 例如:待填充字符串:Dd,填充成10位的字符串,则为:00000000Dd
* </p>
*
* @param source 待填充的字符串
* @param length 填充后的长度
* @param str 填充的字符(串)
* @param isRight 是否在原字符串的右侧填充
* @return 填充后的字符串
*/
public static String autoFill(String source, Integer length, String str, Boolean isRight) {
// 初始化校验
if (source == null || length == null || (source).length() >= length) {
return source;
}
// 指定填充字符
if (isBlank(str)){
str = "0";
}
// 指定填充方向
if (isRight == null){
isRight = false;
}
// 字符填充长度
int count = (source).length();
StringBuilder sb = new StringBuilder(length);
// 右填充
if (isRight) {
sb.append(source);
}
// 字符填充
int size = length - count;
for (int i = 0; i < size; i++) {
sb.append(str);
}
// 左填充
if (!isRight) {
sb.append(source);
}
return sb.toString();
}
/**
* 字符串中只有数字。如果只含有数字,则返回true,反之,返回false.
*
* @param str 待检测字符串
* @return 是否只含有数字(0-9)
*/
public static boolean hasOnlyNum(String str) {
if (isBlank(str)){
return false;
}
Pattern pattern = Pattern.compile("[0-9]*");
return pattern.matcher(str).matches();
}
/**
* 获取随机字符串
*
* @param length 生成字符串的长度
* @return 随机字符串
*/
public static String getRandomString(int length) {
StringBuilder result = new StringBuilder();
char[] str = "0123456789abcdefghijkmlnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
for (int i = 0; i < length; i++) {
int index = (int) (Math.random() * str.length);
result.append(str[index]);
}
return result.toString();
}
/**
* 删除字符串开始的字符串
* <p>
* 如字符串:abcdefg,删除abc,得到的字符串为defg
* </p>
*
* @param str 原始字符串
* @param remove 需要移除的字符串
* @return 移除后的字符串
*/
public static String removeStart(String str, String remove) {
if (isNotBlank(str) && isNotBlank(remove)) {
return str.startsWith(remove) ? str.substring(remove.length()) : str;
} else {
return str;
}
}
/**
* 生成一个指定长度的星号(*)字符串
*
* @param length 生成星号的长度
* @return 生成一个指定长度的星号(*)字符串
*/
public static String generateStar(int length) {
StringJoiner sj = new StringJoiner("", "", "");
for (int i = 0; i < length; i++) {
sj.add("*");
}
return sj.toString();
}
/**
* 获取字符串左边指定长度的字符串。
* <p>
* 例如,字符串是:张三,截取长度为1,得到的结果是:张。
* </p>
* <p>
* 注意,如果需要截取的长度大于字符串的长度,那么会返回整个字符串。
* 如截取的长度是3,那么得到的结果是:张三。
* </p>
*
* @param source 需要截取的字符串
* @param length 需要获取左边字符串的长度
* @return 返回字符串左边指定长度的字符串
*/
public static String getLeft(String source, int length) {
if (StrUtils.isBlank(source)
|| length < 1) {
return BLANK;
}
if (length > source.length()) {
// PrintUtils.warn("length(" + length + ") > source's length(" + source.length() + ")");
length = source.length();
}
return source.substring(0, length);
}
/**
* 获取字符串右边指定长度的字符串。
* <p>
* 例如,字符串是:张三,截取长度为1,得到的结果是:三。
* </p>
* <p>
* 注意,如果需要截取的长度大于字符串的长度,那么会返回整个字符串。
* 如截取的长度是3,那么得到的结果是:张三。
* </p>
*
* @param source 需要截取的字符串
* @param length 需要获取右边字符串的长度
* @return 返回字符串右边指定长度的字符串
*/
public static String getRight(String source, int length) {
if (StrUtils.isBlank(source)
|| length < 1) {
return BLANK;
}
if (length > source.length()) {
length = source.length();
}
return source.substring(source.length() - length);
}
// 截取前缀后的字符串
public static String substringAfter(String content, String prefix) {
if (isBlank(content)) {
return BLANK;
}
if (isBlank(prefix)) {
return content;
}
return content.substring(prefix.length());
}
// 将字符串的第一个字符大写
public static String lowerCaseFirst(String content) {
if (isBlank(content)) {
return BLANK;
}
String first = content.substring(0, 1);
String after = content.substring(1);
return first.toLowerCase() + after;
}
}
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