文件下载

下载文档

用于说明如何在 Java 后端应用程序中实现 PDF 和 DOCX 文件的下载功能

环境依赖

在开始之前,请确保您的项目已添加以下依赖:

  • hutool-core: 提供工具类,例如资源访问工具。

下载 PDF 文件

实现步骤

  • 定义请求路径:使用@RequestPath("/download/pdf/{id}")注解标注方法,定义了处理 PDF 文件下载的请求路径。
  • 读取文件:使用 ResourceUtil.getStream("pdf/" + id + ".pdf")根据文件 ID 动态获取 PDF 文件的输入流。
  • 发送响应:将 PDF 文件内容以字节形式发送给客户端,并设置 Content-Type 为 application/pdf; charset=utf-8。

示例代码

@RequestPath("/download/pdf/{id}")
public HttpResponse downloadPdf(String id, HttpRequest request) {
  log.info("id:{}", id);
  InputStream inputStream = ResourceUtil.getStream("pdf/" + id + ".pdf");
  int available;
  try {
    available = inputStream.available();
    byte[] fileBytes = new byte[available];
    inputStream.read(fileBytes, 0, available);
    HttpResponse response = Resps.bytesWithContentType(request, fileBytes, "application/pdf; charset=utf-8");
    return response;
  } catch (IOException e) {
    e.printStackTrace();
    return Resps.json(request, RespVo.fail("Error generating captcha"));
  }
}

下载 DOCX 文件

实现步骤

  • 定义请求路径:使用@RequestPath("/download/docx/{id}")注解标注方法,定义了处理 DOCX 文件下载的请求路径。
  • 读取文件:使用 ResourceUtil.getStream(id+".docx")根据文件 ID 动态获取 DOCX 文件的输入流。
  • 发送响应:将 DOCX 文件内容以字节形式发送给客户端,并设置 Content-Type 为 application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=utf-8。

示例代码

@RequestPath("/download/docx/{id}")
public HttpResponse download(String id, HttpRequest request) {
  InputStream inputStream = ResourceUtil.getStream(id+".docx");
  int available;
  try {
    available = inputStream.available();
    byte[] fileBytes = new byte[available];
    inputStream.read(fileBytes, 0, available);
    String contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml. document; charset=utf-8";
    HttpResponse response = Resps.bytesWithContentType(request, fileBytes, contentType);
    return response;
  } catch (IOException e) {
    e.printStackTrace();
    return Resps.json(request, RespVo.fail("Error generating captcha"));
  }
}

结论 通过上述实现,您可以方便地在您的 Java Web 应用中添加文件下载功能,支持多种文件格式,如 PDF 和 DOCX。请注意,文件路径和命名方式可能需要根据实际项目情况进行调整。

下载完整代码示例

import java.io.IOException;
import java.io.InputStream;

import com.litongjava.tio.http.common.HttpRequest;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.http.server.util.Resps;
import com.litongjava.tio.utils.resp.RespVo;

import cn.hutool.core.io.resource.ResourceUtil;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class DownloadController {
  @RequestPath("/download/pdf/{id}")
  public HttpResponse downloadPdf(String id, HttpRequest request) {
    log.info("id:{}", id);
    InputStream inputSteam = ResourceUtil.getStream("pdf/" + id + ".pdf");
    int available;
    try {
      available = inputSteam.available();
      byte[] captchaBytes = new byte[available];
      inputSteam.read(captchaBytes, 0, available);

      HttpResponse response = Resps.bytesWithContentType(request, captchaBytes, "application/pdf; charset=utf-8");
      return response;
    } catch (IOException e) {
      e.printStackTrace();
      return Resps.json(request, RespVo.fail("Error generating captcha"));
    }
  }

  @RequestPath("/download/docx/{id}")
  public HttpResponse download(String id, HttpRequest request) {
    log.info("id:{}", id);
    InputStream inputSteam = ResourceUtil.getStream(id + ".docx");
    int available;
    try {
      available = inputSteam.available();
      byte[] captchaBytes = new byte[available];
      inputSteam.read(captchaBytes, 0, available);
      // Content-Type:
      HttpResponse response = Resps.bytesWithContentType(request, captchaBytes,
          "application/vnd.openxmlformats-officedocument.wordprocessingml.document; charset=utf-8");
      return response;
    } catch (IOException e) {
      e.printStackTrace();
      return Resps.json(request, RespVo.fail("Error generating captcha"));
    }
  }

}

下载图片

返回验证码

用到了 hutool 依赖,请自行添加


import java.io.ByteArrayOutputStream;
import java.io.IOException;

import com.litongjava.tio.http.common.HttpRequest;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.http.server.util.Resps;
import com.litongjava.tio.utils.resp.RespVo;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
@AController
@RequestPath("/captcha")
public class CaptchaController {

  @RequestPath("")
  public HttpResponse captcha(HttpRequest request) {
    // 创建线性验证码
    LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100);

    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
      // 获取验证码图片,并写入到输出流
      captcha.write(outputStream);

      // 将输出流转换为字节数组
      byte[] captchaBytes = outputStream.toByteArray();

      // 使用 Resps 工具类创建一个包含验证码图片的响应
      HttpResponse response = Resps.bytesWithContentType(request, captchaBytes, "image/jpeg");

      // 返回响应
      return response;
    } catch (IOException e) {
      e.printStackTrace();
      return Resps.json(request, RespVo.fail("Error generating captcha"));
    }
  }
}

这段代码定义了一个 Java 控制器类,用于生成并返回一个图形验证码。它利用了 hutool 库中的 CaptchaUtil 工具和 tio-boot 网络框架。以下是对代码的详细解释:

  1. 包和导入:

    • package com.litongjava.tio.boot.hello.AController;: 定义了类所在的包。
    • 导入了需要用到的类和接口,包括处理 HTTP 请求和响应的类,验证码生成工具类等。
  2. 类和注解:

    • @RequestPath("/captcha"): 类级别的注解,设置请求的路径。在这个例子中,类处理以 /captcha 开头的请求。
    • public class CaptchaController: 定义了一个名为 CaptchaController 的公共类。
  3. 方法和路由:

    • @RequestPath(""): 方法级别的注解,指定当访问 /captcha 路径时,调用此方法。
    • public HttpResponse captcha(HttpRequest request): 定义了一个处理 HTTP 请求的方法,接收一个 HttpRequest 对象。
  4. 生成验证码:

    • LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100): 使用 hutoolCaptchaUtil 生成一个线性(LineCaptcha)验证码,尺寸为 200x100 像素。
  5. 创建和返回响应:

    • try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()): 使用 try-with-resources 语句创建一个 ByteArrayOutputStream 实例,确保流在操作结束后会被正确关闭。
    • captcha.write(outputStream): 将验证码图片写入到输出流。
    • byte[] captchaBytes = outputStream.toByteArray(): 将输出流转换为字节数组。
    • HttpResponse response = Resps.bytesWithContentType(request, captchaBytes, "image/jpeg"): 使用 Resps.bytesWithContentType 方法创建一个新的 HttpResponse,其中包含验证码图片数据,设置内容类型为“image/jpeg”。
  6. 异常处理:

    • catch (IOException e): 捕获并处理可能在验证码生成或响应创建过程中出现的 IO 异常。
    • e.printStackTrace(): 打印错误堆栈信息。
    • return Resps.json(request, RespVo.fail("Error generating captcha")): 发生异常时返回一个包含错误信息的 JSON 响应。

总结:这个控制器的作用是生成一个图形验证码,并将它作为 HTTP 响应以图片的形式返回给客户端。如果在生成验证码的过程中出现问题,它会返回一个包含错误信息的 JSON 响应。

返回二维码

添加依赖

<dependency>
  <groupId>com.google.zxing</groupId>
  <artifactId>core</artifactId>
  <version>3.4.1</version> <!-- 使用最新版本 -->
</dependency>
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import com.litongjava.tio.http.common.HttpRequest;
import com.litongjava.tio.http.common.HttpResponse;
import com.litongjava.tio.http.server.annotation.RequestPath;
import com.litongjava.tio.http.server.util.Resps;
import com.litongjava.tio.utils.resp.RespVo;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
@AController
@RequestPath("/qr")
public class QrController {

  @RequestPath("")
  public HttpResponse qr(HttpRequest request, String content) {
    // 获取要生成的二维码内容
    if (StrUtil.isBlank(content)) {
      return Resps.json(request, RespVo.fail("No content provided for QR code"));
    }

    try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
      // 生成二维码图片,并写入到输出流
      QrCodeUtil.generate(content, 300, 300, "png", outputStream);

      // 将输出流转换为字节数组
      byte[] qrCodeBytes = outputStream.toByteArray();

      // 使用 Resps 工具类创建一个包含二维码图片的响应
      HttpResponse response = Resps.bytesWithContentType(request, qrCodeBytes, "image/png");

      // 返回响应
      return response;
    } catch (IOException e) {
      e.printStackTrace();
      return Resps.json(request, RespVo.fail("Error generating QR code"));
    }
  }
}

测试访问 http://localhost/qr?content=tio-boot
这段代码是一个 Java 控制器类,用于生成并返回一个二维码图片。它是基于 hutool 库的 QrCodeUtil 工具和 tio 网络框架实现的。以下是对代码的逐行解释:

  1. 类和注解:

    • @RequestPath("/qr"): 这是一个类级别的注解,用于设置请求的路径。在这个例子中,它将处理以 /qr 开头的请求。
    • public class QrController: 定义了一个名为 QrController 的公共类。
  2. 方法和路由:

    • @RequestPath(""): 方法级别的注解,指定当访问 /qr 路径时,将调用此方法。
    • public HttpResponse qr(HttpRequest request, String content): 定义了一个处理 HTTP 请求的方法。它接收两个参数:一个 HttpRequest 对象和一个 String 类型的 content
  3. 生成二维码:

    • if (StrUtil.isBlank(content)): 检查传入的 content 字符串是否为空。如果为空,则返回一个包含错误信息的 JSON 响应。
    • try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()): 使用 try-with-resources 语句创建一个 ByteArrayOutputStream 实例。这确保了流在操作结束后会被正确关闭。
    • QrCodeUtil.generate(content, 300, 300, "png", outputStream): 使用 hutoolQrCodeUtil 生成一个尺寸为 300x300 像素的 PNG 格式二维码,并写入到 outputStream
  4. 创建响应:

    • byte[] qrCodeBytes = outputStream.toByteArray(): 将输出流转换为字节数组。
    • HttpResponse response = Resps.bytesWithContentType(request, qrCodeBytes, "image/png"): 使用 Resps.bytesWithContentType 方法创建一个新的 HttpResponse,其中包含二维码图片数据和设置为“image/png”的内容类型。
  5. 异常处理:

    • catch (IOException e): 捕获并处理可能在二维码生成或响应创建过程中出现的 IO 异常。
    • e.printStackTrace(): 打印错误堆栈信息。
    • return Resps.json(request, RespVo.fail("Error generating QR code")): 发生异常时返回一个包含错误信息的 JSON 响应。
  6. 请求示例:

    • 访问 http://localhost/qr?content=tio-boot 将会触发这个控制器方法,content=tio-boot 表示生成包含文本 “tio-boot” 的二维码。

这个控制器的作用是接收一个文本内容,并将其转换为二维码图片,然后将这个图片作为 HTTP 响应返回给客户端。如果在生成二维码的过程中出现问题,它会返回一个包含错误信息的 JSON 响应。