mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add method
This commit is contained in:
parent
d41b917006
commit
ab4f58bb31
@ -9,6 +9,8 @@
|
||||
* 【all】 升级JDK最低 支持到8
|
||||
* 【log】 Log接口添加get的static方法
|
||||
* 【all】 部分接口添加FunctionalInterface修饰
|
||||
* 【crypto】 KeyUtil增加readKeyStore重载
|
||||
* 【extra】 JschUtil增加私钥传入支持(issue#INKDR@Gitee)
|
||||
|
||||
### Bug修复
|
||||
* 【http】 修复Cookie中host失效导致的问题(issue#583@Github)
|
||||
|
@ -1549,6 +1549,12 @@ public class FileUtil {
|
||||
String pathToUse = StrUtil.removePrefixIgnoreCase(path, URLUtil.CLASSPATH_URL_PREFIX);
|
||||
// 去除file:前缀
|
||||
pathToUse = StrUtil.removePrefixIgnoreCase(pathToUse, URLUtil.FILE_URL_PREFIX);
|
||||
|
||||
// 识别home目录形式,并转换为绝对路径
|
||||
if(pathToUse.startsWith("~")){
|
||||
pathToUse = pathToUse.replace("~", getUserHomePath());
|
||||
}
|
||||
|
||||
// 统一使用斜杠
|
||||
pathToUse = pathToUse.replaceAll("[/\\\\]+", StrUtil.SLASH).trim();
|
||||
//兼容Windows下的共享目录路径(原始路径如果以\\开头,则保留这种路径)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.hutool.crypto;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
@ -32,6 +33,7 @@ import javax.crypto.spec.PBEKeySpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
@ -619,6 +621,20 @@ public class KeyUtil {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取密钥库(Java Key Store,JKS) KeyStore文件<br>
|
||||
* KeyStore文件用于数字证书的密钥对保存<br>
|
||||
* see: http://snowolf.iteye.com/blog/391931
|
||||
*
|
||||
* @param keyFile 证书文件
|
||||
* @param password 密码
|
||||
* @return {@link KeyStore}
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public static KeyStore readJKSKeyStore(File keyFile, char[] password) {
|
||||
return readKeyStore(KEY_TYPE_JKS, keyFile, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取密钥库(Java Key Store,JKS) KeyStore文件<br>
|
||||
* KeyStore文件用于数字证书的密钥对保存<br>
|
||||
@ -632,6 +648,53 @@ public class KeyUtil {
|
||||
return readKeyStore(KEY_TYPE_JKS, in, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取PKCS12 KeyStore文件<br>
|
||||
* KeyStore文件用于数字证书的密钥对保存
|
||||
*
|
||||
* @param keyFile 证书文件
|
||||
* @param password 密码
|
||||
* @return {@link KeyStore}
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public static KeyStore readPKCS12KeyStore(File keyFile, char[] password) {
|
||||
return readKeyStore(KEY_TYPE_PKCS12, keyFile, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取PKCS12 KeyStore文件<br>
|
||||
* KeyStore文件用于数字证书的密钥对保存
|
||||
*
|
||||
* @param in {@link InputStream} 如果想从文件读取.keystore文件,使用 {@link FileUtil#getInputStream(java.io.File)} 读取
|
||||
* @param password 密码
|
||||
* @return {@link KeyStore}
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public static KeyStore readPKCS12KeyStore(InputStream in, char[] password) {
|
||||
return readKeyStore(KEY_TYPE_PKCS12, in, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取KeyStore文件<br>
|
||||
* KeyStore文件用于数字证书的密钥对保存<br>
|
||||
* see: http://snowolf.iteye.com/blog/391931
|
||||
*
|
||||
* @param type 类型
|
||||
* @param keyFile 证书文件
|
||||
* @param password 密码,null表示无密码
|
||||
* @return {@link KeyStore}
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public static KeyStore readKeyStore(String type, File keyFile, char[] password) {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = FileUtil.getInputStream(keyFile);
|
||||
return readKeyStore(type, in, password);
|
||||
} finally {
|
||||
IoUtil.close(in);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取KeyStore文件<br>
|
||||
* KeyStore文件用于数字证书的密钥对保存<br>
|
||||
|
@ -1,11 +1,11 @@
|
||||
package cn.hutool.db.nosql.mongo;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import cn.hutool.core.exceptions.NotInitedException;
|
||||
import cn.hutool.core.net.NetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.DbRuntimeException;
|
||||
import cn.hutool.log.Log;
|
||||
import cn.hutool.setting.Setting;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoClientOptions;
|
||||
import com.mongodb.MongoClientOptions.Builder;
|
||||
@ -13,14 +13,11 @@ import com.mongodb.MongoCredential;
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import org.bson.Document;
|
||||
|
||||
import cn.hutool.core.exceptions.NotInitedException;
|
||||
import cn.hutool.core.net.NetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.db.DbRuntimeException;
|
||||
import cn.hutool.log.Log;
|
||||
import cn.hutool.log.StaticLog;
|
||||
import cn.hutool.setting.Setting;
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MongoDB工具类
|
||||
@ -29,7 +26,7 @@ import cn.hutool.setting.Setting;
|
||||
*
|
||||
*/
|
||||
public class MongoDS implements Closeable {
|
||||
private final static Log log = StaticLog.get();
|
||||
private final static Log log = Log.get();
|
||||
|
||||
/** 默认配置文件 */
|
||||
public final static String MONGO_CONFIG_PATH = "config/mongo.setting";
|
||||
@ -188,7 +185,7 @@ public class MongoDS implements Closeable {
|
||||
setting = new Setting(MONGO_CONFIG_PATH, true);
|
||||
}
|
||||
|
||||
final List<ServerAddress> addrList = new ArrayList<ServerAddress>();
|
||||
final List<ServerAddress> addrList = new ArrayList<>();
|
||||
for (String group : groups) {
|
||||
addrList.add(createServerAddress(group));
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import cn.hutool.setting.Setting;
|
||||
*
|
||||
*/
|
||||
public class UploadSetting {
|
||||
private static Log log = StaticLog.get();
|
||||
private static final Log log = Log.get();
|
||||
|
||||
/** 默认的配置文件路径(相对ClassPath) */
|
||||
public final static String DEFAULT_SETTING_PATH = "config/upload.setting";
|
||||
|
@ -1,42 +1,44 @@
|
||||
package cn.hutool.extra.ssh;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* Jsch会话池
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public enum JschSessionPool {
|
||||
INSTANCE;
|
||||
|
||||
/** SSH会话池,key:host,value:Session对象 */
|
||||
private Map<String, Session> sessionPool = new ConcurrentHashMap<String, Session>();
|
||||
/** 锁 */
|
||||
/**
|
||||
* SSH会话池,key:host,value:Session对象
|
||||
*/
|
||||
private Map<String, Session> sessionPool = new ConcurrentHashMap<>();
|
||||
/**
|
||||
* 锁
|
||||
*/
|
||||
private static final Object lock = new Object();
|
||||
|
||||
/**
|
||||
* 获取Session,不存在返回null
|
||||
*
|
||||
*
|
||||
* @param key 键
|
||||
* @return Session
|
||||
*/
|
||||
public Session get(String key) {
|
||||
return sessionPool.get(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获得一个SSH跳板机会话,重用已经使用的会话
|
||||
*
|
||||
*
|
||||
* @param sshHost 跳板机主机
|
||||
* @param sshPort 跳板机端口
|
||||
* @param sshUser 跳板机用户名
|
||||
@ -58,10 +60,35 @@ public enum JschSessionPool {
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得一个SSH跳板机会话,重用已经使用的会话
|
||||
*
|
||||
* @param sshHost 跳板机主机
|
||||
* @param sshPort 跳板机端口
|
||||
* @param sshUser 跳板机用户名
|
||||
* @param prvkey 跳板机私钥路径
|
||||
* @param passphrase 跳板机私钥密码
|
||||
* @return SSH会话
|
||||
*/
|
||||
public Session getSession(String sshHost, int sshPort, String sshUser, String prvkey, byte[] passphrase) {
|
||||
final String key = StrUtil.format("{}@{}:{}", sshUser, sshHost, sshPort);
|
||||
Session session = get(key);
|
||||
if (null == session || false == session.isConnected()) {
|
||||
synchronized (lock) {
|
||||
session = get(key);
|
||||
if (null == session || false == session.isConnected()) {
|
||||
session = JschUtil.openSession(sshHost, sshPort, sshUser, prvkey, passphrase);
|
||||
put(key, session);
|
||||
}
|
||||
}
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入Session
|
||||
*
|
||||
* @param key 键
|
||||
*
|
||||
* @param key 键
|
||||
* @param session Session
|
||||
*/
|
||||
public void put(String key, Session session) {
|
||||
@ -70,7 +97,7 @@ public enum JschSessionPool {
|
||||
|
||||
/**
|
||||
* 关闭SSH连接会话
|
||||
*
|
||||
*
|
||||
* @param key 主机,格式为user@host:port
|
||||
*/
|
||||
public void close(String key) {
|
||||
@ -80,20 +107,20 @@ public enum JschSessionPool {
|
||||
}
|
||||
sessionPool.remove(key);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移除指定Session
|
||||
*
|
||||
*
|
||||
* @param session Session会话
|
||||
* @since 4.1.15
|
||||
*/
|
||||
public void remove(Session session) {
|
||||
if(null != session) {
|
||||
if (null != session) {
|
||||
final Iterator<Entry<String, Session>> iterator = this.sessionPool.entrySet().iterator();
|
||||
Entry<String, Session> entry;
|
||||
while(iterator.hasNext()) {
|
||||
while (iterator.hasNext()) {
|
||||
entry = iterator.next();
|
||||
if(session.equals(entry.getValue())) {
|
||||
if (session.equals(entry.getValue())) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
|
@ -1,43 +1,41 @@
|
||||
package cn.hutool.extra.ssh;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.net.LocalPortGenerater;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.jcraft.jsch.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
import com.jcraft.jsch.ChannelShell;
|
||||
import com.jcraft.jsch.JSch;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.net.LocalPortGenerater;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* Jsch工具类<br>
|
||||
* Jsch是Java Secure Channel的缩写。JSch是一个SSH2的纯Java实现。<br>
|
||||
* 它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等。<br>
|
||||
*
|
||||
*
|
||||
* @author Looly
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class JschUtil {
|
||||
|
||||
/** 不使用SSH的值 */
|
||||
/**
|
||||
* 不使用SSH的值
|
||||
*/
|
||||
public final static String SSH_NONE = "none";
|
||||
|
||||
/** 本地端口生成器 */
|
||||
/**
|
||||
* 本地端口生成器
|
||||
*/
|
||||
private static final LocalPortGenerater portGenerater = new LocalPortGenerater(10000);
|
||||
|
||||
/**
|
||||
* 生成一个本地端口,用于远程端口映射
|
||||
*
|
||||
*
|
||||
* @return 未被使用的本地端口
|
||||
*/
|
||||
public static int generateLocalPort() {
|
||||
@ -46,7 +44,7 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 获得一个SSH会话,重用已经使用的会话
|
||||
*
|
||||
*
|
||||
* @param sshHost 主机
|
||||
* @param sshPort 端口
|
||||
* @param sshUser 用户名
|
||||
@ -57,9 +55,23 @@ public class JschUtil {
|
||||
return JschSessionPool.INSTANCE.getSession(sshHost, sshPort, sshUser, sshPass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得一个SSH会话,重用已经使用的会话
|
||||
*
|
||||
* @param sshHost 主机
|
||||
* @param sshPort 端口
|
||||
* @param sshUser 用户名
|
||||
* @param privateKeyPath 私钥路径
|
||||
* @param passphrase 私钥密码
|
||||
* @return SSH会话
|
||||
*/
|
||||
public static Session getSession(String sshHost, int sshPort, String sshUser, String privateKeyPath, byte[] passphrase) {
|
||||
return JschSessionPool.INSTANCE.getSession(sshHost, sshPort, sshUser, privateKeyPath, passphrase);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开一个新的SSH会话
|
||||
*
|
||||
*
|
||||
* @param sshHost 主机
|
||||
* @param sshPort 端口
|
||||
* @param sshUser 用户名
|
||||
@ -77,39 +89,103 @@ public class JschUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建一个新的SSH会话
|
||||
*
|
||||
* @param sshHost 主机
|
||||
* @param sshPort 端口
|
||||
* @param sshUser 机用户名
|
||||
* @param sshPass 密码
|
||||
* 打开一个新的SSH会话
|
||||
*
|
||||
* @param sshHost 主机
|
||||
* @param sshPort 端口
|
||||
* @param sshUser 用户名
|
||||
* @param privateKeyPath 私钥的路径
|
||||
* @param passphrase 私钥文件的密码,可以为null
|
||||
* @return SSH会话
|
||||
* @since 4.5.2
|
||||
*/
|
||||
public static Session createSession(String sshHost, int sshPort, String sshUser, String sshPass) {
|
||||
if (StrUtil.isEmpty(sshHost) || sshPort < 0 || StrUtil.isEmpty(sshUser) || StrUtil.isEmpty(sshPass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Session session;
|
||||
public static Session openSession(String sshHost, int sshPort, String sshUser, String privateKeyPath, byte[] passphrase) {
|
||||
final Session session = createSession(sshHost, sshPort, sshUser, privateKeyPath, passphrase);
|
||||
try {
|
||||
session = new JSch().getSession(sshUser, sshHost, sshPort);
|
||||
session.setPassword(sshPass);
|
||||
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
session.connect();
|
||||
} catch (JSchException e) {
|
||||
throw new JschRuntimeException(e);
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建一个新的SSH会话,此方法并不打开会话(既不调用connect方法)
|
||||
*
|
||||
* @param sshHost 主机
|
||||
* @param sshPort 端口
|
||||
* @param sshUser 用户名,如果为null,默认root
|
||||
* @param sshPass 密码
|
||||
* @return SSH会话
|
||||
* @since 4.5.2
|
||||
*/
|
||||
public static Session createSession(String sshHost, int sshPort, String sshUser, String sshPass) {
|
||||
Assert.notEmpty(sshHost, "SSH Host must be not empty!");
|
||||
Assert.isTrue(sshPort < 0, "SSH Host must be not empty!");
|
||||
|
||||
// 默认root用户
|
||||
if (StrUtil.isEmpty(sshUser)) {
|
||||
sshUser = "root";
|
||||
}
|
||||
|
||||
final JSch jsch = new JSch();
|
||||
Session session;
|
||||
try {
|
||||
session = jsch.getSession(sshUser, sshHost, sshPort);
|
||||
} catch (JSchException e) {
|
||||
throw new JschRuntimeException(e);
|
||||
}
|
||||
|
||||
if (StrUtil.isNotEmpty(sshPass)) {
|
||||
session.setPassword(sshPass);
|
||||
}
|
||||
|
||||
// 设置第一次登陆的时候提示,可选值:(ask | yes | no)
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建一个新的SSH会话,此方法并不打开会话(既不调用connect方法)
|
||||
*
|
||||
* @param sshHost 主机
|
||||
* @param sshPort 端口
|
||||
* @param sshUser 用户名,如果为null,默认root
|
||||
* @param privateKeyPath 私钥的路径
|
||||
* @param passphrase 私钥文件的密码,可以为null
|
||||
* @return SSH会话
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public static Session createSession(String sshHost, int sshPort, String sshUser, String privateKeyPath, byte[] passphrase) {
|
||||
Assert.notEmpty(sshHost, "SSH Host must be not empty!");
|
||||
Assert.isTrue(sshPort < 0, "SSH Host must be not empty!");
|
||||
Assert.notEmpty(privateKeyPath, "PrivateKey Path must be not empty!");
|
||||
|
||||
// 默认root用户
|
||||
if (StrUtil.isEmpty(sshUser)) {
|
||||
sshUser = "root";
|
||||
}
|
||||
|
||||
final JSch jsch = new JSch();
|
||||
Session session;
|
||||
try {
|
||||
jsch.addIdentity(privateKeyPath, passphrase);
|
||||
session = jsch.getSession(sshUser, sshHost, sshPort);
|
||||
} catch (JSchException e) {
|
||||
throw new JschRuntimeException(e);
|
||||
}
|
||||
|
||||
// 设置第一次登录的时候提示,可选值:(ask | yes | no)
|
||||
session.setConfig("StrictHostKeyChecking", "no");
|
||||
return session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定端口到本地。 一个会话可绑定多个端口
|
||||
*
|
||||
* @param session 需要绑定端口的SSH会话
|
||||
*
|
||||
* @param session 需要绑定端口的SSH会话
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
* @param localPort 本地端口
|
||||
* @param localPort 本地端口
|
||||
* @return 成功与否
|
||||
* @throws JschRuntimeException 端口绑定失败异常
|
||||
*/
|
||||
@ -127,8 +203,8 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 解除端口映射
|
||||
*
|
||||
* @param session 需要解除端口映射的SSH会话
|
||||
*
|
||||
* @param session 需要解除端口映射的SSH会话
|
||||
* @param localPort 需要解除的本地端口
|
||||
* @return 解除成功与否
|
||||
*/
|
||||
@ -143,8 +219,8 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 打开SSH会话,并绑定远程端口到本地的一个随机端口
|
||||
*
|
||||
* @param sshConn SSH连接信息对象
|
||||
*
|
||||
* @param sshConn SSH连接信息对象
|
||||
* @param remoteHost 远程主机
|
||||
* @param remotePort 远程端口
|
||||
* @return 映射后的本地端口
|
||||
@ -162,7 +238,7 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 打开SFTP连接
|
||||
*
|
||||
*
|
||||
* @param session Session会话
|
||||
* @return {@link ChannelSftp}
|
||||
* @since 4.0.3
|
||||
@ -173,7 +249,7 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 创建Sftp
|
||||
*
|
||||
*
|
||||
* @param sshHost 远程主机
|
||||
* @param sshPort 远程主机端口
|
||||
* @param sshUser 远程主机用户名
|
||||
@ -187,7 +263,7 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 创建Sftp
|
||||
*
|
||||
*
|
||||
* @param session SSH会话
|
||||
* @return {@link Sftp}
|
||||
* @since 4.0.5
|
||||
@ -198,7 +274,7 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 打开Shell连接
|
||||
*
|
||||
*
|
||||
* @param session Session会话
|
||||
* @return {@link ChannelShell}
|
||||
* @since 4.0.3
|
||||
@ -209,8 +285,8 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 打开Channel连接
|
||||
*
|
||||
* @param session Session会话
|
||||
*
|
||||
* @param session Session会话
|
||||
* @param channelType 通道类型,可以是shell或sftp等,见{@link ChannelType}
|
||||
* @return {@link Channel}
|
||||
* @since 4.5.2
|
||||
@ -224,11 +300,11 @@ public class JschUtil {
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 创建Channel连接
|
||||
*
|
||||
* @param session Session会话
|
||||
*
|
||||
* @param session Session会话
|
||||
* @param channelType 通道类型,可以是shell或sftp等,见{@link ChannelType}
|
||||
* @return {@link Channel}
|
||||
* @since 4.5.2
|
||||
@ -248,9 +324,9 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 执行Shell命令
|
||||
*
|
||||
*
|
||||
* @param session Session会话
|
||||
* @param cmd 命令
|
||||
* @param cmd 命令
|
||||
* @param charset 发送和读取内容的编码
|
||||
* @return {@link ChannelExec}
|
||||
* @since 4.0.3
|
||||
@ -261,10 +337,10 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 执行Shell命令
|
||||
*
|
||||
* @param session Session会话
|
||||
* @param cmd 命令
|
||||
* @param charset 发送和读取内容的编码
|
||||
*
|
||||
* @param session Session会话
|
||||
* @param cmd 命令
|
||||
* @param charset 发送和读取内容的编码
|
||||
* @param errStream 错误信息输出到的位置
|
||||
* @return {@link ChannelExec}
|
||||
* @since 4.3.1
|
||||
@ -294,7 +370,7 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 关闭SSH连接会话
|
||||
*
|
||||
*
|
||||
* @param session SSH会话
|
||||
*/
|
||||
public static void close(Session session) {
|
||||
@ -306,7 +382,7 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 关闭会话通道
|
||||
*
|
||||
*
|
||||
* @param channel 会话通道
|
||||
* @since 4.0.3
|
||||
*/
|
||||
@ -318,7 +394,7 @@ public class JschUtil {
|
||||
|
||||
/**
|
||||
* 关闭SSH连接会话
|
||||
*
|
||||
*
|
||||
* @param key 主机,格式为user@host:port
|
||||
*/
|
||||
public static void close(String key) {
|
||||
|
@ -21,7 +21,7 @@ public enum GlobalHeaders {
|
||||
INSTANCE;
|
||||
|
||||
/** 存储头信息 */
|
||||
protected Map<String, List<String>> headers = new HashMap<String, List<String>>();
|
||||
protected Map<String, List<String>> headers = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -11,35 +11,30 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.util.CharUtil;
|
||||
|
||||
/**
|
||||
* HTML过滤器,用于去除XSS(Cross Site Scripting) 漏洞隐患。
|
||||
*
|
||||
* HTML filtering utility for protecting against XSS (Cross Site Scripting).
|
||||
* <p>
|
||||
* 此类中的方法非线程安全
|
||||
* </p>
|
||||
*
|
||||
* This code is licensed LGPLv3
|
||||
* <pre>
|
||||
* String clean = new HTMLFilter().filter(input);
|
||||
* </pre>
|
||||
* <p>
|
||||
* 此类来自:http://xss-html-filter.sf.net
|
||||
*
|
||||
* This code is a Java port of the original work in PHP by Cal Hendersen. http://code.iamcal.com/php/lib_filter/
|
||||
*
|
||||
* The trickiest part of the translation was handling the differences in regex handling between PHP and Java. These resources were helpful in the process:
|
||||
*
|
||||
* http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php http://www.regular-expressions.info/modifiers.html
|
||||
*
|
||||
* A note on naming conventions: instance variables are prefixed with a "v"; global constants are in all caps.
|
||||
*
|
||||
* Sample use: String input = ... String clean = new HTMLFilter().filter( input );
|
||||
*
|
||||
* The class is not thread safe. Create a new instance if in doubt.
|
||||
*
|
||||
* If you find bugs or have suggestions on improvement (especially regarding performance), please contact us. The latest version of this source, and our contact details, can be found at
|
||||
* http://xss-html-filter.sf.net
|
||||
*
|
||||
* @author Joseph O'Connell
|
||||
* @author Cal Hendersen
|
||||
* @author Michael Semb Wever
|
||||
*/
|
||||
public final class HTMLFilter {
|
||||
|
||||
/** regex flag union representing /si modifiers in php **/
|
||||
/**
|
||||
* regex flag union representing /si modifiers in php
|
||||
**/
|
||||
private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL;
|
||||
private static final Pattern P_COMMENTS = Pattern.compile("<!--(.*?)-->", Pattern.DOTALL);
|
||||
private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI);
|
||||
@ -66,29 +61,49 @@ public final class HTMLFilter {
|
||||
private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>");
|
||||
|
||||
// @xxx could grow large... maybe use sesat's ReferenceMap
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<String, Pattern>();
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<String, Pattern>();
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>();
|
||||
|
||||
/** set of allowed html elements, along with allowed attributes for each element **/
|
||||
/**
|
||||
* set of allowed html elements, along with allowed attributes for each element
|
||||
**/
|
||||
private final Map<String, List<String>> vAllowed;
|
||||
/** counts of open tags for each (allowable) html element **/
|
||||
private final Map<String, Integer> vTagCounts = new HashMap<String, Integer>();
|
||||
/**
|
||||
* counts of open tags for each (allowable) html element
|
||||
**/
|
||||
private final Map<String, Integer> vTagCounts = new HashMap<>();
|
||||
|
||||
/** html elements which must always be self-closing (e.g. "<img />") **/
|
||||
/**
|
||||
* html elements which must always be self-closing (e.g. "<img />")
|
||||
**/
|
||||
private final String[] vSelfClosingTags;
|
||||
/** html elements which must always have separate opening and closing tags (e.g. "<b></b>") **/
|
||||
/**
|
||||
* html elements which must always have separate opening and closing tags (e.g. "<b></b>")
|
||||
**/
|
||||
private final String[] vNeedClosingTags;
|
||||
/** set of disallowed html elements **/
|
||||
/**
|
||||
* set of disallowed html elements
|
||||
**/
|
||||
private final String[] vDisallowed;
|
||||
/** attributes which should be checked for valid protocols **/
|
||||
/**
|
||||
* attributes which should be checked for valid protocols
|
||||
**/
|
||||
private final String[] vProtocolAtts;
|
||||
/** allowed protocols **/
|
||||
/**
|
||||
* allowed protocols
|
||||
**/
|
||||
private final String[] vAllowedProtocols;
|
||||
/** tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />") **/
|
||||
/**
|
||||
* tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />")
|
||||
**/
|
||||
private final String[] vRemoveBlanks;
|
||||
/** entities allowed within html markup **/
|
||||
/**
|
||||
* entities allowed within html markup
|
||||
**/
|
||||
private final String[] vAllowedEntities;
|
||||
/** flag determining whether comments are allowed in input String. */
|
||||
/**
|
||||
* flag determining whether comments are allowed in input String.
|
||||
*/
|
||||
private final boolean stripComment;
|
||||
private final boolean encodeQuotes;
|
||||
private boolean vDebug = false;
|
||||
@ -100,36 +115,35 @@ public final class HTMLFilter {
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*
|
||||
*/
|
||||
public HTMLFilter() {
|
||||
vAllowed = new HashMap<String, List<String>>();
|
||||
vAllowed = new HashMap<>();
|
||||
|
||||
final ArrayList<String> a_atts = new ArrayList<String>();
|
||||
final ArrayList<String> a_atts = new ArrayList<>();
|
||||
a_atts.add("href");
|
||||
a_atts.add("target");
|
||||
vAllowed.put("a", a_atts);
|
||||
|
||||
final ArrayList<String> img_atts = new ArrayList<String>();
|
||||
final ArrayList<String> img_atts = new ArrayList<>();
|
||||
img_atts.add("src");
|
||||
img_atts.add("width");
|
||||
img_atts.add("height");
|
||||
img_atts.add("alt");
|
||||
vAllowed.put("img", img_atts);
|
||||
|
||||
final ArrayList<String> no_atts = new ArrayList<String>();
|
||||
final ArrayList<String> no_atts = new ArrayList<>();
|
||||
vAllowed.put("b", no_atts);
|
||||
vAllowed.put("strong", no_atts);
|
||||
vAllowed.put("i", no_atts);
|
||||
vAllowed.put("em", no_atts);
|
||||
|
||||
vSelfClosingTags = new String[] { "img" };
|
||||
vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" };
|
||||
vDisallowed = new String[] {};
|
||||
vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp.
|
||||
vProtocolAtts = new String[] { "src", "href" };
|
||||
vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" };
|
||||
vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" };
|
||||
vSelfClosingTags = new String[]{"img"};
|
||||
vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"};
|
||||
vDisallowed = new String[]{};
|
||||
vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp.
|
||||
vProtocolAtts = new String[]{"src", "href"};
|
||||
vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"};
|
||||
vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"};
|
||||
stripComment = true;
|
||||
encodeQuotes = true;
|
||||
alwaysMakeTags = true;
|
||||
@ -202,6 +216,7 @@ public final class HTMLFilter {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* given a user submitted input String, filter out any invalid or restricted html.
|
||||
*
|
||||
@ -292,15 +307,15 @@ public final class HTMLFilter {
|
||||
}
|
||||
m.appendTail(buf);
|
||||
|
||||
s = buf.toString();
|
||||
|
||||
// these get tallied in processTag
|
||||
// (remember to reset before subsequent calls to filter method)
|
||||
final StringBuilder sBuilder = new StringBuilder(buf.toString());
|
||||
for (String key : vTagCounts.keySet()) {
|
||||
for (int ii = 0; ii < vTagCounts.get(key); ii++) {
|
||||
s += "</" + key + ">";
|
||||
sBuilder.append("</").append(key).append(">");
|
||||
}
|
||||
}
|
||||
s = sBuilder.toString();
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -350,12 +365,12 @@ public final class HTMLFilter {
|
||||
|
||||
// debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
|
||||
if (allowed(name)) {
|
||||
String params = "";
|
||||
final StringBuilder params = new StringBuilder();
|
||||
|
||||
final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);
|
||||
final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);
|
||||
final List<String> paramNames = new ArrayList<String>();
|
||||
final List<String> paramValues = new ArrayList<String>();
|
||||
final List<String> paramNames = new ArrayList<>();
|
||||
final List<String> paramValues = new ArrayList<>();
|
||||
while (m2.find()) {
|
||||
paramNames.add(m2.group(1)); // ([a-z0-9]+)
|
||||
paramValues.add(m2.group(3)); // (.*?)
|
||||
@ -378,7 +393,7 @@ public final class HTMLFilter {
|
||||
if (inArray(paramName, vProtocolAtts)) {
|
||||
paramValue = processParamProtocol(paramValue);
|
||||
}
|
||||
params += " " + paramName + "=\"" + paramValue + "\"";
|
||||
params.append(CharUtil.SPACE).append(paramName).append("=\"").append(paramValue).append("\"");
|
||||
}
|
||||
}
|
||||
|
||||
@ -421,9 +436,9 @@ public final class HTMLFilter {
|
||||
final String protocol = m.group(1);
|
||||
if (!inArray(protocol, vAllowedProtocols)) {
|
||||
// bad protocol, turn into local anchor link instead
|
||||
s = "#" + s.substring(protocol.length() + 1, s.length());
|
||||
s = "#" + s.substring(protocol.length() + 1);
|
||||
if (s.startsWith("#//")) {
|
||||
s = "#" + s.substring(3, s.length());
|
||||
s = "#" + s.substring(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -429,9 +429,8 @@ public class HttpConnection {
|
||||
* 当返回错误代码时,获得错误内容流
|
||||
*
|
||||
* @return 错误内容
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public InputStream getErrorStream() throws IOException {
|
||||
public InputStream getErrorStream() {
|
||||
if (null != this.conn) {
|
||||
return this.conn.getErrorStream();
|
||||
}
|
||||
@ -514,8 +513,6 @@ public class HttpConnection {
|
||||
* 初始化http或https请求参数<br>
|
||||
* 有些时候htts请求会出现com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl的实现,此为sun内部api,按照普通http请求处理
|
||||
*
|
||||
* @param hostnameVerifier 域名验证器,非https传入null
|
||||
* @param ssf SSLSocketFactory,非https传入null
|
||||
* @return {@link HttpURLConnection},https返回{@link HttpsURLConnection}
|
||||
*/
|
||||
private HttpURLConnection openHttp() throws IOException {
|
||||
@ -532,7 +529,7 @@ public class HttpConnection {
|
||||
* 建立连接
|
||||
*
|
||||
* @return {@link URLConnection}
|
||||
* @throws IOException
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
private URLConnection openConnection() throws IOException {
|
||||
return (null == this.proxy) ? url.openConnection() : url.openConnection(this.proxy);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.hutool.http;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.CookieManager;
|
||||
|
||||
import cn.hutool.http.cookie.GlobalCookieManager;
|
||||
@ -10,10 +11,11 @@ import cn.hutool.http.cookie.GlobalCookieManager;
|
||||
* @author Looly
|
||||
* @since 4.6.2
|
||||
*/
|
||||
public class HttpGlobalConfig {
|
||||
public class HttpGlobalConfig implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
protected static int timeout = -1;
|
||||
|
||||
|
||||
/**
|
||||
* 获取全局默认的超时时长
|
||||
*
|
||||
|
@ -18,7 +18,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
public class HttpInputStream extends InputStream {
|
||||
|
||||
/** 原始流 */
|
||||
private volatile InputStream in;
|
||||
private InputStream in;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
|
@ -1,21 +1,5 @@
|
||||
package cn.hutool.http;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
@ -25,27 +9,36 @@ import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.io.StreamProgress;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.core.util.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Http请求工具类
|
||||
*
|
||||
*
|
||||
* @author xiaoleilu
|
||||
*/
|
||||
public class HttpUtil {
|
||||
|
||||
/** 正则:Content-Type中的编码信息 */
|
||||
/**
|
||||
* 正则:Content-Type中的编码信息
|
||||
*/
|
||||
public static final Pattern CHARSET_PATTERN = Pattern.compile("charset\\s*=\\s*([a-z0-9-]*)", Pattern.CASE_INSENSITIVE);
|
||||
/** 正则:匹配meta标签的编码信息 */
|
||||
/**
|
||||
* 正则:匹配meta标签的编码信息
|
||||
*/
|
||||
public static final Pattern META_CHARSET_PATTERN = Pattern.compile("<meta[^>]*?charset\\s*=\\s*['\"]?([a-z0-9-]*)", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/**
|
||||
* 检测是否https
|
||||
*
|
||||
*
|
||||
* @param url URL
|
||||
* @return 是否https
|
||||
*/
|
||||
@ -55,9 +48,9 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 创建Http请求对象
|
||||
*
|
||||
*
|
||||
* @param method 方法枚举{@link Method}
|
||||
* @param url 请求的URL,可以使HTTP或者HTTPS
|
||||
* @param url 请求的URL,可以使HTTP或者HTTPS
|
||||
* @return {@link HttpRequest}
|
||||
* @since 3.0.9
|
||||
*/
|
||||
@ -67,7 +60,7 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 创建Http GET请求对象
|
||||
*
|
||||
*
|
||||
* @param url 请求的URL,可以使HTTP或者HTTPS
|
||||
* @return {@link HttpRequest}
|
||||
* @since 3.2.0
|
||||
@ -78,7 +71,7 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 创建Http POST请求对象
|
||||
*
|
||||
*
|
||||
* @param url 请求的URL,可以使HTTP或者HTTPS
|
||||
* @return {@link HttpRequest}
|
||||
* @since 3.2.0
|
||||
@ -89,8 +82,8 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
*
|
||||
* @param urlString 网址
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @param customCharset 自定义请求字符集,如果字符集获取不到,使用此字符集
|
||||
* @return 返回内容,如果只检查状态码,正常只返回 "",不正常返回 null
|
||||
*/
|
||||
@ -100,7 +93,7 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
*
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @return 返回内容,如果只检查状态码,正常只返回 "",不正常返回 null
|
||||
*/
|
||||
@ -110,9 +103,9 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
*
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @param timeout 超时时长,-1表示默认超时,单位毫秒
|
||||
* @param timeout 超时时长,-1表示默认超时,单位毫秒
|
||||
* @return 返回内容,如果只检查状态码,正常只返回 "",不正常返回 null
|
||||
* @since 3.2.0
|
||||
*/
|
||||
@ -122,9 +115,9 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
*
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @param paramMap post表单数据
|
||||
* @param paramMap post表单数据
|
||||
* @return 返回数据
|
||||
*/
|
||||
public static String get(String urlString, Map<String, Object> paramMap) {
|
||||
@ -133,10 +126,10 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 发送get请求
|
||||
*
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @param paramMap post表单数据
|
||||
* @param timeout 超时时长,-1表示默认超时,单位毫秒
|
||||
* @param paramMap post表单数据
|
||||
* @param timeout 超时时长,-1表示默认超时,单位毫秒
|
||||
* @return 返回数据
|
||||
* @since 3.3.0
|
||||
*/
|
||||
@ -146,9 +139,9 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 发送post请求
|
||||
*
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @param paramMap post表单数据
|
||||
* @param paramMap post表单数据
|
||||
* @return 返回数据
|
||||
*/
|
||||
public static String post(String urlString, Map<String, Object> paramMap) {
|
||||
@ -157,10 +150,10 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 发送post请求
|
||||
*
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @param paramMap post表单数据
|
||||
* @param timeout 超时时长,-1表示默认超时,单位毫秒
|
||||
* @param paramMap post表单数据
|
||||
* @param timeout 超时时长,-1表示默认超时,单位毫秒
|
||||
* @return 返回数据
|
||||
* @since 3.2.0
|
||||
*/
|
||||
@ -171,14 +164,14 @@ public class HttpUtil {
|
||||
/**
|
||||
* 发送post请求<br>
|
||||
* 请求体body参数支持两种类型:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 1. 标准参数,例如 a=1&b=2 这种格式
|
||||
* 2. Rest模式,此时body需要传入一个JSON或者XML字符串,Hutool会自动绑定其对应的Content-Type
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @param body post表单数据
|
||||
* @param body post表单数据
|
||||
* @return 返回数据
|
||||
*/
|
||||
public static String post(String urlString, String body) {
|
||||
@ -188,15 +181,15 @@ public class HttpUtil {
|
||||
/**
|
||||
* 发送post请求<br>
|
||||
* 请求体body参数支持两种类型:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 1. 标准参数,例如 a=1&b=2 这种格式
|
||||
* 2. Rest模式,此时body需要传入一个JSON或者XML字符串,Hutool会自动绑定其对应的Content-Type
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @param urlString 网址
|
||||
* @param body post表单数据
|
||||
* @param timeout 超时时长,-1表示默认超时,单位毫秒
|
||||
* @param body post表单数据
|
||||
* @param timeout 超时时长,-1表示默认超时,单位毫秒
|
||||
* @return 返回数据
|
||||
* @since 3.2.0
|
||||
*/
|
||||
@ -205,10 +198,11 @@ public class HttpUtil {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------------- download
|
||||
|
||||
/**
|
||||
* 下载远程文本
|
||||
*
|
||||
* @param url 请求的url
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param customCharsetName 自定义的字符集
|
||||
* @return 文本
|
||||
*/
|
||||
@ -218,8 +212,8 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文本
|
||||
*
|
||||
* @param url 请求的url
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param customCharset 自定义的字符集,可以使用{@link CharsetUtil#charset} 方法转换
|
||||
* @return 文本
|
||||
*/
|
||||
@ -229,10 +223,10 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文本
|
||||
*
|
||||
* @param url 请求的url
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param customCharset 自定义的字符集,可以使用{@link CharsetUtil#charset} 方法转换
|
||||
* @param streamPress 进度条 {@link StreamProgress}
|
||||
* @param streamPress 进度条 {@link StreamProgress}
|
||||
* @return 文本
|
||||
*/
|
||||
public static String downloadString(String url, Charset customCharset, StreamProgress streamPress) {
|
||||
@ -247,8 +241,8 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文件
|
||||
*
|
||||
* @param url 请求的url
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param dest 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名
|
||||
* @return 文件大小
|
||||
*/
|
||||
@ -258,8 +252,8 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文件
|
||||
*
|
||||
* @param url 请求的url
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名
|
||||
* @return 文件大小
|
||||
*/
|
||||
@ -269,10 +263,10 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文件
|
||||
*
|
||||
* @param url 请求的url
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名
|
||||
* @param timeout 超时,单位毫秒,-1表示默认超时
|
||||
* @param timeout 超时,单位毫秒,-1表示默认超时
|
||||
* @return 文件大小
|
||||
* @since 4.0.4
|
||||
*/
|
||||
@ -282,9 +276,9 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文件
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名
|
||||
* @param streamProgress 进度条
|
||||
* @return 文件大小
|
||||
*/
|
||||
@ -294,10 +288,10 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文件
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名
|
||||
* @param timeout 超时,单位毫秒,-1表示默认超时
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param destFile 目标文件或目录,当为目录时,取URL中的文件名,取不到使用编码后的URL做为文件名
|
||||
* @param timeout 超时,单位毫秒,-1表示默认超时
|
||||
* @param streamProgress 进度条
|
||||
* @return 文件大小
|
||||
* @since 4.0.4
|
||||
@ -318,9 +312,9 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文件
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param out 将下载内容写到输出流中 {@link OutputStream}
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param out 将下载内容写到输出流中 {@link OutputStream}
|
||||
* @param isCloseOut 是否关闭输出流
|
||||
* @return 文件大小
|
||||
*/
|
||||
@ -330,10 +324,10 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 下载远程文件
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param out 将下载内容写到输出流中 {@link OutputStream}
|
||||
* @param isCloseOut 是否关闭输出流
|
||||
*
|
||||
* @param url 请求的url
|
||||
* @param out 将下载内容写到输出流中 {@link OutputStream}
|
||||
* @param isCloseOut 是否关闭输出流
|
||||
* @param streamProgress 进度条
|
||||
* @return 文件大小
|
||||
*/
|
||||
@ -354,7 +348,7 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 将Map形式的Form表单数据转换为Url参数形式,不做编码
|
||||
*
|
||||
*
|
||||
* @param paramMap 表单数据
|
||||
* @return url参数
|
||||
*/
|
||||
@ -365,8 +359,8 @@ public class HttpUtil {
|
||||
/**
|
||||
* 将Map形式的Form表单数据转换为Url参数形式<br>
|
||||
* 编码键和值对
|
||||
*
|
||||
* @param paramMap 表单数据
|
||||
*
|
||||
* @param paramMap 表单数据
|
||||
* @param charsetName 编码
|
||||
* @return url参数
|
||||
*/
|
||||
@ -378,13 +372,13 @@ public class HttpUtil {
|
||||
* 将Map形式的Form表单数据转换为Url参数形式<br>
|
||||
* paramMap中如果key为空(null和"")会被忽略,如果value为null,会被做为空白符("")<br>
|
||||
* 会自动url编码键和值
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* key1=v1&key2=&key3=v3
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @param paramMap 表单数据
|
||||
* @param charset 编码
|
||||
* @param charset 编码
|
||||
* @return url参数
|
||||
*/
|
||||
public static String toParams(Map<String, ?> paramMap, Charset charset) {
|
||||
@ -423,16 +417,15 @@ public class HttpUtil {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对URL参数做编码,只编码键和值<br>
|
||||
* 提供的值可以是url附带参数,但是不能只是url
|
||||
*
|
||||
*
|
||||
* <p>注意,此方法只能标准化整个URL,并不适合于单独编码参数值</p>
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param paramsStr url参数,可以包含url本身
|
||||
* @param charset 编码
|
||||
* @param charset 编码
|
||||
* @return 编码后的url和参数
|
||||
* @since 4.0.1
|
||||
*/
|
||||
@ -458,17 +451,17 @@ public class HttpUtil {
|
||||
}
|
||||
|
||||
paramPart = normalizeParams(paramPart, charset);
|
||||
|
||||
|
||||
return StrUtil.isBlank(urlPart) ? paramPart : urlPart + "?" + paramPart;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 标准化参数字符串,即URL中?后的部分
|
||||
*
|
||||
*
|
||||
* <p>注意,此方法只能标准化整个URL,并不适合于单独编码参数值</p>
|
||||
*
|
||||
*
|
||||
* @param paramPart 参数字符串
|
||||
* @param charset 编码
|
||||
* @param charset 编码
|
||||
* @return 标准化的参数字符串
|
||||
* @since 4.5.2
|
||||
*/
|
||||
@ -523,9 +516,9 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 将URL参数解析为Map(也可以解析Post中的键值对参数)
|
||||
*
|
||||
*
|
||||
* @param paramsStr 参数字符串(或者带参数的Path)
|
||||
* @param charset 字符集
|
||||
* @param charset 字符集
|
||||
* @return 参数Map
|
||||
* @since 4.0.2
|
||||
*/
|
||||
@ -542,9 +535,9 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 将URL参数解析为Map(也可以解析Post中的键值对参数)
|
||||
*
|
||||
*
|
||||
* @param paramsStr 参数字符串(或者带参数的Path)
|
||||
* @param charset 字符集
|
||||
* @param charset 字符集
|
||||
* @return 参数Map
|
||||
*/
|
||||
public static Map<String, List<String>> decodeParams(String paramsStr, String charset) {
|
||||
@ -558,7 +551,7 @@ public class HttpUtil {
|
||||
paramsStr = StrUtil.subSuf(paramsStr, pathEndPos + 1);
|
||||
}
|
||||
|
||||
final Map<String, List<String>> params = new LinkedHashMap<String, List<String>>();
|
||||
final Map<String, List<String>> params = new LinkedHashMap<>();
|
||||
final int len = paramsStr.length();
|
||||
String name = null;
|
||||
int pos = 0; // 未处理字符开始位置
|
||||
@ -601,10 +594,10 @@ public class HttpUtil {
|
||||
/**
|
||||
* 将表单数据加到URL中(用于GET表单提交)<br>
|
||||
* 表单的键值对会被url编码,但是url中原参数不会被编码
|
||||
*
|
||||
* @param url URL
|
||||
* @param form 表单数据
|
||||
* @param charset 编码
|
||||
*
|
||||
* @param url URL
|
||||
* @param form 表单数据
|
||||
* @param charset 编码
|
||||
* @param isEncodeParams 是否对键和值做转义处理
|
||||
* @return 合成后的URL
|
||||
*/
|
||||
@ -620,11 +613,11 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 将表单数据字符串加到URL中(用于GET表单提交)
|
||||
*
|
||||
* @param url URL
|
||||
*
|
||||
* @param url URL
|
||||
* @param queryString 表单数据字符串
|
||||
* @param charset 编码
|
||||
* @param isEncode 是否对键和值做转义处理
|
||||
* @param charset 编码
|
||||
* @param isEncode 是否对键和值做转义处理
|
||||
* @return 拼接后的字符串
|
||||
*/
|
||||
public static String urlWithForm(String url, String queryString, Charset charset, boolean isEncode) {
|
||||
@ -662,7 +655,7 @@ public class HttpUtil {
|
||||
/**
|
||||
* 从Http连接的头信息中获得字符集<br>
|
||||
* 从ContentType中获取
|
||||
*
|
||||
*
|
||||
* @param conn HTTP连接对象
|
||||
* @return 字符集
|
||||
*/
|
||||
@ -676,14 +669,13 @@ public class HttpUtil {
|
||||
/**
|
||||
* 从流中读取内容<br>
|
||||
* 首先尝试使用charset编码读取内容(如果为空默认UTF-8),如果isGetCharsetFromContent为true,则通过正则在正文中获取编码信息,转换为指定编码;
|
||||
*
|
||||
* @param in 输入流
|
||||
* @param charset 字符集
|
||||
*
|
||||
* @param in 输入流
|
||||
* @param charset 字符集
|
||||
* @param isGetCharsetFromContent 是否从返回内容中获得编码信息
|
||||
* @return 内容
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
public static String getString(InputStream in, Charset charset, boolean isGetCharsetFromContent) throws IOException {
|
||||
public static String getString(InputStream in, Charset charset, boolean isGetCharsetFromContent) {
|
||||
final byte[] contentBytes = IoUtil.readBytes(in);
|
||||
return getString(contentBytes, charset, isGetCharsetFromContent);
|
||||
}
|
||||
@ -691,9 +683,9 @@ public class HttpUtil {
|
||||
/**
|
||||
* 从流中读取内容<br>
|
||||
* 首先尝试使用charset编码读取内容(如果为空默认UTF-8),如果isGetCharsetFromContent为true,则通过正则在正文中获取编码信息,转换为指定编码;
|
||||
*
|
||||
* @param contentBytes 内容byte数组
|
||||
* @param charset 字符集
|
||||
*
|
||||
* @param contentBytes 内容byte数组
|
||||
* @param charset 字符集
|
||||
* @param isGetCharsetFromContent 是否从返回内容中获得编码信息
|
||||
* @return 内容
|
||||
*/
|
||||
@ -727,11 +719,11 @@ public class HttpUtil {
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据文件扩展名获得MimeType
|
||||
*
|
||||
* @param filePath 文件路径或文件名
|
||||
*
|
||||
* @param filePath 文件路径或文件名
|
||||
* @param defaultValue 当获取MimeType为null时的默认值
|
||||
* @return MimeType
|
||||
* @see FileUtil#getMimeType(String)
|
||||
@ -743,7 +735,7 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 根据文件扩展名获得MimeType
|
||||
*
|
||||
*
|
||||
* @param filePath 文件路径或文件名
|
||||
* @return MimeType
|
||||
* @see FileUtil#getMimeType(String)
|
||||
@ -754,16 +746,16 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 从请求参数的body中判断请求的Content-Type类型,支持的类型有:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* 1. application/json
|
||||
* 1. application/xml
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @param body 请求参数体
|
||||
* @return Content-Type类型,如果无法判断返回null
|
||||
* @since 3.2.0
|
||||
* @see ContentType#get(String)
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static String getContentTypeByRequestBody(String body) {
|
||||
final ContentType contentType = ContentType.get(body);
|
||||
@ -773,20 +765,17 @@ public class HttpUtil {
|
||||
|
||||
/**
|
||||
* 将键值对加入到值为List类型的Map中
|
||||
*
|
||||
* @param params 参数
|
||||
* @param name key
|
||||
* @param value value
|
||||
*
|
||||
* @param params 参数
|
||||
* @param name key
|
||||
* @param value value
|
||||
* @param charset 编码
|
||||
*/
|
||||
private static void addParam(Map<String, List<String>> params, String name, String value, String charset) {
|
||||
name = URLUtil.decode(name, charset);
|
||||
value = URLUtil.decode(value, charset);
|
||||
List<String> values = params.get(name);
|
||||
if (values == null) {
|
||||
values = new ArrayList<String>(1); // 一般是一个参数
|
||||
params.put(name, values);
|
||||
}
|
||||
final List<String> values = params.computeIfAbsent(name, k -> new ArrayList<>(1));
|
||||
// 一般是一个参数
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,9 @@ public final class StaticLog {
|
||||
*
|
||||
* @param clazz 日志发出的类
|
||||
* @return Log
|
||||
* @deprecated 请使用 {@link Log#get(Class)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Log get(Class<?> clazz) {
|
||||
return LogFactory.get(clazz);
|
||||
}
|
||||
@ -230,14 +232,18 @@ public final class StaticLog {
|
||||
*
|
||||
* @param name 自定义的日志发出者名称
|
||||
* @return Log
|
||||
* @deprecated 请使用 {@link Log#get(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Log get(String name) {
|
||||
return LogFactory.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 获得日志,自动判定日志发出者
|
||||
* @deprecated 请使用 {@link Log#get()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Log get() {
|
||||
return LogFactory.get(CallerUtil.getCallerCaller());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user