J'essaie de configurer Vert.X avec Jersey pour gérer les données POST (pas nécessairement des données de formulaire). Le ContainerRequest.setEntityStream
de Jersey prend dans un InputStream
qui est ce que j'essaye de construire Cependant, je ne peux pas sembler se passer autour de ces données sans lire la chose en mémoire à l'aide bodyHandler
ou ma propre méthode personnalisée qui fait quelque chose de similaire, mais limite l'entréeVert.x ReadStream <Buffer> à InputStream
final Buffer body = Buffer.buffer();
event
.handler(buffer -> {
if (!event.response().headWritten()) {
body.appendBuffer(buffer);
if (body.length() > 10 * 1024 * 1024) {
event.response()
.setStatusCode(REQUEST_ENTITY_TOO_LARGE.getStatusCode())
.setStatusMessage(REQUEST_ENTITY_TOO_LARGE.getReasonPhrase())
.end();
}
}
})
.endHandler(aVoid -> {
request.setEntityStream(new VertxBufferInputStream(body));
appHandler.handle(request);
});
VertxBufferInputStream
est une enveloppe simple au VertXbuffer . Juste pour économiser de la mémoire en évitant de convertir en ByteArrayInputStream(). Mais il a tout le corps.
Je veux éviter d'avoir le corps entier et le faire couler. J'ai essayé quelques trucs tout à fait hacky et mauvais code qui finalement ne fonctionne pas parce qu'il bloque la boucle d'événement parce que le handler
n'est pas appelé et l'attend.
Merci aussi j'ai regardé dedans. Une de mes tentatives était similaire à cela mais elle bloque toujours car "take()" bloquera. –
Je ne comprends pas. C'est parfaitement ok; 'take()' bloque (c'est le contrat de 'InputStream.read()').La partie importante est ce que j'ai décrit à [1], le 'ApplicationHandler.handle()' doit être délégué à un thread différent. Par conséquent, la méthode 'take()' est appelée par cet autre thread et tout fonctionne parfaitement. Il n'y a pas d'autre moyen que celui-ci, à moins que Jersey ne soit équipé d'une API non bloquante, ce qui ne s'est pas produit (malheureusement, mais c'était proche). –
Correct c'est le plus proche. (Je viens de le faire travailler maintenant) –