如何使用 Undertow return 将文件下载到 Java?
How to return a file to download in Java using 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);
}
}
但是,我收到文件必须是 ByteBuffer 的错误消息。我怎样才能 return 下载一个文件?
我的网络服务器如下所示:
public static void initialize() {
ServerController server = new ServerController("localhost", 8080, 8443);
server.register(new APIVirtualHost());
server.inititialize();
}
我的 APIVirtualHost 如下所示:
public APIVirtualHost() {
super(127.0.0.1);
setDirectoryListingEnabled(false);
}
使用 Undertow,您需要将处理程序分派到 I/O 线程以使用阻塞操作。您需要在任何需要执行阻塞操作的时候执行此操作,例如读取请求正文、接受文件上传流,当然还有发送文件。
在 handle() 方法的顶部,使用它来将请求分派到阻塞线程,并关闭非阻塞 I/O 线程:
if (serverExchange.isInIoThread()) {
serverExchange.dispatch(this);
return;
}
然后在您准备好发送缓冲区时开始阻塞:
serverExchange.startBlocking();
然后要发送文件,可以使用缓冲流:
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();
ServerExchange
对象上的 send
方法用于使用非阻塞方法发送响应数据 - 适用于文本或 JSON。 ByteBuffer
参数重载用于发送原始字节数据,这是 Undertow 在发送时将字符串转换成的内容。这可能有点误导。
快乐编码。
尝试用这个 io.undertow.server.handlers.BlockingHandler
包装您自己的处理程序。它已经包含执行阻塞操作之前的必要检查。
public final class BlockingHandler implements HttpHandler {
...
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
exchange.startBlocking();
if (exchange.isInIoThread()) {
exchange.dispatch(handler);
} else {
handler.handleRequest(exchange);
}
}
...
}
我正在尝试让我的游戏客户端将客户端所需的缓存下载到 运行。在我的游戏网络服务器中,我正在这样做:
@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);
}
}
但是,我收到文件必须是 ByteBuffer 的错误消息。我怎样才能 return 下载一个文件?
我的网络服务器如下所示:
public static void initialize() {
ServerController server = new ServerController("localhost", 8080, 8443);
server.register(new APIVirtualHost());
server.inititialize();
}
我的 APIVirtualHost 如下所示:
public APIVirtualHost() {
super(127.0.0.1);
setDirectoryListingEnabled(false);
}
使用 Undertow,您需要将处理程序分派到 I/O 线程以使用阻塞操作。您需要在任何需要执行阻塞操作的时候执行此操作,例如读取请求正文、接受文件上传流,当然还有发送文件。
在 handle() 方法的顶部,使用它来将请求分派到阻塞线程,并关闭非阻塞 I/O 线程:
if (serverExchange.isInIoThread()) {
serverExchange.dispatch(this);
return;
}
然后在您准备好发送缓冲区时开始阻塞:
serverExchange.startBlocking();
然后要发送文件,可以使用缓冲流:
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();
ServerExchange
对象上的 send
方法用于使用非阻塞方法发送响应数据 - 适用于文本或 JSON。 ByteBuffer
参数重载用于发送原始字节数据,这是 Undertow 在发送时将字符串转换成的内容。这可能有点误导。
快乐编码。
尝试用这个 io.undertow.server.handlers.BlockingHandler
包装您自己的处理程序。它已经包含执行阻塞操作之前的必要检查。
public final class BlockingHandler implements HttpHandler {
...
@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
exchange.startBlocking();
if (exchange.isInIoThread()) {
exchange.dispatch(handler);
} else {
handler.handleRequest(exchange);
}
}
...
}