对接第三文件下载接口,通过restTemplate或java执行linux的cmd指令完成

2023-11-18

对接第三文件下载接口,通过restTemplate或java执行linux的cmd指令完成

1.业务场景

与其他第三方通过restful接口对接,需调用第三方文件下载接口。
这里有两个思路,一种是用http client调用第三方接口进行文件下载。另一种可以通过java执行系统(linux)的cmd指令,进行文件下载,从而实现对下载文件的管理。

2.通过restTemplate.exhcange()方法下载文件

  // 1.请求下载文件接口
HttpHeaders headers = new HttpHeaders();
headers.add("content-type", "application/x-www-form-urlencoded");
RestTemplate restTemplate = new RestTemplate();
String id = "id123";
String invalid = "in123";
ResponseEntity<byte[]> entity = restTemplate.exchange(
                "localhost:8080/download?id=${id}&invalid=${invalid}",
                HttpMethod.POST,
                new HttpEntity<>(headers),
                byte[].class,
                id,
                invalid);
// 2.获取二进制数据,写入inputStream
byte[] bytes = entity.getBody();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);

// 3.从heads中获取fileName,在获取文件名称时需进行预防空指针
List<String> list = entity.getHeaders().get("content-disposition");
String fileName = list.get(0).split("filename=")[1];

// 4.通过outputStream返数据
String agent = request.getHeader("USER-AGENT");
log.info("[ndss] request's agent is :{}", agent);

try {
  // 设置heads
  headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
  headers.add("Content-Disposition", "inline;filename=" + fileName);
  headers.add("Pragma", "no-cache");
  headers.add("Expires", "0");
  response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
  response.setContentType("application/octet-stream;charset=UTF-8");
  response.setHeader("Pragma", "no-cache");
  response.setDateHeader("Expires", 0);
  response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
  response.setHeader("Access-Control-Allow-Credentials", "true");
  response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, PATCH, DELETE");
  response.setHeader("Access-Control-Max-Age", "3600");
  response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

  OutputStream fos = response.getOutputStream();

  byte[] b = new byte[1024];
  int length;
  while ((length = inputStream.read(b)) > 0) {
    fos.write(b, 0, length);
  }
  fos.flush();
  inputStream.close();
  fos.close();

  return ResponseEntity
    .ok()
    .headers(headers)
    .body("下载成功");
} catch (Exception e) {
  log.error("文件下载出错,错误信息:{}", e.toString());
  return ResponseEntity
    .ok()
    .body("文件下载失败。");
}

3.通过java调用linux指令进行文件下载

主要思路是通过服务器的curl指令请求第三方接口进行文件下载。

通过java调用linux的cmd指令,通过curl调用文件下载接口,可以将文件下载本地,再读取本地文件进行操作。

核心代码如下:

private void executeLinuxCmd(String cmd) {
  System.out.println("got cmd job : " + cmd);
  Runtime run = Runtime.getRuntime();
  try {
    Process process = run.exec(cmd);
    InputStream in = process.getInputStream();
    BufferedReader bs = new BufferedReader(new InputStreamReader(in));
    StringBuffer out = new StringBuffer();
    byte[] b = new byte[8192];
    for (int n; (n = in.read(b)) != -1; ) {
      out.append(new String(b, 0, n));
    }
    log.info("execute cmd job result:[ +{}+]", out.toString());
    in.close();
    process.destroy();
  } catch (IOException e) {
    log.error("execute cmd job err:{}", e.toString());
  }
}

4.WebClient

在翻阅restTemplate文档时,看到这么一段话。

As of Spring Framework 5, alongside the WebFlux stack, Spring introduced a new HTTP client called WebClient.
WebClient is a modern, alternative HTTP client to RestTemplate. Not only does it provide a traditional synchronous API, but it also supports an efficient nonblocking and asynchronous approach.
That said, if we're developing new applications or migrating an old one, it's a good idea to use WebClient. Moving forward, RestTemplate will be deprecated in future versions.

Spring Framework 5开始,引入了新的http client工具–webClient,特点是支持异步。webClient的使用后续再进行梳理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对接第三文件下载接口,通过restTemplate或java执行linux的cmd指令完成 的相关文章

  • 使用 BlobOutputStream 在 Azure 中上传 blob

    我正在尝试直接从流上传 blob 因为我不知道我决定尝试的流的长度这个答案 https stackoverflow com a 24621538 3695939 这不起作用 即使它从流中读取并且不会抛出任何异常 内容也不会上传到我的容器 我
  • 我可以在 Java 枚举上使用构建器模式吗

    我正在重写一些代码 并且我已经决定了重新创建类的方法 因为有固定数量的工作表 我将它们创建为枚举 这是基于构建器模式与伸缩构造器的可读性的决定 我的代码获取一些 xls 文件 添加标题 并从其他 xls 文件中读取一些 也许还有一些子表 然
  • Spring Security 自定义身份验证 - AuthenticationProvider 与 UserDetailsS​​ervice

    据我所知 当您想要在 Spring Security 中进行自定义身份验证时 您可以实现自定义AuthenticationProvider或定制UserDetailsService Autowired public void configu
  • 我需要在 Java 9 中使用哪个模块才能使用 JPA?

    我正在使用一个需要 JPA 的项目测试 Java 9 javax persistence 类 当我添加module info java并声明我的模块 下的所有类javax persistece包变得不可用 我搜索了很多 但找不到在 Java
  • Java 7u51/7u55 带星号的清单变量

    我正在部署一个小程序 其中包含清单中的下一个变量 Manifest Version 2 0 Ant Version Apache Ant 1 8 2 Trusted Library true Permissions all permissi
  • Java中如何对对象数组进行排序?

    我的数组不包含任何字符串 但它包含对象引用 每个对象引用都通过 toString 方法返回名称 id 作者和发布者 public String toString return name n id n author n publisher n
  • 参考接口创建对象

    引用变量可以声明为类类型或接口类型 如果变量声明为接口类型 则它可以引用实现该接口的任何类的任何对象 根据上面的说法我做了一个理解上的代码 正如上面所说声明为接口类型 它可以引用实现该接口的任何类的任何对象 但在我的代码中显示display
  • 使用 Microsoft REST API - Java 将 Xbox-Live GamerTag 转换为 XUID

    我有一个 Java 应用程序 它需要能够获取用户输入的 Minecraft Bedrock Edition 玩家标签 并将其转换为给定帐户的 XUID 以便我可以将其存储起来以供稍后列入白名单和参考目的 我一直在浏览 Microsoft R
  • 检查更新时 Maven 无限期挂起

    我正在使用 Maven 构建一个项目 我是新手 并且它挂起 mvn package INFO Scanning for projects INFO INFO Building Presentation Reports INFO task s
  • @Transactional 注解属于哪里?

    如果您将 Transactional in the DAO类和 或其方法 或者注释使用 DAO 对象调用的服务类是否更好 或者注释两个 层 是否有意义 我认为事务属于服务层 它是了解工作单元和用例的人 如果您将多个 DAO 注入到需要在单个
  • 从 Java 应用程序读取的文件是否会调用系统调用?

    我的理解是 请求文件系统路径 例如 aFile 的用户应用程序将调用文件系统并获取所请求文件的虚拟地址 然后应用程序将尝试以该地址作为参数 即作为 CPU 指令 进行读 写操作 执行读取命令时 内存管理单元会将该地址转换为物理地址 并查看页
  • 为什么 CompletableFuture 的 thenAccept() 不在主线程上运行

    我在 CompletableFuture 的 SupplyAsync 中处理长时间运行的操作 并将结果放入 thenAccept 中 有时 thenAccept 在主线程上执行 但有时它在工作线程上运行 但我只想在主线程上运行 thenAc
  • 莫基托。验证方法参数是特定类

    我有一个方法 void putObject
  • 运行 Espresso 测试时在 Android studio 中找不到属性 android:forceQueryable

    我已经使用 android studio 录制了我的 Android 应用程序 Espresso 测试记录浓缩咖啡测试选项中Run菜单 在记录的最后 我用自己的文件名保存了测试 单击保存按钮后 IDE 会自动在以下位置创建文件Android
  • 尝试通过 Java 8 中的 JDBC-ODBC 连接到 .accdb 文件时出现 ClassNotFoundException

    我正在 Eclipse EE IDE 中的 Java 项目中工作 我必须在其中查询 accdb文件 问题是当我尝试加载驱动程序然后连接到数据库时 它给了我一个异常错误 My code try String filePath myfilepa
  • 可空日期列合并问题

    我在 Geronimo 应用程序服务器上使用 JPA 和下面的 openjpa 实现 我也在使用MySQL数据库 我在更新具有可为空 Date 属性的对象时遇到问题 当我尝试合并 Date 属性设置为 null 的实体时 不会生成 sql
  • 如果 @transactional 在类级别应用,如何拦截 @transactional 参数

    我想捕获 transactional 的参数 如果它应用于类级别 例如如果 transactional应用在方法级别 例如 class A transactional readOnly true public void someMethod
  • java - 简单计算在多线程中比在单线程中花费更长的时间

    我试图了解如何利用多线程 我写了一个简单的程序来增加i 比方说 使用两种方式 400 000 次 单线程方式 0 到 400 000 和多线程方式 在我的例子中 4 次 0 到 100 000 线程数等于Runtime getRuntime
  • Bipush 在 JVM 中如何工作?

    我知道 iload 接受整数 1 到 5 但是如何使用 bipush 指令扩展到更高的数字 特定整数如何与字节码一起存储 有几种不同的指令可用于推送整数常量 最小的是iconst 指令 这些只是一个字节 因为该值是在操作码本身中编码的 ic
  • RetentionPolicy CLASS 与 RUNTIME

    两者之间有什么实际区别RetentionPolicy CLASS and RetentionPolicy RUNTIME 看起来两者都被记录到字节码中 并且无论如何都可以在运行时访问 无论如何 两者都可以在运行时访问 那不是那个javado

随机推荐