Recientemente, mi colega me preguntó si tenía algún libro electrónico sobre tecnología. Abrí la pequeña biblioteca en mi computadora, pero el correo electrónico era demasiado grande para enviarlo, y la compañía prohibió compartir con carpetas, así que pasé medio día escribiendo un pequeño programa de carga de archivos e implementándolo en mi máquina Linux.
Proporcionar funciones: 1. Libra de archivo de archivo 2. Pantalla de lista de archivos y descarga
La pieza cargada original es fea. Escribí algún código JS para optimizarlo. La interfaz final se muestra de la siguiente manera:
Primero, primero dar los resultados, y a continuación demostrará cómo implementarlos paso a paso.
1. Crea un nuevo proyecto
Lo primero es crear un nuevo proyecto Spring-Boot. Puede elegir inicializar un proyecto en el sitio web o usar la función Spring Initialier del IDE, y puede crear un nuevo proyecto. Aquí creo un nuevo proyecto a partir de la idea:
A continuación, luego ingrese grupo y artefacto y continúe haciendo clic en Siguiente:
En este momento, aparece esta interfaz de selección de módulo. Haga clic en la opción web y verifique la web para demostrar que esta es una aplicación web. Luego haga clic en Motores de plantilla para seleccionar el motor de plantilla frontal. Elegimos Thymleaf. Spring-Boot Official también recomienda usar esta plantilla en lugar de JSP.
El último paso, luego espere a que el proyecto se inicialice con éxito.
2. Configuración de la OPM
Primero, verifique qué dependencias necesita agregar al proyecto y publicar directamente mi archivo POM:
<? xml versión = "1.0" encoding = "utf-8"?> <Project xmlns = "http://maven.apache.org/pom/4.0.0" xmlns: xsi = "http://www.w3.org/2001/xmlschemainstance" xsi: schemalocation = "http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion> 4.0.0 </modelversion> <MoupRoupid> com.shuqing28 </groupid> <arifactid> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>upload</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <Spendency> <MoupRoMID> org.springframework.boot </groupid> <artifactId> spring-boot-starter </artifactid> </pendency> <pendency> <proupid> org.springframework.boot </groupId> <AriFactId> spring-boot-stymeleaf </artifactid> <//dependency> <pendency> <MoupRoD> org.springframework.boot </groupid> <artifactid> spring-boot-configuation-procesador </arfactid> <pectional> true </pectional> </dependency> <ependency> <proupid> org.springwork.boot </groupid> <artifactid> tope-starr-test </artid </shockiD-test> </shope- <tockiDeMe10 </dependency> <!-- https://mvnrepository.com/artifact/org.webjars/bootstrap --> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.5</version> </dependency> <!-- https://mvnrepository.com/artifact/org.webjars.bower/jquery -> <pendency> <MoupRid> org.webjars.bower </proupid> <artifactid> jQuery </artifactid> <versión> 2.2.4 </spersion> </dependencia> </pendencies> <brugins> <glugins> <MoupRid> org.springframework.boot </groupid> <artifactID> spring-boot-saven-plugin </arfactid> </glugin> </glugins> </stract> </proyecto>
Puede ver que Spring-Boot-Starter-Thymeleaf contiene WebApp, y los dos últimos WebJars integran Bootstrap y JQuery, y se utilizarán otros códigos.
El último complemento Maven de arranque de primavera se agrega cuando se crea el sistema, y tiene los siguientes beneficios:
1. Puede empaquetar todos los frascos bajo classpath y construir un "über-jar" ejecutable para facilitar a los usuarios transferir los servicios.
2. Busque automáticamente el método Public static void main () y marque como una clase ejecutable
3. Según la versión Spring-Boot, se proporciona una explicación de dependencia incorporada.
3. Cargar el controlador de archivo
Si solo está utilizando SpringMVC para cargar archivos, debe configurar un frijol múltiple, o configurar un <preatt-Config> en web.xml, pero con la ayuda de la configuración automática de Spring-Boot, no tiene que hacer nada. Para escribir la clase de controlador directamente, creamos un nuevo paquete de controlador en SRC/Main/Java y creamos un nuevo FileUploadController:
paquete com.shuqing28.upload.controller; import com.shuqing28.uploadfiles.pojo.linker; import org.springframework.beans.factory.annotation.aUtowired; import org.springframework.core.io.resource; import org.springframework.http.httpheaders; import og.springFramework.htttp.ResponseNTity; import orge.springframework.steretipo. org. org.springframework.web.servlet.mvc.support.redirectattributes; import java.io.ioException; import java.util.list; import java.util.stream.collectores; @ControllerPublic FileUploadController {StorageService final privado StoragesService; @AUTOWIRED Public FileUploadController (StorageService StorageService) {this.storageService = storageService; } @GetMapping("/") public String listUploadedFiles(Model model)throws IOException { List<Linker> linkers = storageService.loadAll().map( path -> new Linker(MvcUriComponentsBuilder.fromMethodName(FileUploadController.class, "serveFile", Path.getFileName (). ToString ()). Build (). ToString (), Path.getFileName (). ToString ())) .Collect (coleccionadores.tolist ()); model.addattribute ("Linkers", Linkers); return "cargar forma"; } @Getmapping ("/files/{nombre de archivo :.+}") @ResponseBody Public ResponseEntity <conseurce> ServFile (@PathVariable String FileName) {recource archivo = storageservice.loadAsResource (fileName); return responseEntity.ok (). Header (httpheaders.content_disposition, "adjunto; filename =/" " + file.getFileName () +" /"").body(file); } @PostMapping ("/") Cadena pública HandleFileUpload (@RequestParam ("File") File multipartfile, redirectAttributes redirectatTributes) {storageservice.store (archivo); redirectattributes.AddFlashAttribute ("Mensaje", "Usted cargó con éxito" + file.getOriginalFileName () + "!"); return "redirect:/"; } @ExceptionHandler (StorageFileNotFoundException.Class) Public ResponseEntity <?> HandLeStorageFilenotFound (StorageFilenotFoundException exc) {return ResponseEntity.NotFound (). Build (); }}La anotación @Controller se agrega en la definición de clase, lo que demuestra que este es un controlador. Cada método se agrega con @getMapping y @PostMapping correspondiente a las solicitudes de GET y POST respectivamente.
En primer lugar, @getmapping ("/"), método listupleadedfiles, como lo indica el nombre, muestra la lista de archivos. Aquí usamos StorageService para atravesar todos los archivos en la carpeta y usamos el método de mapa para sintetizar la lista de nombres de enlace y archivo, devolviendo una matriz de objetos de enlace. El objeto enlazador es un POJO simple, que solo contiene las siguientes dos partes:
String private FileUrl; Nombre de archivo privado de cadena;
Este método incluye el uso de la transmisión en Java8. Si no comprende, puede leer este artículo sobre las funciones de Java8 en detalle (ii) API de transmisión.
Siguiente es @GetMapping("/files/{filename:.+}") , que es ServFile, que proporciona función de descarga de archivos, o usa StorageService, y el código StorageService se publicará más adelante. Finalmente, use ResponseEntity para devolver el archivo como un cuerpo a la parte solicitante.
El HlegileLUPLOAD de @PostMapping("/") utiliza la solicitud de publicación para cargar archivos. El parámetro @requestparam ("archivo") extrae el objeto de archivo en la solicitud de la página web, o usa StorageService para guardar el objeto, y finalmente usa redireccionamiento para actualizar la página web y proporciona el mensaje cargado con éxito.
4. Procesamiento de archivos
StoragesService proporcionan muchos métodos llamados por el controlador anterior. Definimos una interfaz que contiene los siguientes métodos:
paquete com.shuqing28.uploadfiles.service; import org.springframework.core.io.resource; import og.springframework.web.multipart.multipartFile; import java.nio.file.path; import java.util.stream.stream; public interface storageStourervice {void ();); tienda void (archivo multipartfile); Stream <Path> LoadAll (); Carga de ruta (nombre de archivo de cadena); Recursos LoadAsResource (nombre de archivo de cadena); void deleteall ();}Debido a que solo estoy usando el sistema de archivos local para procesar descargas de archivos a largo plazo, tengo la siguiente clase de implementación:
paquete com.shuqing28.uploadfiles.service; import com.shuqing28.uploadfiles.exceptions.storageException; import org.springframework.beans.factory.annotation.aUtowired; import org.springframework.core.io.resource; import org.springframework.core.io.urlresource; import og.springFrameWork.stereotpe.service; import org.springFramework.util.filesysemutystemsysysteStemiLs. org.springframework.util.stringutils; import org.springframework.web.multipart.multipartFile; import java.io.ioexception; import java.net.malFormedureLException; import java.nio.file.files; import java.nio.file.path; import java.nio.paths; java.nio.file.paths; import java.nio.file.standardCopyOption; import java.util.stream.stream; @ServicePublic Public Los sistemas de sistemas de sistemas de servicios de servicio de almacenamiento de la ruta final privada; @AUTOWIRED Public Files SystemStoraGeService (StorageProperties Properties) {this.rootlocation = paths.get (propiedades.getLocation ()); } @Override public void init () {try {files.createDirectorios (rootLocation); } Catch (ioException e) {Throw New StorageException ("no se pudo inicializar el almacenamiento", e); }} @Override public void store (archivo multipartfile) {string filename = stringUtils.cleanPath (file.getOriginalFileName ()); intente {if (file.isEmpty ()) {tire nueva almacenamientoException ("no se pudo almacenar el archivo vacío" + nombre de archivo); } if (FileName.Contains ("..")) {// Esta es una verificación de seguridad, arroje nuevo almacenamiento, "no puede almacenar el archivo con ruta relativa fuera del directorio actual" + nombre de archivo); } Files.Copy (file.getInputStream (), this.rootlocation.resolve (nombre de archivo), StandardCopyOption.replace_Existing); } catch (ioException e) {tire nueva almacenamientoException ("no pudo almacenar archivo" + nombre de archivo, e); }} @Override public stream <Path> loadAll () {try {return files.walk (this.rootlocation, 1) .filter (path ->! } Catch (ioException e) {Throw New StorageException ("Error al leer archivos almacenados", e); }} @Override public Path Load (String FileName) {return rootLocation.resolve (nombre de archivo); } @Override Public Resource LoadAsResource (String FileName) {try {Path File = Load (FileName); Recursos recursos = new UrlResource (file.touri ()); if (resource.exists () || resource.iseadable ()) {return Resource; } else {lanzar nueva almacenamientofilenotfoundException ("no se pudo leer el archivo:" + nombre de archivo); }} Catch (MalFormedUrLeCeption e) {lanzar nueva almacenamientofilenotfoundException ("no se pudo leer el archivo:" + nombre de archivo, e); }} @Override public void DeleteAll () {filesSystemUtils.deleterCursive (rootLocation.tofile ()); }}Esta clase también utiliza básicamente el NIO de Java y usa el objeto de ruta para definir la ruta de guardado predeterminada para la ubicación para el archivo.
Veamos primero el método de la tienda. La tienda acepta un objeto multiparto como parámetro. En comparación con el JSP tradicional, es solo pasar matrices de bytes binarios. MultipartFile proporciona muchos métodos convenientes para llamar, para que podamos obtener varias información sobre el archivo cargado:
Public Interface MultipartFile extiende InputStreamSource {String getName (); Cadena getOriginalFileName (); Cadena getContentType (); boolean isEmpty (); Long getSize (); byte [] getbytes () lanza ioexception; InputStream getInputStream () lanza IOException; Void TransferTo (File Dest) lanza ioexception, ilegalstateException;} El código utiliza el método de copia de archivos para copiar la transmisión del archivo a la ruta correspondiente a la ubicación. Por supuesto, también podemos usar el método TransferTo para guardar el archivo, file.transferTo(this.rootLocation.resolve(filename).toFile());
El método LoadAll carga toda la información de la ruta del archivo en esta ruta, LoadAsResource carga el archivo como un objeto de recursos, luego mire el código del controlador y finalmente acepta un objeto de recurso como un cuerpo para volver al solicitante.
5. Plantilla frontal
Finalmente, se define la plantilla front-end, y aquí todavía veremos el código primero:
<html xmlns: th = "http://www.thymeleaf.org"> <fead> <title> compartir archivos </title> </head> <body> <div th: if = "$ {mensaje}"> <h2 th: text = "$ {message}"/> </div> <div> <form method = "Post" Action = "/" Inctype < type = "enviar"> enviar </boton> <button type = "reset"> reet </boton> </div> </borm> </div> <div> <ul> <li th: every = "linker: $ {linkers}"> <a th: href = "$ {linker.fileUrl}" rel = "noFllow" th: text = "$ {{{{{{{{{filer.fileame}" </li> </ul> </div> <script src = "// ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.1.min.js"></script><script src ="/webjars/bootstrap/3.3.5/js/bootstrap.min.js "> </script> <script type =" text/jaxting " th: inline = "javaScript"> function bs_input_file () {$ (". input-file"). antes (function () {if (! $ (this) .prev (). Hasclass ('input-ghost')) {var elemento = $ (". input-ghost"); elemento (function () { element.next (elemento) .find ('input'). Val ((element.val ()). Split ('//'). Pop ()); $ (this) .Parents (". Input-File"). Find ('Input'). Val (''); elemento; } } ); } $ (function () {bs_input_file ();}); </script> <link rel = "stylesheet" href = "/webjars/bootstrap/3.3.5/css/bootstrap.min.css" rel = "nofollow externo"/> </body> </html>Lo importante aquí es el contenido en la etiqueta <Form>. <Form Method = "Post" Action = "/" Enctype = "Multipart/Form-Data"> Enctype debe escribirse como multipart/formy-data. Use la publicación para cargar archivos. El control de carga original es feo, por lo que hice un texto+entrada y lo coloqué en la superficie, y coloqué una entrada de archivo de carga invisible a continuación. Puedes mirar el código por ti mismo, así que no hablaré de ello en este artículo.
Aquí también colocamos una lista para mostrar la lista de archivos. Aquí obtenemos el objeto enlazadores proporcionado por el servidor. Por constantemente foreach, podemos obtener los dos elementos en FileUrl y el nombre de archivo.
Aquí, JQuery ha sido reemplazada por CDN de Microsoft, y no se puede presentar WebJARS, así que no sé por qué.
Otras configuraciones
Establezca el límite de tamaño del archivo de carga en SRC/Main/Resources/Application.Properties
spring.http.multipart.max-file-size = 128mbspring.http.multipart.max-request-size = 128mb
Además, la ruta de ahorro de archivo predeterminada también está establecida:
paquete com.shuqing28.uploadfiles.config; import org.springframework.boot.context.properties.configurationProperties; @configurationProperties ("almacenamiento") publicidad de clase pública Aproperties {ubicación de cadena privada = "/home/jenkins/carga-film/"; "; public String getLocation () {ubicación de retorno; } public void setLocation (ubicación de cadena) {this.location = ubicación; }}Tenga en cuenta que, debido a la configuración de StorageProperties, debe agregarla a la clase de aplicación.
@EnableconfigurationProperties anotation@springbootapplication@habiledeconfigurationProperties (storageProperties.class) public class uploadApplication {public static void main (string [] args) {springapplication.run (uploadapplication.class, args); }}Resumir
Lo anterior es el Spring Boot + Thymeleaf que el Editor le presentó para realizar la función de carga y descarga de archivos. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!