How to return a file to download in Java using Undertow?

Jaquarh :

I am trying to allow my game client to download the cache needed for the client to run. Inside of my game web server I am doing this:

@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);
    }
}

However, I am receiving the error that the file must be a ByteBuffer. How can I return a file to download?

My web server looks like this:

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

My APIVirtualHost looks like this:

public APIVirtualHost() {
    super(127.0.0.1);
    setDirectoryListingEnabled(false);
}
mwieczorek :

With Undertow, you need to dispatch the handler off the I/O thread to use a blocking operation. You'll need to do this any time you need to perform blocking operations, such as reading the a request body, accepting a file upload stream, and of course, sending a file.

At the top of your handle() method, use this to dispatch the request to a blocking thread, and off the non-blocking I/O thread:

if (serverExchange.isInIoThread()) {
    serverExchange.dispatch(this);
    return;
}

Then start blocking when you're ready to send the buffer:

serverExchange.startBlocking();

Then to send a file, you can use a Buffered stream:

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();

The send method on the ServerExchange object is for sending response data using the non-blocking method - good for text or JSON. The ByteBuffer argument overload is for sending raw byte data, which is what Undertow converts strings to when sending. It can be a bit misleading.

Happy Coding.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=151645&siteId=1