No desenvolvimento do sistema de aplicativos da Web, as funções de upload e download de arquivos são funções muito usadas. Hoje, vamos falar sobre a implementação das funções de upload e download de arquivos no Javaweb.
Visão geral do upload do arquivo
1. A função do upload do arquivo
Por exemplo, o disco rígido da rede! É usado para fazer upload e baixar arquivos.
Para preencher um currículo completo sobre o recrutamento da Zhilian, você também precisa fazer upload de fotos.
2. Requisitos para o upload da página
Existem muitos requisitos para fazer upload de arquivos, lembre -se:
O formulário deve ser usado, não um método de forma de hiperlink deve ser postado, não um obtém
O encantamento do formulário deve ser multipart/formulário
Adicione o campo do formulário de arquivo no formulário, ou seja, <input type = "file" name = "xxx"/>
<Form Action = "$ {PageContext.Request.ContextPath}/FileUploadServlet" Method = "Post" ENCTYPE = "Multipart/Form-Data"> Nome de usuário: <input Type = "Text" Name = "UserName"/> <br/> Arquivo 1: <input Type = "FILE" ") name = "file2"/> <br/> <input type = "submit" value = "submit"/> </morm>3. Compare a diferença entre o formulário de upload do arquivo e o formulário de texto normal
Veja a diferença entre "formulário de upload de arquivo" e "formulário de texto normal" através do httpwatch.
O Enctype do arquivo de upload de arquivo = "Multipart/Form-Data", que representa dados de formulário de várias partes;
Os formulários de texto normais podem ser definidos sem definir o atributo ENCTYPE:
Quando Method = ”Post”, o valor padrão do ENCTYPE é APLICAÇÃO/X-WWW-FORM-URLECODED, o que significa que, quando o método = ”Get” é usado, o valor padrão do ENCTYPE é nulo e não há texto, não há necessidade de testar o formulário de texto normal:
<Form Action = "$ {PageContext.Request.ContextPath}/FileUploadServlet" Method = "post"> Nome de usuário: <input type = "text" name = "nome de usuário"/> <br/> arquivo 1: <input type = "file" = "file1"/> <br/> file 2: <input 1: <bring type = "file" = "file1"/> <br/> file 2: <input 1: type = "submeter" value = "submeter"/> </mand>Através do teste HTTPWatch, analisando o corpo de dados do Formulário de solicitação, descobrimos que existe apenas o nome do arquivo na solicitação, mas nenhum conteúdo de arquivo. Ou seja, quando o encantamento do formulário não é multipart/formulário, a solicitação não contém o conteúdo do arquivo, mas apenas o nome do arquivo, o que significa que não há diferença entre entrada: arquivo e entrada: texto em um formulário de texto normal.
Testando o Formulário de Upload de Arquivos:
<Form Action = "$ {PageContext.Request.ContextPath}/FileUploadServlet" Method = "Post" ENCTYPE = "Multipart/Form-Data"> Nome de usuário: <input Type = "Text" Name = "UserName"/> <br/> Arquivo 1: <input Type = "FILE" ") name = "file2"/> <br/> <input type = "submit" value = "submit"/> </morm>Através do teste httpwatch, vemos a parte do corpo dos dados de solicitação do formulário e descobrimos que a parte do corpo é composta por vários componentes, cada componente corresponde a um campo de formulário e cada componente possui suas próprias informações de cabeçalho. Abaixo das informações do cabeçalho, há uma linha em branco e abaixo da linha em branco está a parte do corpo do campo. Várias partes são separadas por divisores gerados aleatoriamente.
As informações do cabeçalho do campo de texto contêm apenas uma informação do cabeçalho, ou seja, disposição de conteúdo. O valor dessas informações do cabeçalho possui duas partes. A primeira parte é fixa, a saber, os dados de forma, e a segunda parte é o nome do campo. Atrás da linha em branco está a parte principal, e a parte principal está o conteúdo preenchido na caixa de texto.
As informações do cabeçalho do campo Arquivo contêm dois cabeçalhos, disposição de conteúdo e tipo de conteúdo. Há um nome de arquivo extra na disposição de conteúdo, que especifica o nome do arquivo carregado. Tipo de conteúdo especifica o tipo de arquivo carregado. A parte principal do campo de arquivo é o conteúdo do arquivo.
Observe que, como os arquivos que carregamos são todos os arquivos de texto normais, ou seja, arquivos TXT, eles podem ser exibidos normalmente no httpwatch. Se os arquivos enviados forem exe, mp3, etc., o que você vê no httpwatch será iluminado.
4. Requisitos para servlets ao fazer o upload de arquivos
Quando o formulário enviado é um formulário de upload de arquivo, também existem requisitos para o servlet.
Primeiro de tudo, precisamos ter certeza de que os dados do formulário de upload de arquivo também estão encapsulados no objeto Solicitação.
O método Request.GetParameter (String) obtém o conteúdo especificado do caractere de campo do formulário, mas o formulário de upload de arquivo não é mais o conteúdo do caractere, mas o conteúdo de bytes, por isso é inválido.
No momento, você pode usar o método getInputStream () de solicitação para obter o objeto ServletInputStream. É uma subclasse do InputStream. Esse objeto ServletInputStream corresponde à parte do corpo de todo o formulário (começando do primeiro divisor até o final), que mostra os dados no fluxo de análise de que precisamos. Obviamente, analisar é uma coisa muito problemática, e o Apache nos forneceu ferramentas para analisá-lo: Commons-FileUpload
Você pode tentar imprimir o conteúdo do fluxo de request.getInputStream () e comparar os dados da solicitação no httpwatch.
public void DoPost (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {inputStream in = request.getInputStream (); String s = ioutils.toString (in); System.out.println (S);}------------------------------- 7DDD3370AB2CONTENT-DISPOSIÇÃO: FORM-Data; name = "Nome de usuário" Hello --------------------------- 7DDD3370AB2Content-Disposition: Form-Data; name = "file1"; FileName = "A.Txt"-Type: Text/PlainAaa ------------------------------- 7DDD3370AB2CONTENT-DISPOSIÇÃO: FORM-DATA; name = "file2"; filename = "b.txt"-type: text/planbbb ------------------------------- 7DDD3370AB2--
Commons-FileUpload
Por que usar o FileUpload:
Existem muitos requisitos para fazer upload de arquivos, lembre -se:
Deve ser um formulário de postagem;
O espreguiçador do formulário deve ser multipart/formulário;
Adicione o campo do formulário de arquivo ao formulário, ou seja,
Requisitos de servlet:
Você não pode mais usar o request.getParameter () para obter dados de formulário. Você pode usar o request.getInputStream () para obter todos os dados do formulário, em vez dos dados de um item de formulário. Isso significa que você não usa o FileUpload, precisamos analisar o conteúdo do request.getInputStream ().
1. Visão geral do FileUpload
O FileUpload é um componente de upload fornecido pelo componente Commons do Apache. Seu trabalho principal é nos ajudar a analisar a solicitação.getInputStream ()
Os pacotes JAR exigidos pelo componente FileUpload são:
Commons-FileUpload.jar, Pacote Core
Commons-io.jar, pacote de dependência
2. Aplicação simples do FileUpload
As classes principais do FileUpload são: DiskFileItemFactory, ServletFileUpload, FileItem
As etapas para usar o componente FileUpload são as seguintes:
// 1. Crie a classe de fábrica DiskFileItemFactory Object DiskFileItemFactory Factory = new DiskFileItemFactory (); // 2. Crie um objeto de analisador usando o Factory ServletFileUpload fileUpload = new ServletFileUpload (Factory); // 3. Use o analisador para analisar a lista de objetos de solicitação <FileItem> list = fileUpload.parserequest (request);
DiskFileItemFactory Disk Arquive Item Class de fábrica
public DiskFileItemFactory (int sizethreshold, repositório de arquivos)
Ao construir uma fábrica, especifique o tamanho do buffer de memória e o local de armazenamento temporário de arquivos.
Public void Setsizethreshold (int sizethreshold)
Defina o tamanho do buffer de memória, padrão 10k
public void setrepository (repositório de arquivos)
Defina o local de armazenamento de arquivos temporários, padrão System.getProperty ("java.io.tmpdir").
Buffer de memória: Ao fazer o upload de um arquivo, o conteúdo do arquivo carregado é salvo no buffer de memória primeiro. Quando o tamanho do arquivo carregado exceder o tamanho do buffer, os arquivos temporários serão gerados no lado do servidor.
Localização temporária de armazenamento de arquivos: Os arquivos de upload que excedam o tamanho do buffer de memória para gerar arquivos temporários. Os arquivos temporários podem ser excluídos através do método Delete () do FileItem
O FileItem representa cada parte dos dados no formulário de upload do arquivo
Introduziremos a classe FileItem solenemente, que é o resultado final que queremos. Um objeto FileItem corresponde a um item de formulário (campo de formulário). Campos de arquivo e campos normais existem em um formulário. Você pode usar o método iSformField () da classe FileItem para determinar se o campo de formulário é um campo normal. Se não for um campo normal, é um campo de arquivo.
Nota: Como o formulário de upload de arquivo é codificado usando dados multipart/formulários, diferente da codificação de URL tradicional, todos os métodos getParameter () não podem usar o setCharacterencoding () não pode resolver o problema distorcido dos itens de entrada.
ServletfileUpload Arquivo Class
3. Exemplo de upload simples
Escreva um exemplo simples de upload:
O formulário contém um campo de nome de usuário e um campo de arquivo;
O servlet salva arquivos carregados no diretório Uploads, exibindo nome de usuário, nome do arquivo, tamanho do arquivo, tipo de arquivo.
Primeiro passo:
Para concluir o index.jsp, apenas um formulário é necessário. Observe que o formulário deve ser posta
<Form Action = "$ {PageContext.Request.ContextPath}/FileUploadServlet" Method = "Post" ENCTYPE = "Multipart/Form-Data"> Nome de usuário: <input Type = "Text" Name = "UserName"/> <br/> Arquivo 1: <input Type = "Nome" ") value = "submeter"/> </morm>Etapa 2: Complete FileUploadServlet
Public void DoPost (solicitação HttpServletRequest, HttpServletResponse Response) lança servletexception, ioexception {// porque você deseja imprimir com resposta, defina sua resposta de codificação.setContentType ("text/html; charset = utf-8"); // Crie factory diskFileItemFactory dfif = new DiskFileItemFactory (); // Crie objeto Parser usando o Factory ServletFileUpload fileUpload = new ServletFileUpload (DFIF); tente {// use o objeto Parser para analisar a solicitação e obter a lista de fileItem List <FileItem> list = FileUpload.parserequest (request); // Traverse todos os itens do formulário para (FileItem FileItem: List) {// Se o item de formulário atual for um item de formulário normal se (fileItem.isformfield ()) {// obtenha o nome do campo do formulário atual string fieldname = FILEITEM.getFieldName (); // Se o nome de campo do item de formulário atual for nome de usuário if (fieldname.equals ("nome de usuário")) {// imprima o conteúdo do item de formulário atual, ou seja, o conteúdo inserido pelo nome de usuário do formulário Response.getWriter (). }} else {// Se o item de formulário atual não for um item de formulário normal, significa o nome do campo da sequência do campo Nome = FileItem.getName (); // Obtenha o nome do arquivo carregado // se o nome do arquivo carregado estiver vazio, nenhum arquivo enviado; } // Obtenha o caminho real, correspondendo a $ {Diretório do Projeto}/Uploads. Obviamente, este diretório deve ter string savePath = this.getServletContext (). GetRealPath ("/uploads"); // Crie o objeto de arquivo através do diretório do uploads e arquivo de nomes do arquivo Arquivo = novo arquivo (salvAPath, nome); // Salvar o arquivo de upload no local especificado FileItem.Write (arquivo); // imprima o nome do arquivo de upload Response.getWriter (). Print ("Carregue o nome do arquivo:" + nome + "<br/>"); // imprima o tamanho do arquivo de upload Response.getWriter (). Print ("Upload do tamanho do arquivo:" + FILEITEM.GETSIZE () + "<br/>"); // imprima o tipo de arquivo de arquivo carregado. }}} Catch (Exceção e) {tire nova servletexception (e); }}Detalhes do upload de arquivo
1. Coloque o arquivo carregado no diretório da Web-Inf
Se os arquivos enviados pelo usuário não forem armazenados no diretório Web-Inf, o usuário poderá acessar diretamente os arquivos enviados através do navegador, o que é muito perigoso.
Se o usuário enviar um arquivo A.JSP e o usuário acessar o arquivo A.JSP através do navegador, o conteúdo do A.JSP será executado. Se houver a seguinte declaração em A.JSP: RunTime.GetRuntime (). Exec ("Shutdown ST 1"); Então você vai ...
Normalmente, criaremos um diretório de upload no diretório Web-Inf para armazenar os arquivos enviados. Para encontrar esse diretório no servlet, precisamos usar o método GetRealPath (String) do servletContext. Por exemplo, há a seguinte declaração no meu projeto Upload1:
ServletContext servletContext = this.getServletContext (); string savePath = servletContext.getRealPath ("/web-inf/uploads");O SalvePath é: f:/tomcat6_1/webApps/upload1/web-inf/uploads.
2. Nome do arquivo (caminho completo, nome do arquivo)
O nome do arquivo carregado pode ser o caminho completo:
O nome do arquivo de upload obtido pelo IE6 é o caminho completo, enquanto o nome do arquivo de upload obtido por outros navegadores é apenas o nome do arquivo. Ainda precisamos lidar com o problema das diferenças de navegador
String name = file1fileItem.getName (); Response.getWriter (). Print (nome);
Usando diferentes navegadores para testar, o IE6 retornará o caminho completo para fazer upload do arquivo. Não sei o que o IE6 está fazendo, o que nos traz muitos problemas, o que é lidar com esse problema.
Também é muito simples lidar com esse problema. Seja um caminho completo ou não, apenas interceptamos o conteúdo após o último "/"
String name = file1fileItem.getName (); int lastIndex = name.LastIndexOf ("//"); // Obtenha a posição do último "/" if (lastIndex! = -1) {// Observe que, se não for o caminho completo, não haverá não "/". name = name.substring (lastIndex + 1); // obtenha o nome do arquivo} resposta.getWriter (). print (nome);3.
O nome do arquivo carregado contém chinês:
Quando o nome carregado contém chinês, você precisa definir a codificação. O componente Commons-FileUpload nos fornece duas maneiras de definir a codificação:
Request.Setcharacterencoding (String): Este método é a maneira mais familiar que somos.
FileUpload.setheaderencdoing (String): Este método tem maior prioridade que o anterior
O conteúdo do arquivo do arquivo carregado contém chinês:
Normalmente, não precisamos nos preocupar com o conteúdo do upload de arquivos, porque salvaremos os arquivos enviados no disco rígido! Em outras palavras, como é o arquivo e como é no servidor!
Mas se você tiver esse requisito e precisar exibir o conteúdo do arquivo carregado no console, poderá usar o FileItem.getString ("UTF-8") para lidar com a codificação
Conteúdo do arquivo de texto e conteúdo normal do formulário Use GetString ("UTF-8") da classe FileItem para lidar com a codificação.
4. A emissão de fazer upload do arquivo com o mesmo nome (renomeação de arquivos)
Normalmente, salvamos o arquivo enviado pelo usuário no diretório Uploads, mas e se o usuário enviar um arquivo com o mesmo nome? Isso causará cobertura. O método para lidar com esse problema é usar o UUID para gerar um nome exclusivo e, em seguida, usar o "_" para conectar o nome original enviado pelo arquivo.
Por exemplo, o arquivo enviado pelo usuário é "minha foto de uma polegada.jpg". Após o processamento, o nome do arquivo é: "891B3881395F4175B969256A3F7B6E10_MY ONE POLETO POTO.JPG". Este método não fará com que o arquivo perca sua extensão. Devido à singularidade do UUID, o arquivo carregado tem o mesmo nome, mas não haverá problema com o mesmo nome no lado do servidor.
public void DoPost (solicitação httpServletRequest, httpServletResponse Response) lança servletexception, ioexception {request.setcharacterencoding ("utf-8"); DiskFileItemFactory dfif = new DiskFileItemFactory (); ServletfileUpload fileUpload = new ServletFileUpload (DFIF); tente {list <FileItem> list = fileUpload.parserequest (request); // Obtenha o segundo item do formulário, porque o primeiro item do formulário é o nome de usuário, o segundo é o arquivo de arquivo de formulário FileItem FileItem = list.get (1); String name = fileItem.getName (); // Obtenha o nome do arquivo // Se o cliente estiver usando o IE6, você precisar if (lastIndex! = -1) {name = name.substring (lastIndex + 1); } // Obtenha o arquivo carregado salvath = this.getServletContext (). GetRealPath ("/web-inf/uploads"); String uuid = CommonUtils.uuid();//Generate uuid String filename = uuid + "_" + name;//The new file name is uuid + underscore + original name//Create a file object, and the uploaded file will be saved to the path specified by this file//savepath, that is, the uploaded file directory//filename, file name File file = new File(savepath, filename); // salvar o arquivo item.write (arquivo); } catch (Exceção e) {lança nova servletexception (e); }}5. Um diretório não pode armazenar muitos arquivos (diretório da loja para quebrar)
Não deve haver muitos arquivos armazenados em um diretório. Geralmente, 1.000 arquivos são armazenados em um diretório e, se houver muitos, será muito "cracky" ao abrir o diretório. Você pode tentar imprimir o diretório C:/Windows/System32, você sentirá
Ou seja, precisamos colocar os arquivos enviados em diretórios diferentes. No entanto, um diretório não pode ser usado para cada arquivo carregado, pois esse método levará a muitos diretórios. Então, devemos usar algum algoritmo para "quebrar"!
Existem muitas maneiras de quebrá -lo, como usar datas para quebrá -lo, gerando um diretório todos os dias. Você também pode usar a primeira letra do nome do arquivo para gerar um diretório e os arquivos com a mesma letra inicial são colocados no mesmo diretório.
Algoritmo de quebra de data: se houver muitos arquivos enviados em um determinado dia, também haverá muitos arquivos de diretórios;
O algoritmo para quebrar a primeira letra: se o nome do arquivo estiver em chinês, porque há muitos chineses, levará a muitos diretórios.
Usamos o algoritmo de hash aqui para interromper:
Obtenha o código de hash do nome do arquivo: int hcode = name.hashcode ()
Obtenha os 4 bits inferiores de Hcode e converta -os em caracteres hexadecimais para obter os 5 ~ 8 bits de HCode e convertê -los em caracteres hexadecimais para gerar uma cadeia de diretórios usando esses dois caracteres hexadecimais. Por exemplo, os caracteres mais baixos de 4 bits são "5"
A vantagem desse algoritmo é que um máximo de 16 diretórios é gerado no diretório do uploads, e um máximo de 16 diretórios é gerado em cada diretório, ou seja, 256 diretórios e todos os arquivos enviados são colocados nesses 256 diretórios. Se o número máximo de cada diretório for de 1000 arquivos, um total de 256.000 arquivos poderá ser salvo.
Por exemplo, o nome do arquivo de upload é: novo documento de texto.txt e obtenha o código de hash de "novo documento de texto.txt" e, em seguida, obtenha os 4 dígitos inferiores do código de hash e 5 a 8 dígitos. Se os 4 bits inferiores forem: 9 e 5 ~ 8 bits forem 1, o caminho de salvamento do arquivo será uploads/9/1//1/
int hcode = name.hashcode (); // Obtenha o código de hash do nome do arquivo // Obtenha os 4 bits baixos de hcode e converta -o em string hexadecimal string dir1 = integro.toHexstring (hcode & 0xf); // obtém a baixa 5 ~ 8 bits de hcode e converti no >>> 4 & 0xf); // Conecte o caminho de salvar o arquivo ao caminho completo savepath = salvarpath + "/" + dir1 + "/" + dir2; // porque esse caminho pode não existir, crie -o como um objeto de arquivo e, em seguida, crie uma cadeia de diretórios para garantir que o diretório já exista novo antes de salvar o arquivo (salvamento) .mkdirs ();
6. Limites de tamanho para arquivos enviados individuais
É muito simples limitar o tamanho dos arquivos carregados, apenas o SetfilesizEMAX (longo) da classe ServletFileUpload. O parâmetro é o número de limite superior de bytes do arquivo carregado. Por exemplo, ServletFileUpload.SetFilesizEMAX (1024*10) significa que o limite superior é de 10kb.
Depois que o arquivo carregado exceder o limite superior, uma exceção FileUploadBase.FilesizElimitexEdEdException será lançada. Podemos obter essa exceção no servlet e a saída "o arquivo carregado excede o limite" da página.
public void DoPost (solicitação httpServletRequest, httpServletResponse Response) lança servletexception, ioexception {request.setcharacterencoding ("utf-8"); DiskFileItemFactory dfif = new DiskFileItemFactory (); ServletfileUpload fileUpload = new ServletFileUpload (DFIF); // Defina o limite superior do arquivo único carregado como 10kb fileUpload.setFileSizEMAX (1024 * 10); tente {list <FileItem> list = fileUpload.parserequest (request); // Obtenha o segundo item do formulário, porque o primeiro item de formulário é o nome de usuário, o segundo é o arquivo de formulário de arquivo fileItem = list.get (1); String name = fileItem.getName (); // Obtenha o nome do arquivo // Se o cliente estiver usando o IE6, você precisar if (lastIndex! = -1) {name = name.substring (lastIndex + 1); } // Obtenha o arquivo carregado salvath = this.getServletContext (). GetRealPath ("/web-inf/uploads"); String uuid = CommonUtils.uuid (); // Gere uuid string filename = uuid + "_" + name; // O novo nome do arquivo é uuid + sublinhado + nome original int hcode = name.hashcode (); // obtenha o hashcode do nome do arquivo // obtenha o 4 Bits de HC de HC Integer.ToHexString (Hcode & 0xf); // Obtenha os 5 ~ 8 bits inferiores de Hcode e converta -os em String hexadecimal String dir2 = Integer.toHexString (hcode >>> 4 & 0xf); // Conecte o caminho de salvar o arquivo em um caminho completo savepath = savePath + "/" + dir1 + "/" + dir2; // Como esse caminho pode não existir, crie um objeto de arquivo e, em seguida, crie uma cadeia de diretórios para garantir que o diretório já exista antes de salvar o arquivo novo (salveira) .mkdirs (); // Crie um objeto de arquivo e o arquivo carregado será salvo no caminho especificado por este arquivo // salvath, ou seja, o arquivo carregado salvar diretório // nome de arquivo, nome do arquivo, nome do arquivo; // Salvar fileItem.write (arquivo); } Catch (Exceção e) {// Determine se o tipo de exceção arremessada é FileUploadBase.FilesizELImitexEdEdException // se sim, significa que o limite foi excedido ao fazer o upload do arquivo. if (e instanceof fileUploadbase.filesizelimitexcededException) {// salve a mensagem de erro na solicitação request.setAttribute ("msg", "upload falhou! O arquivo carregado excedeu 10kb!"); // Avance para a página Index.jsp! Na página Index.jsp, você precisa usar $ {msg} para exibir a mensagem de erro request.getRequestDispatcher ("/index.jsp"). Forward (solicitação, resposta); retornar; } lança nova servletexception (e); }}7. Limite de tamanho total para o upload de arquivos
O formulário para fazer upload de um arquivo pode permitir que vários arquivos sejam carregados, por exemplo:
Às vezes, precisamos limitar o tamanho de uma solicitação. Ou seja, o número máximo de bytes para esta solicitação (soma de todos os itens de formulário)! Implementar esta função também é muito simples. Você só precisa chamar o método SetSizemax (longo) da classe ServletFileUpload.
Por exemplo, FileUpload.SetSizEMAX (1024 * 10);, o limite superior para toda a solicitação é de 10kb. Quando o tamanho da solicitação exceder 10kb, o método parserequest () da classe ServletFileUpload lançará uma exceção FileUploadBase.sizelimitexcededException.
8. Tamanho do cache e diretório temporário
Pense nisso, se eu carregar um filme de Blu-ray, salve o filme na memória primeiro e depois copie-o para o disco rígido do servidor através da memória, então sua memória pode ser consumida?
Portanto, o componente FileUpload não pode salvar todos os arquivos na memória. O FileUpload determinará se o tamanho do arquivo excede 10kb. Nesse caso, salve o arquivo no disco rígido. Se não exceder, salve -o na memória.
10KB é o valor padrão do FileUpload, podemos defini -lo.
Quando o arquivo é salvo no disco rígido, o FileUpload salva o arquivo no diretório temporário do sistema. Claro, você também pode definir o diretório temporário
public void DoPost (solicitação httpServletRequest, httpServletResponse Response) lança servletexception, ioexception {request.setcharacterencoding ("utf-8"); DiskFileItemFactory dfif = new DiskFileItemFactory (1024*20, novo arquivo ("f: // temp")); ServletfileUpload fileUpload = new ServletFileUpload (DFIF); tente {list <FileItem> list = fileUpload.parserequest (request); FileItem fileItem = list.get (1); Nome da string = FILEITEM.GETNAME (); String savePath = this.getServletContext (). GetRealPath ("/web-inf/uploads"); // Salvar fileItem.Write (Path (Path (SalvePath, Nome));} Catch (Exceção e) {Throw New ServleTexception (e);}} Caminho de arquivo privado (String SalvePath, String FileName) {// Obtenha o nome do arquivo int a partir do caminho completo lastIndex = FILENAME.LASTIndexOf ("//") se ("); FileName.substring (LastIndex + 1); Dir2;Download do arquivo
1. Download 1 através do servlet
Os recursos baixados devem ser colocados no diretório Web-Inf (tudo bem, desde que o usuário não possa acessar diretamente através do navegador) e, em seguida, faça o download através do servlet.
Dê o hiperlink na página JSP, link para o DownloadServlet e forneça o nome do arquivo para download. Em seguida, o DownloadServlet recebe o caminho real do arquivo e grava o arquivo no fluxo de resposta.getOutputStream ().
Download.jsp
<Body> Esta é a minha página JSP. <br> <a href = "<c: url value = '/downloadservlet? path = a.avi' //>"> a.avi </a> <br/> value = '/DownloadServlet? Path = A.txt' ////> "> a.txt </a> <br/> </body>
DownloadServlet.java
public void Doget (solicitação httpServletRequest, httpServletResponse Response) lança servletexception, ioexception {string filename = request.getParameter ("caminho"); String filepath = this.getServletContext (). GetRealPath ("/web-inf/uploads/" + filename); Arquivo de arquivo = novo arquivo (filepath); if (! file.exists ()) {Response.getWriter (). print ("O arquivo que você deseja baixar não existe!"); retornar; } Ioutils.copy (new FileInputStream (file), Response.getOutputStream ());}O código acima tem os seguintes problemas:
1. Você pode baixar a.avi, mas o nome do arquivo na caixa de download é downloadservlet;
2. Você não pode baixar A.JPG e A.TXT, mas exibi -los na página.
2. Download 2 através do servlet
Vamos lidar com o problema no exemplo anterior, para que a caixa de download possa exibir o nome do arquivo correto e você pode baixar arquivos A.JPG e A.TXT
Lidar com o problema acima, adicionando cabeçalho de disposição de conteúdo. Quando o cabeçalho da disposição de conteúdo estiver definido, o navegador aparecerá na caixa de download
E você também pode especificar o nome do arquivo baixado através do cabeçalho da disposição de conteúdo!
String filename = request.getParameter ("caminho"); String filepath = this.getServletContext (). GetRealPath ("/web-inf/uploads/" + filename); Arquivo de arquivo = novo arquivo (filepath); if (! file.exists ()) {Response.getWriter (). print ("O arquivo que você deseja baixar não existe!"); retornar; } Response.addHeader ("Content-Disposition", "Applement; FileName =" + FileName); Ioutils.copy (new FileInputStream (FILE), Response.getOutputStream ());Embora o código acima já possa lidar com o download de arquivos como TXT e JPG e também lidar com o problema de exibir nomes de arquivos na caixa de download, se o nome do arquivo baixado estiver em chinês, ele ainda não pode
3. Download 3 através do servlet
Abaixo está o problema de lidar com a exibição de chineses na caixa de download!
De fato, essa pergunta é muito simples. Você só precisa codificar chinês através do URL!
Download.jsp
<a href = "<c: url value = '/downloadservlet? path = esse assassino não é muito frio.avi' //>"> esse assassino não é muito frio.avi </a> <br/> <a href = "<c: url value = '/downloads? href = "<C: URL Value = '/DownloadServlet? PATH = Description.txt'/>"> Descrição.txt </a> <br/>
DownloadServlet.java
String filename = request.getParameter ("caminho"); // Na solicitação GET, o parâmetro chinês contém os chineses e precisa ser convertido por você. //Claro, se você usa o "filtro de codificação global", não precisa lidar com isso aqui FileName = new String (FILENAME.GETBYTES ("ISO-8859-1"), "UTF-8"); string filepath = this.getServletContext () .MeeM). Arquivo (filepath); if (! File.exists ()) {Response.getWriter (). Print ("O arquivo que você deseja baixar não existe!"); return;} // Todos os navegadores usarão a codificação local, ou seja, o sistema operacional chinês usa GBK // depois que o navegador receber esse nome de arquivo, ele usará ISO-8859-1 para decodificar o nome do arquivo = new String (FILENAMED.ADBYTES ("GBK"), "ISO-885-1"); nome do arquivo); ioutils.copy (new FileInputStream (arquivo), Response.getOutputStream ());O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.