Estamos utilizando Zuul para reenviar solicitudes a un microservicio interno. El servicio interno tiene 2 puntos finales (un punto final PUT y un punto final POST). Descubrimos que las solicitudes de varias partes se dañan antes de que lleguen a nuestro punto final PUT interno.
Los datos de varias partes parecen haber sido eliminados de la solicitud. Este solo parece ser el caso con las solicitudes PUT porque POST funciona perfectamente.
Si golpeamos el punto final PUT interno directamente con cURL, la solicitud se maneja correctamente. El comando cURL correspondiente y el cuerpo de la solicitud tienen este aspecto:
curl -v -X PUT -H "Content-Type: multipart/form-data" -F "file=@/path/to/file.txt" "http://localhost:8081/file/put"Encabezados:
{user-agent=[curl/7.35.0], host=[localhost:8082], accept=[/], content-length=[203], expect=[100-continue], content-type=[multipart/ formulario-datos; límite=------------------------c1efb86a9054e387]}
Entidad:
--------------------------c1efb86a9054e387 Disposición de contenido: datos de formulario; nombre="archivo"; filename="helloworld.txt" Tipo de contenido: texto/simple
este es el contenido de mi archivo
--------------------------c1efb86a9054e387--
Sin embargo, si tratamos de llegar al extremo PUT con cURL a través de Zuul, la solicitud se ve así:
curl -X PUT -H "Content-Type: multipart/form-data" -F "file=@/path/to/file.txt" "http://localhost:8082/file/put"Encabezamiento:
{agente-usuario=[curl/7.35.0], aceptar=[/], esperar=[100-continuar], tipo-contenido=[multipart/form-data;boundary=hkBnDNXOcDTwkuL1qLhglF6i4NA2YREd], x-forwarded-host=[ localhost:8081], x-forwarded-proto=[http], x-forwarded-prefix=[/file], x-forwarded-port=[8081], x-forwarded-for=[127.0.0.1], accept- codificación=[gzip], contenido-longitud=[38], host=[localhost:8082], conexión=[Keep-Alive]}
Entidad:
--hkBnDNXOcDTwkuL1qLhglF6i4NA2YREd--
Observe que la Entidad está incompleta.
He subido un código de ejemplo a este repositorio: https://github.com/trcodestore/zuul-put-demo . El repositorio contiene 2 pequeños proyectos utilizados para demostrar este problema. El archivo Léame contiene instrucciones de compilación y ejecución.
Entiendo que las solicitudes son manejadas inicialmente por DispatcherServlet de Spring y luego son manejadas eventualmente por ZuulServlet. Creo que es DispatcherServlet el que está causando el problema. Podemos omitir el DispatcherServlet anteponiendo todos nuestros URI de solicitud con "/zuul"; esto permite que la solicitud de varias partes vaya directamente a ZuulServlet y luego funcione como se esperaba. Sin embargo, esta no es una solución ideal.
Cualquier consejo sería apreciado. Gracias.
Bien, tengo la solución ( crédito: Mohammad Zolmajd ).
Spring Boot usa StandardServletMultipartResolver para manejar varias partes, lo que supone que todas las solicitudes de varias partes se enviarán con POST.
Para permitir que StandardServletMultipartResolver maneje solicitudes PUT, debemos anular el método isMultiPart . Terminé usando la siguiente configuración:
@Bean public MultipartResolver multipartResolver() { return new StandardServletMultipartResolver() { @Override public boolean isMultipart(HttpServletRequest request) { String method = request.getMethod().toLowerCase(); if (!Arrays.asList("put", "post").contains(method)) { return false; } String contentType = request.getContentType(); return (contentType != null &&contentType.toLowerCase().startsWith("multipart/")); } }; }