Implementación de carga de archivos en formularios con Spring MVC

Para gestionar la subida de archivos en aplicaciones Spring MVC, se debe configurar el formulario HTML con el atributo enctype adecuado y emplear la interfaz MultipartFile en el controlador.

1. Configuración del formulario JSP

En el archivo JSP, el elemento <form> debe establecer enctype="multipart/form-data" para enviar los datos como partes múltiples. El campo de entrada de tipo file permite al usuario seleccionar el archivo, y su atributo name debe coincidir con el parámetro del controlador.

<form action="procesar" method="POST" enctype="multipart/form-data">
      Nombre: <input type="text" name="nombre" /><br/>
      Documento: <input type="file" accept="image/jpeg,image/png"
                name="documento">
      <input type="submit" value="Enviar" />
</form>

2. Interfaz MultipartFile de Spring

La interfaz MultipartFile proporciona métodos para manejar los datos del archivo cargado. Entre sus funciones principales se incluyen obtener el nombre original, el tipo de contenido, el tamaño y convertir el archivo a un flujo de bytes o entrada.

package org.springframework.web.multipart;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.core.io.InputStreamSource;

public interface MultipartFile extends InputStreamSource {
    String getName();
    String getNombreOriginal(); // Nombre original del archivo
    String getTipoContenido();  // Tipo MIME del archivo
    boolean estaVacio();        // Verifica si el archivo está vacío
    long getTamano();           // Tamaño en bytes
    byte[] getBytes() throws IOException; // Contenido como array de bytes
    @Override
    InputStream getInputStream() throws IOException; // Flujo de entrada
    void transferirA(File destino) throws IOException, IllegalStateException; // Guarda el archivo en el sistema
}

3. Métodos del controlador para manejar la carga

El controlador recibe el archivo mediante un parámetro de tipo MultipartFile. Existen tres enfoques comunes para almacenar el archivo: usando transferirA(), getBytes() o getInputStream().

import java.io.IOException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

@Controller
@RequestMapping("/aplicacion")
public class ControladorArchivo {

    @RequestMapping("/subir")
    public String subirArchivo(Usuario usuario, MultipartFile documento, Model modelo) throws IllegalStateException, IOException {
        // Lógica para procesar el objeto usuario (omitida)
        guardarConTransferencia(documento); // Método usando transferirA()
        guardarConBytes(documento);         // Método usando getBytes()
        guardarConFlujo(documento);         // Método usando getInputStream()
        return "resultado";
    }
}

3.1 Guardar usando el método transferirA()

Este método simplifica la escritura del archivo directamente a una ubicación en el sistema. Asegúrese de que el directorio exista y que el nombre del archivo no contenga caracteres especiales.

import java.io.File;
import java.io.IOException;
import org.springframework.web.multipart.MultipartFile;

public class ControladorArchivo {
    public void guardarConTransferencia(MultipartFile documento) throws IllegalStateException, IOException {
        String rutaDestino = "/almacen/archivos/";
        documento.transferirA(new File(rutaDestino + documento.getNombreOriginal()));
    }
}

3.2 Guardar usando el método getBytes()

Este enfoque implica crear manualmente el directorio y el archivo, luego escribir los bytes del archivo cargado en un flujo de salida.

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.springframework.web.multipart.MultipartFile;

public class ControladorArchivo {
    public void guardarConBytes(MultipartFile documento) throws IOException {
        String rutaBase = "/aplicacion/temp/";
        String carpetaCompleta = rutaBase + "archivos_usuario";
        File carpeta = new File(carpetaCompleta);
        if (!carpeta.exists()) {
            carpeta.mkdirs();
        }

        String rutaArchivo = carpetaCompleta + File.separator + documento.getNombreOriginal();
        File archivoDestino = new File(rutaArchivo);
        if (!archivoDestino.exists()) {
            archivoDestino.createNewFile();
        }

        BufferedOutputStream flujoSalida = new BufferedOutputStream(new FileOutputStream(archivoDestino));
        byte[] buffer = documento.getBytes();
        flujoSalida.write(buffer);
        flujoSalida.flush();
        flujoSalida.close();
    }
}

3.3 Guardar usando el método getInputStream()

Se obtiene un flujo de entrada del archivo y se transfiere byte a byte a un flujo de salida, permitiendo un control más dteallado sobre la escritura.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.web.multipart.MultipartFile;

public class ControladorArchivo {
    public void guardarConFlujo(MultipartFile documento) throws IOException {
        String rutaBase = "/aplicacion/datos/";
        String carpetaDestino = rutaBase + "respaldos";
        File directorio = new File(carpetaDestino);
        if (!directorio.exists()) {
            directorio.mkdirs();
        }

        String rutaFinal = carpetaDestino + File.separator + documento.getNombreOriginal();
        File archivo = new File(rutaFinal);
        if (!archivo.exists()) {
            archivo.createNewFile();
        }

        BufferedOutputStream salida = new BufferedOutputStream(new FileOutputStream(archivo));
        InputStream entrada = documento.getInputStream();
        BufferedInputStream entradaBuffer = new BufferedInputStream(entrada);

        int byteActual;
        while ((byteActual = entradaBuffer.read()) != -1) {
            salida.write(byteActual);
        }

        salida.flush();
        salida.close();
        entradaBuffer.close();
        entrada.close();
    }
}

Etiquetas: Spring MVC MultipartFile java jsp carga de archivos

Publicado el 6-28 19:14