Как вернуть файл для загрузки в Java с помощью Undertow? - PullRequest
2 голосов
/ 08 марта 2019

Я пытаюсь разрешить моему игровому клиенту загружать кеш, необходимый для его работы.Внутри моего игрового веб-сервера я делаю это:

@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.Как я могу вернуть файл для загрузки?

Мой веб-сервер выглядит так:

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

1 Ответ

1 голос
/ 08 марта 2019

При использовании Undertow вам необходимо отправить обработчик из потока ввода-вывода, чтобы использовать операцию блокировки. Это необходимо делать каждый раз, когда вам нужно выполнить операции блокировки, такие как чтение тела запроса, принятие потока загрузки файла и, конечно, отправка файла.

В верхней части вашего метода handle () используйте его, чтобы отправить запрос в блокирующий поток и отключить неблокирующий поток ввода-вывода:

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

Метод send на объекте ServerExchange предназначен для отправки данных ответа с использованием неблокирующего метода - подходит для текста или JSON. Перегрузка аргумента ByteBuffer предназначена для отправки необработанных байтовых данных, в которые Undertow преобразует строки при отправке. Это может вводить в заблуждение.

Счастливое кодирование.

...