Как правильно прочитать тело запроса POST в обработчике?
Код, который я использую сейчас:
Pooled<ByteBuffer> pooledByteBuffer = exchange.getConnection().getBufferPool().allocate();
ByteBuffer byteBuffer = pooledByteBuffer.getResource();
int limit = byteBuffer.limit();
byteBuffer.clear();
exchange.getRequestChannel().read(byteBuffer);
int pos = byteBuffer.position();
byteBuffer.rewind();
byte[] bytes = new byte[pos];
byteBuffer.get(bytes);
String requestBody = new String(bytes, Charset.forName("UTF-8") );
byteBuffer.clear();
pooledByteBuffer.free();
Кажется, что все работает нормально, но я не уверен в необходимости clear()
ByteBuffer перед возвратом в пул. Я даже не уверен в использовании exchange.getConnection().getBufferPool().allocate();
. В документации не так много.
Ответы
Ответ 1
Простейший способ прочитать тело запроса - отправить в рабочий поток, что делает доступным HttpExchange#getInputStream()
.
Есть два способа сделать это: используя BlockingHandler
или шаблон отправки, указанный в документации. Здесь приведен пример использования BlockingHandler
:
new BlockingHandler(myHandler)
BlockingHandler
в основном отправляет вам сообщение.
Ответ 2
@atok, я использую ваш метод некоторое время, но иногда я получаю пустое тело, когда поток закрыт перед вызовом чтения. Это работает как прелесть:
BufferedReader reader = null;
StringBuilder builder = new StringBuilder( );
try {
exchange.startBlocking( );
reader = new BufferedReader( new InputStreamReader( exchange.getInputStream( ) ) );
String line;
while( ( line = reader.readLine( ) ) != null ) {
builder.append( line );
}
} catch( IOException e ) {
e.printStackTrace( );
} finally {
if( reader != null ) {
try {
reader.close( );
} catch( IOException e ) {
e.printStackTrace( );
}
}
}
String body = builder.toString( );
Ответ 3
import io.undertow.Handlers;
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import io.undertow.server.handlers.BlockingHandler;
public static void main(String[] args) {
Undertow server = Undertow.builder()
.addHttpListener(8087, "xx.xx.xx.xx")
.setHandler(Handlers.pathTemplate().add("/webhook", new BlockingHandler(new ItemHandler())))
.build();
server.start();
}
static class ItemHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
exchange.getInputStream());
}
}