如何使用 Undertow 返回要在 Java 中下载的文件?

Jaq*_*arh 3 java web undertow

我试图允许我的游戏客户端下载客户端运行所需的缓存。在我的游戏网络服务器内部我正在这样做:

@RouteManifest(template="/cache", method="GET")
public class APICacheRoute extends RouteHttpHandler<JadePreprocessor> {
    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
        Path path = Paths.get("./cache/Alterscape.zip");
        File file = path.toFile();
        exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/octet-stream");
        exchange.getResponseSender().send(file);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我收到错误消息,该文件必须是 ByteBuffer。如何返回文件以供下载?

我的网络服务器如下所示:

public static void initialize() {
    ServerController server = new ServerController("localhost", 8080, 8443);
    server.register(new APIVirtualHost());
    server.inititialize();
}
Run Code Online (Sandbox Code Playgroud)

我的 APIVirtualHost 如下所示:

public APIVirtualHost() {
    super(127.0.0.1);
    setDirectoryListingEnabled(false);
}
Run Code Online (Sandbox Code Playgroud)

mwi*_*rek 6

使用 Undertow,您需要从 I/O 线程分派处理程序才能使用阻塞操作。任何时候需要执行阻塞操作时都需要执行此操作,例如读取请求正文、接受文件上传流,当然还有发送文件。

在handle()方法的顶部,使用它将请求分派到阻塞线程,并关闭非阻塞I/O线程:

if (serverExchange.isInIoThread()) {
    serverExchange.dispatch(this);
    return;
}
Run Code Online (Sandbox Code Playgroud)

然后当你准备好发送缓冲区时开始阻塞:

serverExchange.startBlocking();
Run Code Online (Sandbox Code Playgroud)

然后要发送文件,您可以使用缓冲流:

serverExchange.getResponseHeaders().put(Headers.CONTENT_TYPE, "application/octet-stream");

final File file = new File("/location/to/your/file");
final OutputStream outputStream = serverExchange.getOutputStream();
final InputStream inputStream = new FileInputStream(file);

byte[] buf = new byte[8192];
int c;
while ((c = inputStream.read(buf, 0, buf.length)) > 0) {
    outputStream.write(buf, 0, c);
    outputStream.flush();
}

outputStream.close();
inputStream.close();
Run Code Online (Sandbox Code Playgroud)

send对象上的方法用于ServerExchange使用非阻塞方法发送响应数据 - 适用于文本或 JSON。参数ByteBuffer重载用于发送原始字节数据,这是 Undertow 在发送时将字符串转换为的数据。这可能有点误导。

快乐编码。