Manejo de descarga e información JSON

Tengo un método de control estándar para responder a las solicitudes POST en el /products ruta:

@PostMapping(value = "/products")
public ResponseEntity postProduct(@RequestBody ProductUpsertRequestBody postRequest)
{
   .
   .
   .

ProductUpsertRequestBody es sólo una clase simple que uso para capturar la carga útil JSON:

public class ProductUpsertRequestBody implements Serializable
{
    @JsonProperty("id") private String clientProductId;          
    @JsonProperty("product_name")  private String productName;
    @JsonProperty("product_type") private String productType;
    @JsonProperty("cost_in_cents") private Long costInCents;
    @JsonProperty("description")  private String description;
    @JsonProperty("label_color") private String labelColor;
    .
    .
    .

Necesito ampliar mi método de controlador con un MultiPartFile argumento, transformándolo en:

    @PostMapping(value = "/products")
    public ResponseEntity postProduct(@RequestBody ProductUpsertRequestBody postRequest, @RequestParam MultiPartFile myImage)
    {
      .
      .
      .
    

Pero estoy confundido sobre cómo se llamará este método de controlador. No es difícil hacer un frontend rudimentario con un formulario HTML que subyace tantas imágenes como quiera, pero luego pierdo la capacidad de enviar una carga útil de JSON (es una API REST, y estoy enviando solicitudes a través de Swagger 2.9, Postman, efectivamente curl llamadas). ¿Cómo puedo combinar la carga de imagen binaria con una carga útil JSON, de tal manera que mi controlador puede capturarlo? Tal vez exactamente lo más importante, ¿hay una manera de hacer esto a través de Swagger o Postman, para que pueda hacer pruebas de extremo a extremo de mi API?

Pregunta hecha hace 3 años, 5 meses, 1 días - Por devguru123


3 Respuestas:

  • Por eso tienes múltiples solicitudes de parte, la idea es que envías múltiples partes independientes, cada una con su propio tipo de contenido.

    La bota de primavera soporta fuera de la caja tales casos. Aquí va un ejemplo:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestPart;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    @RestController
    @RequestMapping(path = "/multi")
    public class MultipartController {
    
        private static final Logger LOG = LoggerFactory.getLogger(MultipartController.class);
        
        @PostMapping
        public void upload(@RequestPart(name = "user") User user, 
                @RequestPart(name = "my-file") MultipartFile file) {
            LOG.info("User name: {}", user.getName());
            LOG.info("File size: {}", file.getSize());
        }
    }
    

    Para probar esto puede utilizar el cartero que también viene con soporte para este tipo de solicitudes

    enter image description here

    Respondida el Dec 17, 2020 a las 19:16 - por codesculptor

    Votos positivos: 0 | Votos negativos: 0

  • Para enviar una carga útil JSON junto con una imagen binaria a través de Swagger, Postman o curl, puedes realizar lo siguiente:

    • Modificar tu método de controlador para recibir el `MultiPartFile` y el `ProductUpsertRequestBody` de la siguiente manera:
    java
    @PostMapping(value = "/products")
    public ResponseEntity postProduct(@RequestPart("product") ProductUpsertRequestBody postRequest, @RequestPart("file") MultipartFile myImage) {
       // Código para manejar la carga útil JSON y la imagen binaria
    }
    
    • En tu cliente (Swagger, Postman, `curl`), debes cambiar la forma en que envías la solicitud POST para incluir tanto el JSON como la imagen binaria:
    • En Postman, puedes seleccionar el tipo de cuerpo `form-data` y agregar dos partes: una para el JSON y otra para la imagen. Asegúrate de nombrarlas como `"product"` para el JSON y `"file"` para la imagen.
    • En Swagger, puedes modificar la definición de la solicitud para incluir dos partes con los nombres `"product"` y `"file"`.
    • Con `curl`, puedes enviar una solicitud multipart usando el siguiente comando:
    bash
    curl -X POST -F "product=" -F "file=@path/to/image.jpg" http://url/products
    

    Al hacer esto, tanto el JSON como la imagen binaria se enviarán juntas en la solicitud POST y tu controlador podrá capturar ambas partes correctamente. Así puedes probar tu API de extremo a extremo para asegurarte de que todo está funcionando como se espera.

    Respondida el Dec 18, 2020 a las 19:11 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Combinando JSON y archivos multipart en solicitudes HTTP

    Para enviar datos JSON y archivos multipart en una sola solicitud HTTP, puedes utilizar la técnica multipart/form-data. Esto te permite enviar tanto datos de formulario (JSON) como archivos binarios en una sola solicitud.

    Ajustes en el método del controlador

    Tu método del controlador debe actualizarse para aceptar un objeto MultipartFile:

    java
    @PostMapping(value = "/products")
    public ResponseEntity postProduct(@RequestParam("product") ProductUpsertRequestBody postRequest, @RequestParam("image") MultipartFile image) {
        // ...
    }
    

    Creación de un formulario HTML para la carga

    Para crear un formulario HTML que permita la carga de JSON y archivos:

    html
    

    Uso de Swagger para las pruebas

    Swagger te permite enviar solicitudes multipart/form-data. En el editor de solicitudes, selecciona el parámetro "body" y establece el tipo de contenido en multipart/form-data. Luego, puedes agregar un nuevo parámetro de "formulario" para el JSON y un nuevo parámetro de "archivo" para la imagen.

    Uso de Postman para las pruebas

    Postman también admite solicitudes multipart/form-data. En el panel "Cuerpo", selecciona la pestaña "Formulario de datos" y agrega un campo para el JSON y un campo de archivo para la imagen.

    Ejemplo de solicitud

    Una solicitud de ejemplo utilizando multipart/form-data se vería así:

    
    POST /products HTTP/1.1
    
    Content-Type: multipart/form-data; boundary=--------------------------186498050235277
    
    
    • ----------------------------186498050235277
    Content-Disposition: form-data; name="product" { "product_name": "Nuevo producto" }
    • ----------------------------186498050235277
    Content-Disposition: form-data; name="image"; filename="imagen.jpg" [Contenido del archivo de imagen]
    • ----------------------------186498050235277--

    Al utilizar multipart/form-data, puedes enviar datos JSON y archivos binarios en una sola solicitud HTTP, lo que te permite ampliar tu método del controlador para manejar cargas tanto JSON como de imágenes.

    Respondida el Dec 18, 2020 a las 19:19 - por Gemini

    Votos positivos: 0 | Votos negativos: 0