2010-08-26 23 views
20

He estado integrando spring en una aplicación, y tengo que volver a cargar un archivo desde formularios. Soy consciente de lo que Spring MVC tiene para ofrecer y de lo que debo hacer para configurar mis controladores para que puedan cargar archivos. He leído suficientes tutoriales para poder hacer esto, pero lo que ninguno de estos tutoriales explica son los métodos correctos/de mejores prácticas sobre cómo/qué se debe hacer para manejar realmente el archivo una vez que lo tiene. A continuación se muestra un código similar al código que se encuentra en el Spring MVC Docs en el manejo de la carga de archivos que se pueden encontrar en
Spring MVC File UploadSpring MVC File Upload Help

En el siguiente ejemplo se puede ver que te muestran todo lo que hacer para obtener el archivo, pero a decir hacer algo con el grano de

he comprobado muchas clases particulares y todos ellos me parecen llegar a este punto, pero lo que realmente quiero saber es la mejor manera de manejar el archivo. Una vez que tengo un archivo en este punto, ¿cuál es la mejor manera de guardar este archivo en un directorio en un servidor? ¿Puede alguien ayudarme con esto? Gracias

public class FileUploadController extends SimpleFormController { 

protected ModelAndView onSubmit(
    HttpServletRequest request, 
    HttpServletResponse response, 
    Object command, 
    BindException errors) throws ServletException, IOException { 

    // cast the bean 
    FileUploadBean bean = (FileUploadBean) command; 

    let's see if there's content there 
    byte[] file = bean.getFile(); 
    if (file == null) { 
     // hmm, that's strange, the user did not upload anything 
    } 

    //do something with the bean 
    return super.onSubmit(request, response, command, errors); 
} 
+1

Simplemente abra un outputstream y escriba los bytes en la secuencia. FileOutputStram fos = new FileOutputStream ("ubicación/en/servidor/nombre de archivo"); fos.write (archivo); fos.close(); – mhshams

+0

Te das cuenta de que estás siguiendo los documentos para Spring 2.0, ¿verdad? Las cosas han avanzado mucho en el mundo de la primavera desde entonces. Recomiendo encarecidamente utilizar 3.0, en cambio, encontrará muchas cosas mucho más sencillas, incluida la carga de archivos. – skaffman

+0

He leído la documentación de Spring 3.0 y el uso de formularios de varias partes y la documentación para el manejo de varias partes es casi idéntica a la documentación 2.0. – TheJediCowboy

Respuesta

20

Esto es lo que prefiero al tiempo que los archivos subidos. Creo que dejar que Spring controle el guardado de archivos es la mejor manera. Spring lo hace con su función MultipartFile.transferTo(File dest).

import java.io.File; 
import java.io.IOException; 

import javax.servlet.http.HttpServletResponse; 

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.ResponseBody; 
import org.springframework.web.multipart.MultipartFile; 

@Controller 
@RequestMapping("/upload") 
public class UploadController { 

    @ResponseBody 
    @RequestMapping(value = "/save") 
    public String handleUpload(
      @RequestParam(value = "file", required = false) MultipartFile multipartFile, 
      HttpServletResponse httpServletResponse) { 

     String orgName = multipartFile.getOriginalFilename(); 

     String filePath = "/my_uploads/" + orgName; 
     File dest = new File(filePath); 
     try { 
      multipartFile.transferTo(dest); 
     } catch (IllegalStateException e) { 
      e.printStackTrace(); 
      return "File uploaded failed:" + orgName; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return "File uploaded failed:" + orgName; 
     } 
     return "File uploaded:" + orgName; 
    } 
} 
+0

Para obtener la ruta base use request.getServletContext(). GetRealPath ("/") – Roberto

+1

@Roberto 'getRealPath ("/")' devuelve el directorio de contenido web. No es buena idea guardar archivos allí. Cuando la aplicación se redistribuya, los archivos guardados/cargados se perderán. –

+0

multipartFile.transferTo (dest); me da IOException. Me aseguré de haber creado los directorios necesarios. ¿Tienes alguna idea sobre cuál podría ser la razón? –

2

pero lo que ninguno de estos tutoriales explicar es mejores métodos correctos/práctica sobre cómo/lo que hay que hacer para manejar efectivamente el archivo una vez que lo tienes

La mejor práctica depende de lo que intenta hacer. Usualmente uso algún AOP para postprocesar el archivo cargado. A continuación, puede utilizar FileCopyUtils almacenar el archivo subido

@Autowired 
@Qualifier("commandRepository") 
private AbstractRepository<Command, Integer> commandRepository; 

protected ModelAndView onSubmit(...) throws ServletException, IOException { 
    commandRepository.add(command); 
} 

AOP se describe como sigue

@Aspect 
public class UploadedFileAspect { 

    @After("execution(* br.com.ar.CommandRepository*.add(..))") 
    public void storeUploadedFile(JoinPoint joinPoint) { 
     Command command = (Command) joinPoint.getArgs()[0]; 

     byte[] fileAsByte = command.getFile(); 
     if (fileAsByte != null) { 
      try { 
       FileCopyUtils.copy(fileAsByte, new File("<SET_UP_TARGET_FILE_RIGHT_HERE>")); 
      } catch (IOException e) { 
       /** 
        * log errors 
        */ 
      } 
     } 

    } 

No se olvide de activar aspecto (actualización del esquema a la primavera 3,0 si es necesario) Poner en la ruta de clase aspectjrt.jar y aspectjweaver.jar (<SPRING_HOME>/lib/aspectj) y

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:aop="http://www.springframework.org/schema/aop" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
          http://www.springframework.org/schema/aop 
          http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> 
    <aop:aspectj-autoproxy /> 
    <bean class="br.com.ar.aop.UploadedFileAspect"/> 
-1

Utilice la clase de controlador siguiente para procesar la carga del archivo.

@Controller 
public class FileUploadController { 

    @Autowired 
    private FileUploadService uploadService; 

    @RequestMapping(value = "/fileUploader", method = RequestMethod.GET) 
    public String home() { 
    return "fileUploader"; 
    } 

    @RequestMapping(value = "/upload", method = RequestMethod.POST) 
    public @ResponseBody List<UploadedFile> upload(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException { 

    // Getting uploaded files from the request object 
    Map<String, MultipartFile> fileMap = request.getFileMap(); 

    // Maintain a list to send back the files info. to the client side 
    List<UploadedFile> uploadedFiles = new ArrayList<UploadedFile>(); 

    // Iterate through the map 
    for (MultipartFile multipartFile : fileMap.values()) { 

     // Save the file to local disk 
     saveFileToLocalDisk(multipartFile); 

     UploadedFile fileInfo = getUploadedFileInfo(multipartFile); 

     // Save the file info to database 
     fileInfo = saveFileToDatabase(fileInfo); 

     // adding the file info to the list 
     uploadedFiles.add(fileInfo); 
    } 

    return uploadedFiles; 
    } 

    @RequestMapping(value = {"/listFiles"}) 
    public String listBooks(Map<String, Object> map) { 

    map.put("fileList", uploadService.listFiles()); 

    return "listFiles"; 
    } 

    @RequestMapping(value = "/getdata/{fileId}", method = RequestMethod.GET) 
    public void getFile(HttpServletResponse response, @PathVariable Long fileId) { 

    UploadedFile dataFile = uploadService.getFile(fileId); 

    File file = new File(dataFile.getLocation(), dataFile.getName()); 

    try { 
     response.setContentType(dataFile.getType()); 
     response.setHeader("Content-disposition", "attachment; filename=\"" + dataFile.getName() + "\""); 

     FileCopyUtils.copy(FileUtils.readFileToByteArray(file), response.getOutputStream()); 


    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 


    private void saveFileToLocalDisk(MultipartFile multipartFile) throws IOException, FileNotFoundException { 

    String outputFileName = getOutputFilename(multipartFile); 

    FileCopyUtils.copy(multipartFile.getBytes(), new FileOutputStream(outputFileName)); 
    } 

    private UploadedFile saveFileToDatabase(UploadedFile uploadedFile) { 
    return uploadService.saveFile(uploadedFile); 
    } 

    private String getOutputFilename(MultipartFile multipartFile) { 
    return getDestinationLocation() + multipartFile.getOriginalFilename(); 
    } 

    private UploadedFile getUploadedFileInfo(MultipartFile multipartFile) throws IOException { 

    UploadedFile fileInfo = new UploadedFile(); 
    fileInfo.setName(multipartFile.getOriginalFilename()); 
    fileInfo.setSize(multipartFile.getSize()); 
    fileInfo.setType(multipartFile.getContentType()); 
    fileInfo.setLocation(getDestinationLocation()); 

    return fileInfo; 
    } 

    private String getDestinationLocation() { 
    return "Drive:/uploaded-files/"; 
    } 
} 
+0

El archivo cargado no está definido. – MuffinMan