文章目录
- 一、简要概述
- 二、封装过程
- 1. 引入依赖
- 2. 定义脚本执行类
- 三、单元测试
- 四、其他资源
一、简要概述
在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具。它支持文件的上传和下载,是综合传输工具,但按传统,习惯称curl为下载工具。它被广泛应用在Unix、多种Linux发行版中,并且有DOS和Win32、Win64下的移植版本。
借助JAVA的shell脚本执行方法,我们可以在curl命令支持下,封装出一个代码精简且功能丰富的HTTP调用工具类。
二、封装过程
1. 引入依赖
pom.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.16</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.15.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.2</version>
</dependency>
2. 定义脚本执行类
ShellExecutor.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.SystemUtils;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ShellExecutor
{
/**
* execute命令
*
* @param command
* @throws IOException
*/
public static void exec(String command)
{
try
{
log.info("✈✈✈✈✈ WILL EXECUTE COMMAND: {} ✈✈✈✈✈", command);
String[] cmd = SystemUtils.IS_OS_WINDOWS ? new String[] {"cmd", "/c", command} : new String[] {"/bin/sh", "-c", command};
Runtime.getRuntime().exec(cmd);
}
catch (IOException e)
{
log.error(e.getMessage(), e);
}
}
/**
* execute命令
*
* @param command
* @return 执行结果
* @throws IOException
*/
public static String execute(String command)
{
try
{
log.info("✈✈✈✈✈ WILL EXECUTE COMMAND: {} ✈✈✈✈✈", command);
String[] cmd = SystemUtils.IS_OS_WINDOWS ? new String[] {"cmd", "/c", command} : new String[] {"/bin/sh", "-c", command};
List<String> resultList = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(cmd).getInputStream())))
{
String line;
while ((line = br.readLine()) != null)
{
resultList.add(line);
}
}
return StringUtils.join(resultList, System.lineSeparator());
}
catch (IOException e)
{
log.error(e.getMessage(), e);
return "";
}
}
}
上面的代码中,我们我们定义了2个方法:
exec
适用于不带返回值或返回值为非String类型的接口调用。
execute
带String类返回值,适用于restful接口json数据返回值的接口调用。
三、单元测试
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Test;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ShellExecutorTest
{
@Test
public void test001()
throws IOException
{
String response = ShellExecutor.execute("curl https://00fly.online/upload/data.json");
log.info(response);
}
@Test
public void test002()
throws IOException
{
ShellExecutor.exec("curl -X GET -H \"Accept:image/jpeg\" -H \"Content-Type:application/x-www-form-urlencoded\" \"https://00fly.online/upload/2019/02/201902262129360274AKuFZcUfip.jpg\" --output cat.jpg");
}
@Test
public void test003()
throws IOException
{
String response = ShellExecutor.execute("curl https://00fly.online/upload/data.json");
FileUtils.writeStringToFile(new File("test.json"), response, StandardCharsets.UTF_8, false);
}
@Test
public void test004()
throws IOException
{
ShellExecutor.exec("curl https://00fly.online/upload/data.json -o test.json");
ShellExecutor.exec("curl https://00fly.online/upload/data.json --output test2.json");
}
@Test
public void test005()
throws IOException
{
// 模仿浏览器、伪造referer
String response = ShellExecutor
.execute("curl -A \"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.0)\" -e \"blog.csdn.net\" \"https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=20&businessType=lately&noMore=false&username=qq_16127313\"");
log.info(response);
}
@Test
public void test006()
throws IOException
{
// 伪造referer
String response = ShellExecutor.execute("curl -e \"blog.csdn.net\" \"https://blog.csdn.net/community/home-api/v1/get-business-list?page=1&size=20&businessType=lately&noMore=false&username=qq_16127313\"");
log.info(response);
}
}
四、其他资源
更多CURL命令高级用法,请参考curl文档
另外,在线接口文档knife4j、httpbin等已经集成了等价curl命令,各位可以拷贝测试自行探索。
注意:如果需要将包含此工具的工程打包成docker镜像,一定要在镜像构建文件Dockerfile中安装curl
#安装curl
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && apk update && apk add curl
有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!
-over-