mirror of
https://gitee.com/dromara/hutool.git
synced 2025-06-28 13:34:09 +08:00
Merge branch 'v5-dev' of github.com:dromara/hutool into v5-dev
This commit is contained in:
commit
b2c0d74dd7
@ -21,6 +21,17 @@ public interface PinyinEngine {
|
|||||||
*/
|
*/
|
||||||
String getPinyin(char c);
|
String getPinyin(char c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果c为汉字,则返回大写拼音;如果c不是汉字,则返回String.valueOf(c)
|
||||||
|
*
|
||||||
|
* @param c 任意字符,汉字返回拼音,非汉字原样返回
|
||||||
|
* @param tone 是否返回声调
|
||||||
|
* @return 汉字返回拼音,非汉字原样返回
|
||||||
|
*/
|
||||||
|
default String getPinyin(char c, boolean tone){
|
||||||
|
return getPinyin(c);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取字符串对应的完整拼音,非中文返回原字符
|
* 获取字符串对应的完整拼音,非中文返回原字符
|
||||||
*
|
*
|
||||||
@ -30,6 +41,19 @@ public interface PinyinEngine {
|
|||||||
*/
|
*/
|
||||||
String getPinyin(String str, String separator);
|
String getPinyin(String str, String separator);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取字符串对应的完整拼音,非中文返回原字符
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
* @param separator 拼音之间的分隔符
|
||||||
|
* @param tone 是否返回声调
|
||||||
|
* @return 拼音
|
||||||
|
*/
|
||||||
|
default String getPinyin(String str, String separator,boolean tone){
|
||||||
|
return getPinyin(str, separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将输入字符串转为拼音首字母,其它字符原样返回
|
* 将输入字符串转为拼音首字母,其它字符原样返回
|
||||||
*
|
*
|
||||||
|
@ -31,6 +31,17 @@ public class PinyinUtil {
|
|||||||
return getEngine().getPinyin(c);
|
return getEngine().getPinyin(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果c为汉字,则返回大写拼音;如果c不是汉字,则返回String.valueOf(c)
|
||||||
|
*
|
||||||
|
* @param c 任意字符,汉字返回拼音,非汉字原样返回
|
||||||
|
* @param tone 是否返回声调
|
||||||
|
* @return 汉字返回拼音,非汉字原样返回
|
||||||
|
*/
|
||||||
|
public static String getPinyin(final char c, boolean tone) {
|
||||||
|
return getEngine().getPinyin(c,tone);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将输入字符串转为拼音,每个字之间的拼音使用空格分隔
|
* 将输入字符串转为拼音,每个字之间的拼音使用空格分隔
|
||||||
*
|
*
|
||||||
@ -41,6 +52,17 @@ public class PinyinUtil {
|
|||||||
return getPinyin(str, StrUtil.SPACE);
|
return getPinyin(str, StrUtil.SPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将输入字符串转为拼音,每个字之间的拼音使用空格分隔
|
||||||
|
*
|
||||||
|
* @param str 任意字符,汉字返回拼音,非汉字原样返回
|
||||||
|
* @param tone 是否返回声调
|
||||||
|
* @return 汉字返回拼音,非汉字原样返回
|
||||||
|
*/
|
||||||
|
public static String getPinyin(final String str, boolean tone) {
|
||||||
|
return getPinyin(str, StrUtil.SPACE, tone);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将输入字符串转为拼音,以字符为单位插入分隔符
|
* 将输入字符串转为拼音,以字符为单位插入分隔符
|
||||||
*
|
*
|
||||||
@ -52,6 +74,18 @@ public class PinyinUtil {
|
|||||||
return getEngine().getPinyin(str, separator);
|
return getEngine().getPinyin(str, separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将输入字符串转为拼音,以字符为单位插入分隔符
|
||||||
|
*
|
||||||
|
* @param str 任意字符,汉字返回拼音,非汉字原样返回
|
||||||
|
* @param separator 每个字拼音之间的分隔符
|
||||||
|
* @param tone 是否返回声调
|
||||||
|
* @return 汉字返回拼音,非汉字原样返回
|
||||||
|
*/
|
||||||
|
public static String getPinyin(final String str, final String separator, boolean tone) {
|
||||||
|
return getEngine().getPinyin(str, separator, tone);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将输入字符串转为拼音首字母,其它字符原样返回
|
* 将输入字符串转为拼音首字母,其它字符原样返回
|
||||||
*
|
*
|
||||||
|
@ -36,8 +36,26 @@ public class Bopomofo4jEngine implements PinyinEngine {
|
|||||||
return Bopomofo4j.pinyin(String.valueOf(c), ToneType.WITHOUT_TONE, false, false, StrUtil.EMPTY);
|
return Bopomofo4j.pinyin(String.valueOf(c), ToneType.WITHOUT_TONE, false, false, StrUtil.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(char c, boolean tone) {
|
||||||
|
if (tone) {
|
||||||
|
return Bopomofo4j.pinyin(String.valueOf(c), ToneType.WITH_VOWEL_TONE, false, false, StrUtil.EMPTY);
|
||||||
|
}else{
|
||||||
|
return getPinyin(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPinyin(String str, String separator) {
|
public String getPinyin(String str, String separator) {
|
||||||
return Bopomofo4j.pinyin(str, ToneType.WITHOUT_TONE, false, false, separator);
|
return Bopomofo4j.pinyin(str, ToneType.WITHOUT_TONE, false, false, separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(String str, String separator, boolean tone) {
|
||||||
|
if (tone) {
|
||||||
|
return Bopomofo4j.pinyin(str, ToneType.WITH_VOWEL_TONE, false, false, separator);
|
||||||
|
}else{
|
||||||
|
return getPinyin(str, separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,10 +65,28 @@ public class HoubbPinyinEngine implements PinyinEngine {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(char c, boolean tone) {
|
||||||
|
if (tone){
|
||||||
|
return PinyinHelper.toPinyin(String.valueOf(c), PinyinStyleEnum.DEFAULT);
|
||||||
|
}else {
|
||||||
|
return getPinyin(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPinyin(String str, String separator) {
|
public String getPinyin(String str, String separator) {
|
||||||
String result;
|
String result;
|
||||||
result = PinyinHelper.toPinyin(str, format, separator);
|
result = PinyinHelper.toPinyin(str, format, separator);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(String str, String separator, boolean tone) {
|
||||||
|
if(tone){
|
||||||
|
return PinyinHelper.toPinyin(str, PinyinStyleEnum.DEFAULT, separator);
|
||||||
|
}else {
|
||||||
|
return getPinyin(str,separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,16 @@ public class JPinyinEngine implements PinyinEngine {
|
|||||||
return ArrayUtil.isEmpty(results) ? String.valueOf(c) : results[0];
|
return ArrayUtil.isEmpty(results) ? String.valueOf(c) : results[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(char c, boolean tone) {
|
||||||
|
if (tone) {
|
||||||
|
String[] results = PinyinHelper.convertToPinyinArray(c, PinyinFormat.WITH_TONE_MARK);
|
||||||
|
return ArrayUtil.isEmpty(results) ? String.valueOf(c) : results[0];
|
||||||
|
}else {
|
||||||
|
return getPinyin(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPinyin(String str, String separator) {
|
public String getPinyin(String str, String separator) {
|
||||||
try {
|
try {
|
||||||
@ -61,4 +71,19 @@ public class JPinyinEngine implements PinyinEngine {
|
|||||||
throw new cn.hutool.extra.pinyin.PinyinException(e);
|
throw new cn.hutool.extra.pinyin.PinyinException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(String str, String separator, boolean tone) {
|
||||||
|
if (tone) {
|
||||||
|
try {
|
||||||
|
return PinyinHelper.convertToPinyinString(str, separator, PinyinFormat.WITH_TONE_MARK);
|
||||||
|
} catch (PinyinException e) {
|
||||||
|
throw new cn.hutool.extra.pinyin.PinyinException(e);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
return getPinyin(str, separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,31 @@ public class Pinyin4jEngine implements PinyinEngine {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(char c, boolean tone) {
|
||||||
|
String result;
|
||||||
|
if(tone){
|
||||||
|
try {
|
||||||
|
//增加声调
|
||||||
|
HanyuPinyinOutputFormat formatTemp = new HanyuPinyinOutputFormat();
|
||||||
|
// 小写
|
||||||
|
formatTemp.setCaseType(HanyuPinyinCaseType.LOWERCASE);
|
||||||
|
// 加声调
|
||||||
|
formatTemp.setToneType(HanyuPinyinToneType.WITH_TONE_MARK);
|
||||||
|
//
|
||||||
|
formatTemp.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
|
||||||
|
String[] results = PinyinHelper.toHanyuPinyinStringArray(c, formatTemp);
|
||||||
|
result = ArrayUtil.isEmpty(results) ? String.valueOf(c) : results[0];
|
||||||
|
} catch (BadHanyuPinyinOutputFormatCombination e) {
|
||||||
|
result = String.valueOf(c);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
result = getPinyin(c);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPinyin(String str, String separator) {
|
public String getPinyin(String str, String separator) {
|
||||||
final StrBuilder result = StrUtil.strBuilder();
|
final StrBuilder result = StrUtil.strBuilder();
|
||||||
@ -107,4 +132,41 @@ public class Pinyin4jEngine implements PinyinEngine {
|
|||||||
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPinyin(String str, String separator, boolean tone) {
|
||||||
|
if(tone){
|
||||||
|
final StrBuilder result = StrUtil.strBuilder();
|
||||||
|
boolean isFirst = true;
|
||||||
|
final int strLen = str.length();
|
||||||
|
try {
|
||||||
|
for(int i = 0; i < strLen; i++){
|
||||||
|
if(isFirst){
|
||||||
|
isFirst = false;
|
||||||
|
} else{
|
||||||
|
result.append(separator);
|
||||||
|
}
|
||||||
|
//增加声调
|
||||||
|
HanyuPinyinOutputFormat formatTemp = new HanyuPinyinOutputFormat();
|
||||||
|
// 小写
|
||||||
|
formatTemp.setCaseType(HanyuPinyinCaseType.LOWERCASE);
|
||||||
|
// 加声调
|
||||||
|
formatTemp.setToneType(HanyuPinyinToneType.WITH_TONE_MARK);
|
||||||
|
//
|
||||||
|
formatTemp.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
|
||||||
|
final String[] pinyinStringArray = PinyinHelper.toHanyuPinyinStringArray(str.charAt(i), formatTemp);
|
||||||
|
if(ArrayUtil.isEmpty(pinyinStringArray)){
|
||||||
|
result.append(str.charAt(i));
|
||||||
|
} else{
|
||||||
|
result.append(pinyinStringArray[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (BadHanyuPinyinOutputFormatCombination e) {
|
||||||
|
throw new PinyinException(e);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}else {
|
||||||
|
return getPinyin(str, separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,10 @@ public abstract class HttpBase<T> {
|
|||||||
*/
|
*/
|
||||||
public static final String HTTP_1_1 = "HTTP/1.1";
|
public static final String HTTP_1_1 = "HTTP/1.1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否聚合重复请求头
|
||||||
|
*/
|
||||||
|
protected boolean isHeaderAggregated = false;
|
||||||
/**
|
/**
|
||||||
* 存储头信息
|
* 存储头信息
|
||||||
*/
|
*/
|
||||||
@ -276,6 +280,26 @@ public abstract class HttpBase<T> {
|
|||||||
this.headers.clear();
|
this.headers.clear();
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置是否需要聚合重复的请求头,将重复的请求头聚合为,拼接
|
||||||
|
*
|
||||||
|
* @param aggregate 是否需要聚合
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public T headerAggregation(boolean aggregate) {
|
||||||
|
this.isHeaderAggregated = aggregate;
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取是否需要聚合请求头状态
|
||||||
|
*
|
||||||
|
* @return isHeaderAggregated 请求头聚合状态
|
||||||
|
*/
|
||||||
|
public boolean isHeaderAggregated() {
|
||||||
|
return isHeaderAggregated;
|
||||||
|
}
|
||||||
// ---------------------------------------------------------------- Headers end
|
// ---------------------------------------------------------------- Headers end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -229,6 +229,31 @@ public class HttpConnection {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置请求头<br>
|
||||||
|
* 不覆盖原有请求头并判断是否需要聚合请求头
|
||||||
|
*
|
||||||
|
* @param headerMap 请求头
|
||||||
|
* @param isOverride 是否覆盖
|
||||||
|
* @param isHeaderAggregated 是否聚合
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
public HttpConnection header(Map<String, List<String>> headerMap, boolean isOverride, boolean isHeaderAggregated) {
|
||||||
|
if (!isHeaderAggregated){
|
||||||
|
return header(headerMap,isOverride);
|
||||||
|
}
|
||||||
|
if (MapUtil.isNotEmpty(headerMap)) {
|
||||||
|
String name;
|
||||||
|
for (Entry<String, List<String>> entry : headerMap.entrySet()) {
|
||||||
|
name = entry.getKey();
|
||||||
|
List<String> values = entry.getValue();
|
||||||
|
String headValues = StrUtil.join(",", values);
|
||||||
|
this.header(name, StrUtil.nullToEmpty(headValues), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取Http请求头
|
* 获取Http请求头
|
||||||
*
|
*
|
||||||
|
@ -1247,7 +1247,7 @@ public class HttpRequest extends HttpBase<HttpRequest> {
|
|||||||
// issue#3462 自定义body长度
|
// issue#3462 自定义body长度
|
||||||
.setFixedLengthStreamingMode(this.fixedContentLength)
|
.setFixedLengthStreamingMode(this.fixedContentLength)
|
||||||
// 覆盖默认Header
|
// 覆盖默认Header
|
||||||
.header(this.headers, false);
|
.header(this.headers, false, this.isHeaderAggregated);
|
||||||
|
|
||||||
if (null != this.cookie) {
|
if (null != this.cookie) {
|
||||||
// 当用户自定义Cookie时,全局Cookie自动失效
|
// 当用户自定义Cookie时,全局Cookie自动失效
|
||||||
|
@ -270,4 +270,17 @@ public class HttpRequestTest {
|
|||||||
HttpRequest request = HttpRequest.get("http://localhost:9999/qms/bus/qmsBusReportCenterData/getReportDataList?reportProcessNo=A00&goodsName=工业硫酸98%&conReportTypeId=1010100000000000007&measureDateStr=2024-07-01");
|
HttpRequest request = HttpRequest.get("http://localhost:9999/qms/bus/qmsBusReportCenterData/getReportDataList?reportProcessNo=A00&goodsName=工业硫酸98%&conReportTypeId=1010100000000000007&measureDateStr=2024-07-01");
|
||||||
request.execute();
|
request.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHttpHead(){
|
||||||
|
Map<String,String> map = new HashMap<>();
|
||||||
|
map.put("test","test");
|
||||||
|
HttpRequest httpRequest = HttpRequest.post("http://127.0.0.1:8080/testHttpHead")
|
||||||
|
.header("test","test1")
|
||||||
|
.headerMap(map,false)
|
||||||
|
.headerAggregation(true);
|
||||||
|
System.out.println(httpRequest.headers());
|
||||||
|
HttpResponse execute = httpRequest.execute();
|
||||||
|
System.out.println(execute.body());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
package cn.hutool.http;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个简单的http服务器示例代码;
|
||||||
|
* 用于打印出接收到的请求头和简单的post-json的请求体数据来测试
|
||||||
|
*
|
||||||
|
* @author ZhangWeinan
|
||||||
|
* @date 2025/2/23 15:32
|
||||||
|
*/
|
||||||
|
public class SimpleHttpServer {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
int port = 8080;
|
||||||
|
ServerSocket serverSocket = new ServerSocket(port);
|
||||||
|
System.out.println("Server started on port " + port);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Socket clientSocket = serverSocket.accept();
|
||||||
|
new Thread(() -> handleClient(clientSocket)).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleClient(Socket clientSocket) {
|
||||||
|
try (BufferedReader in = new BufferedReader(
|
||||||
|
new InputStreamReader(clientSocket.getInputStream()));
|
||||||
|
OutputStream out = clientSocket.getOutputStream()) {
|
||||||
|
String requestLine = in.readLine();
|
||||||
|
if (requestLine == null) return;
|
||||||
|
|
||||||
|
String[] parts = requestLine.split(" ");
|
||||||
|
String method = parts[0];
|
||||||
|
|
||||||
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
String line;
|
||||||
|
System.out.println("\n=== Headers ===");
|
||||||
|
while (!(line = in.readLine()).isEmpty()) {
|
||||||
|
int colonIndex = line.indexOf(':');
|
||||||
|
if (colonIndex > 0) {
|
||||||
|
String key = line.substring(0, colonIndex).trim();
|
||||||
|
String value = line.substring(colonIndex + 1).trim();
|
||||||
|
headers.put(key, value);
|
||||||
|
System.out.println(key + ": " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ("POST".equalsIgnoreCase(method)) {
|
||||||
|
int contentLength = Integer.parseInt(headers.getOrDefault("Content-Length", "0"));
|
||||||
|
if (contentLength > 0) {
|
||||||
|
char[] body = new char[contentLength];
|
||||||
|
in.read(body, 0, contentLength);
|
||||||
|
String jsonBody = new String(body);
|
||||||
|
System.out.println("\n=== JSON Body ===");
|
||||||
|
System.out.println(jsonBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String response = "HTTP/1.1 200 OK\r\n" +
|
||||||
|
"Content-Type: text/plain\r\n" +
|
||||||
|
"Content-Length: 16\r\n\r\n" +
|
||||||
|
"Request received";
|
||||||
|
out.write(response.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
clientSocket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user