Recentemente, meu colega me perguntou se eu tinha algum e-books sobre tecnologia. Abri a pequena biblioteca no meu computador, mas o email era grande demais para enviá -lo, e a empresa proibia o compartilhamento com as pastas, então passei meio dia escrevendo um pequeno programa de upload de arquivos e implantando -o na minha máquina Linux.
Forneça funções: 1. Faça o upload de arquivo 2. Exibição da lista de arquivos e download
A peça de upload original é feia. Eu escrevi um código JS para otimizá -lo. A interface final é mostrada da seguinte maneira:
Primeiro, forneça os resultados e abaixo demonstrará como implementá -los passo a passo.
1. Crie um novo projeto
A primeira coisa é criar um novo projeto de inicialização da primavera. Você pode optar por inicializar um projeto no site ou usar a função inicial do Spring do IDE e pode criar um novo projeto. Aqui eu crio um novo projeto da Idea:
Em seguida, entre em grupo e artefato e continue a clicar em Avançar:
Neste momento, essa interface de seleção de módulos é exibida. Clique na opção da Web e verifique a Web para provar que este é um aplicativo da Web. Em seguida, clique em Modelos Motores para selecionar o mecanismo de modelo front-end. Escolhemos o Thymleaf. O funcionário da Spring-Boot também recomenda o uso deste modelo em vez de JSP.
A última etapa e aguarde a inicialização do projeto com sucesso.
2. Configurações do POM
Primeiro, verifique quais dependências você precisa adicionar ao projeto e postar diretamente meu arquivo POM:
<? xml versão = "1.0" coding = "utf-8"?> <Projeto xmlns = "http://maven.apache.org/pom/4.0.0" xmlns: xsi = "http://www.ww3.org/2001/xmlschaMance 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> <groupId>com.shuqing28</groupId> <artifactId>upload</artifactId> <Versão> 0.0.1-SNAPSHOT </Version> <batyaging> jary </acheging> <name> upload </name> <cription> Projeto de demonstração para bota de primavera </cription> <aroger> <puerpid> org.springframework.boot </groupid> <stifactId> spring-boot-strarter-parent </artefactId> Pai do Repository-> </axer> <Properts> <Project.build.sourceEncoding> utf-8 </project.build.sourceEncoding> <projeto.Reporting.outputEncoding> Utf-8 </project.reporting.outputEncoding> <nava.version> 1.8 </project.reporting.outputing> <nava.version> 1.Jansersion <javaSersion> <PuerpId> org.springframework.boot </frugiD> <ArtifactId> Spring-boot-Starter </ArtifactId> </Dependency> <pendence> <puerpid> org.springframework.boot </groupid> <roupidId> org.springframework.boot </frupiD> <stifactId> spring-boot-configuration-processor </artifactId> <cptional> true </cptional> </ipendency> <spendency> <voundid> org.springframework.BOOT </Groupid> <strofactid> Spring-Bring-Brot-Brot-Brot-spring-Tringwork.BOOT) <scope>test</scope> </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 --> <dependency> <groupId>org.webjars.bower</groupId> <artifactId>jquery</artifactId> <version>2.2.4</version> </dependency> </dependencies> <build> <plugins> <PuerpId> org.springframework.boot </frugiD> <TRATIFACTID> Spring-boot-maven-plugin </stutifactId> </flugin> </plugins> </fruct> </project>
Você pode ver que o Spring-Boot-Starter-Thymeleaf contém o WebApp, e os dois últimos webjars integram bootstrap e jQuery, e outros códigos serão usados.
O plug -in Maven da última primavera é adicionado quando o sistema é criado e tem os seguintes benefícios:
1. Ele pode empacotar todos os frascos em ClassPath e criar um "über-jar" executável para facilitar os usuários a transferir serviços.
2. Pesquise automaticamente o método público estático void main () e marque -o como uma classe executável
3. De acordo com a versão da Spring-Boot, é fornecida uma explicação de dependência interna.
3. Carregar o controlador de arquivos
Se você estiver apenas usando o SpringMVC para fazer upload de arquivos, precisará configurar um feijão multipartresolver ou configurar um <fig> em web.xml, mas com a ajuda da configuração automática do Spring-Boot, não precisará fazer nada. Para escrever diretamente a classe do controlador, criamos um novo pacote de controladores no SRC/Main/Java e criamos um novo FileUploadController:
pacote com.shuqing28.upload.controller; importar com.shuqing28.uploadfiles.pojo.linker; importar com.shuqing28.uploadfiles.exceptions.storageFilenotFoundException; import.shusting28.uPloadfiless. org.springframework.beans.factory.annotation.aUtowired; importar org.springframework.core.io.resource; importar org.springframework.http.httpheaders; importação; org.springframework.ui.model; importar org.springframework.web.bind.annotation.*; importar org.springframework.web.multipart.multipartfile; org.springframework.web.servlet.mvc.support.redirectattributes; importar java.io.ioexception; importar java.util.list; importar java.util.stream.collectors; @Controllerpublic ClassROROUPLOADCONTROLLER {STERGORTORS STORGORES; @AUTowired public fileUploadController (StorageService StorageService) {this.storageservice = storageService; } @GetMapping ("/") public string listuploadedfiles (modelo) lança ioexception {list <linker> linkers = storageService.loadall (). Map (path -> new linker (mvcuricomentsbuilder.frommethodName (fileUploadControlller.cllass, "servir", " path.getfilename (). tostring ()). build (). tostring (), path.getFilename (). tostring ()) .collect (collectors.tolist ()); Model.Addattribute ("Linkers", Linkers); return "uploadform"; } @GetMapping ("/files/{filename:.+}") @ResponseBody Public ResponseEntity <Source> servfile (@PathVariable string filename) {arquivo de recursos = storageService.loadAsResource (nome do arquivo); RETORNO DE REPORTIÇÃOENTITY.OK (). Cabeçalho (httpheaders.content_dispition, "Anexamento; nome do arquivo =/" " + file.getFileName () +" /"").Bodybody(File); } @PostMapping ("/") public String handleFileUpload (@RequestParam ("FILE") arquivo multipart de arquivo, redirectattributes redirectattributes) {storageService.store (arquivo); redirectattributes.addflashattribute ("mensagem", "você carregou com sucesso" + file.getoriginalfileName () + "!"); retornar "redirecionar:/"; } @ExceptionHandler (StorageFilENotFoundException.Class) Resposta pública <?> HandleStorageFilENotFound (StorageFileNotFoundException exc) {Return ResponseEntity.NotFound (). Build (); }}A anotação @Controller é adicionada na definição da classe, provando que este é um controlador. Cada método é adicionado ao @GetMapping e @PostMapp, correspondentes às solicitações GET e POST, respectivamente.
Primeiro de tudo, @GetMapping ("/"), Método listuploadedfiles, como o nome implica, exibe a lista de arquivos. Aqui, usamos o StorageService para atravessar todos os arquivos na pasta e usar o método do mapa para sintetizar o link e a lista de nomes do arquivo, retornando uma matriz de objetos de ligação. O objeto vinculador é um pojo simples, que contém apenas as duas partes a seguir:
private string fileurl; nome do arquivo de sequência privada;
Este método inclui o uso do fluxo em Java8. Se você não entende, pode ler este artigo sobre os recursos Java8 em detalhes (ii) API de fluxo.
O próximo é @GetMapping("/files/{filename:.+}") , Que é o SirtFile, que fornece função de download de arquivos ou usa o StorageService, e o código do StorageService será publicado posteriormente. Por fim, use a resposta de retorno o arquivo como um órgão à parte solicitadora.
O handleFileUpload de @PostMapping("/") usa a solicitação de postagem para fazer upload de arquivos. O parâmetro @RequestParam ("FILE") extrai o objeto de arquivo na solicitação da página da web ou usa o StorageService para salvar o objeto e, finalmente, usa o redirecionamento para atualizar a página da web e fornece a mensagem carregada com sucesso.
4. Processamento de arquivos
Muitos métodos chamados pelo controlador acima são fornecidos pelo StorageService. Definimos uma interface que contém os seguintes métodos:
pacote com.shuqing28.uploadfiles.service; importar org.springframework.core.io.resource; importar org.springframework.web.multipart.multipartFile; import java.nio.file.path; Void Store (arquivo multipart -arquivo); Stream <TACH> loadAll (); Carga de caminho (nome do arquivo de string); Recurso loadAsResource (nome do arquivo de string); void DeLeTeall ();}
Como estou apenas usando o sistema de arquivos local para processar downloads de longo prazo de arquivos, tenho a seguinte classe de implementação:
pacote com.shuqing28.uploadfiles.service; import com.shuqing28.uploadfiles.exceptions.storageException; importação com.shuqing28.uploadfiles.Exceptions.StorageFilenotFoundException; importação.shuqing28.uPloadfiles org.springframework.beans.factory.annotation.autowired; importar org.springframework.core.io.resource; importar org.springframework.core.io.urlResource; importação org.springframework.tereotypey; org.springframework.util.StringUtils;import org.springframework.web.multipart.MultipartFile;import java.io.IOException;import java.net.MalformedURLException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.nio.file.paths; importar java.nio.file.standardcopyOption; importar java.util.stream.stream; @ServicePublic Classystemstorageservice implementa armazenamentos {private Final Path RootLocation; @AUTowired Public FileSystemStoraGeRervice (StorageProperties Properties) {this.rootLocation = paths.get (Properties.getLocation ()); } @Override public void init () {try {files.createDirectories (rootlocation); } catch (ioexception e) {lança a nova armazenamento ("não foi possível inicializar o armazenamento", e); }} @Override public void store (arquivo multipart -arquivo) {string filename = stringUtils.cleanPath (file.getoriginalfileName ()); tente {if (file.isEmpty ()) {lança a nova armazenamento ("Falha ao armazenar o arquivo vazio" + nome do arquivo); } if (filename.contains ("..")) {// Este é um cheque de segurança lançar uma nova armazenamento ("Não é possível armazenar arquivo com caminho relativo fora do diretório atual" + nome do arquivo); } Files.copy (file.getInputStream (), this.rootLocation.resolve (nome do arquivo), StandardCopyOption.replace_existing); } catch (ioexception e) {lança nova storageException ("Falha ao armazenar o arquivo" + nome do arquivo, e); }} @Override Public Stream <Path> loadAll () {try {return files.walk (this.rootLocation, 1) .Filter (path ->! Path.equals (thisrootLocation)) .map (path-> this.rootLocation.Relative (path)); } catch (ioexception e) {lança nova storageException ("Falha ao ler arquivos armazenados", e); }} @Override Public Path Load (String filename) {return rootLocation.Resolve (nome do arquivo); } @Override Public Resource loadAsResource (string filename) {try {path file = load (nome do arquivo); Recurso de recurso = novo urlResource (file.touri ()); if (Resource.Exists () || Resource.isReadable ()) {return Resource; } else {lança new storageFilENotFoundException ("não conseguiu ler o arquivo:" + nome do arquivo); }} catch (malformEdUrlexception e) {lança o novo armazenamentoFilENOTFoundException ("não conseguiu ler o arquivo:" + nome do arquivo, e); }} @Override public void DeLeTeall () {filesystemutils.deleteCursive (rootLocation.tofile ()); }}Essa classe também usa basicamente o NIO de Java e usa o objeto Path para definir o caminho de economia padrão para o local para o arquivo.
Vejamos o método da loja primeiro. A loja aceita um objeto multipart -arquivo como um parâmetro. Comparado ao JSP tradicional, está apenas passando matrizes de bytes binários. O MultipartFile fornece muitos métodos convenientes a serem chamados, para que possamos obter várias informações sobre o arquivo carregado:
interface pública MultipartFile estende o InputStreamSource {string getName (); String getoriginalFilename (); String getContentType (); booleano isEmpty (); long getsize (); byte [] getBytes () lança IoException; InputStream getInputStream () lança IoException; Void Transferto (File Dest) lança IoException, ilegalStateException;} O código usa o método de cópia de arquivos para copiar o fluxo de arquivos para o caminho correspondente ao local. Obviamente, também podemos usar o método transferto para salvar o arquivo, file.transferTo(this.rootLocation.resolve(filename).toFile());
O método loadAll carrega todas as informações do caminho do arquivo nesse caminho, o loadAsResource carrega o arquivo como um objeto de recurso e, em seguida, observe o código do controlador e, finalmente, aceita um objeto de recurso como um órgão para retornar ao solicitante.
5. Modelo de front-end
Finalmente, o modelo front-end é definido e aqui ainda vamos olhar para o código primeiro:
<html xmlns: th = "http://www.thymeleaf.org"> <head> <title> Compartilhe arquivos </title> </ad Head> <body> <div ENCTYPE = "Multipart/Form-Data"> <!-Componente START-> <input type = "file" name = "file" style = "visibilidade: hidden; altura: 0"/> <div> <div name = "Fichier1"> <butter type = "Text" Placeholder = 'Escolha um arquivo ...'/> <Plut> <butter = "Button"> " End -> <div> <botão type = "submit"> submeter </butut> <button type = "reset"> reset </butut> </div> </morm> </div> <div> <ul> <li th: cada = "linker: $ {linkers}"> <a: href = "$ {linker.fileurl} th: text = "$ {linker.filename}"/> </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/javascript" th: inline = "javascript"> function bs_input_file () {$ (". input-fil-bile"). $ (this) .prev (). hasclass ('input-ghost')) {var element = $ (". input-ghost"); $ (this) .Find ("Button.btn-choose"). Clique em (function () {Element.Click ();}); $ (this) .Find ('entrada'). CSS ("cursor", "ponteiro"); } $ (function () {bs_input_file ();}); </script> <link rel = "Stylesheet" href = "/webjars/bootstrap/3.3.5/css/bootstrap.min.css" rel = "Nofollow externo"/> </body> </html>O importante aqui é o conteúdo na tag <morm>. <form method = "post" action = "/" Enctype = "Multipart/form-Data"> Enctype deve ser escrito como multipart/formulário. Use postagem para fazer upload de arquivos. O controle de upload original é feio, então eu fiz uma entrada de texto+e a coloquei na superfície e coloquei uma entrada de arquivo de upload invisível abaixo. Você pode olhar para o código sozinho, para que eu não fale sobre isso neste artigo.
Aqui também colocamos uma lista para exibir a lista de arquivos. Aqui recebemos o objeto Linkers fornecido pelo servidor. Por seenciar constantemente, podemos obter os dois elementos no Fileurl e FileName.
Aqui, o JQuery foi substituído pelo CDN da Microsoft, e os webjars não podem ser introduzidos, então não sei por quê.
Outras configurações
Defina o limite de tamanho de arquivo de upload em SRC/Main/Recursos/Application.properties
spring.http.multipart.max-fil-size = 128mbspring.http.multipart.max-request-size = 128MB
Além disso, o caminho de economia de arquivos padrão também está definido:
pacote com.shuqing28.uploadfiles.config; importar org.springframework.boot.context.properties.configurationproperties; @configurationproperties ("armazenamento") public class StorageProperties {private string local = "/home/jenkins/upsload-files"; public String getLocation () {Return Location; } public void SetLocation (String Location) {this.Location = Location; }}Observe aqui que, devido à configuração do StorageProperties, você precisa adicioná -la à classe de aplicativo.
@EnableConfigurationProperties anotation@springbootApplication@EnableConfigurationProperties (storageproperties.class) classe public uPLOPPLACIONACIONAL {public static void main (string [] args) {springApplication.run (uploadApplication.class, args); }}Resumir
O acima é o Spring Boot + Thymeleaf que o editor apresentou a você para realizar a função de upload e download do arquivo. Espero que seja útil para você. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a você a tempo. Muito obrigado pelo seu apoio ao site wulin.com!