O que é o upload de arquivo?
O upload de arquivo é para salvar informações do usuário.
Por que preciso fazer upload de um arquivo?
Quando um usuário se registra, o usuário pode precisar enviar uma foto. Então esta foto deve ser salva.
Carregar componentes (ferramentas) Por que precisamos usar a ferramenta de upload?
Por que precisamos fazer upload de componentes? Quando queremos obter os dados do cliente, geralmente o obtemos pelo método getParameter ().
Os dados do arquivo carregado são divididos pelo protocolo MIME e o formulário é encapsulado em binário. Em outras palavras: getParameter () não pode obter os dados do arquivo carregado.
Vamos primeiro olhar como os uploads de arquivo http trazem dados com você
Página JSP, Formulário deve especificar Enctype: Multipart/Form-Data
<form action = "$ {PageContext.Request.ContextPath}/servlet/uploadservlet1" Enctype = "multipart/form-data" métod = "post"> upload User: <input type = "text" name = "username"> <br/> File 1: <input type = "filge" "Nome =" File "=" FILE ") name = "file2"> <br/> <input type = "submit" value = "submit"> </morm>HTTP Package pegando
Tente obter dados usando getParameter () no servlet
String ss = request.getParameter ("nome de usuário"); system.out.println (ss);Você não pode obter os dados usando diretamente o getParameter.
Então, o que devemos fazer? ? ? ? O objeto de solicitação fornece o fluxo do servletInputStream para ler os dados para nós
Tentamos ler o arquivo
ServletInputStream inputStream = request.getInputStream (); byte [] bytes = novo byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {System.out.println (new String (bytes, 0, len)); }Adicione um controle de entrada adicional à página JSP
<input type = "text" name = "senha">
O arquivo de texto que carreguei é 111111, e o efeito de leitura é o seguinte:
Agora podemos ler os dados do upload de arquivos, mas agora a pergunta é: como separar os dados enviados do arquivo dos dados enviados para o servidor? ? ? Vimos acima na foto, eles são misturados.
É difícil separar de acordo com nossa prática usual, por isso precisamos fazer upload de componentes
Existem dois tipos de componentes do FileUploads de upload [mais operação] SamrtUpload [mais operação] FileUpload
Para usar o componente FileUpload, você precisa importar dois pacotes JAR
As etapas de desenvolvimento Commons-IO Commons-FileUpload criam um objeto de fábrica de analisador [DiskFileItemFactory] Crie um analisador através da fábrica de analisador [servletFileUpload] Chame o método do analisador para analisar o objeto de solicitação, obtenha todo o arquivo de conteúdo enviado [Lista] da lista, determinar se cada objeto é um arquivo de uplos. Se for um campo de formulário normal, obtenha o nome do campo e o valor do campo. Se for um arquivo enviado, ligue para o método InputSteam para obter o fluxo de entrada, leia os dados enviados rapidamente.
tente {// 1. Obtenha a fábrica de Parsers DiskFileItemFactory Factory = new DiskFileItemFactory (); // 2. Obtenha o Parser ServletFileUpload upload = new ServletFileUpload (Factory); // 3. Determinar o tipo de formulário de upload se (! Upload.ismultipartContent (request)) {// upload O formulário é um formulário normal e, em seguida, obtenha os dados da maneira tradicional de retornar; } // Para fazer upload do formulário, ligue para o analisador para analisar a lista de dados carregada <FileItem> list = upload.parserequest (request); // fileItem // transfuse a lista e utiliza o objeto FileItem usado para encapsular o primeiro objeto de dados de dados do item de entrada para (Item FileItem: list) {if (item.isformfield ()) {// o que você obtém é o nome de entrada de entrada de entrada normal = item.getFieldName (); // Obtenha o nome do item de entrada Valor da string = item.getString (); System.out.println (nome + "=" + valor); } else {// Obtenha o item de entrada do upload string filename = item.getName (); // Obtenha o nome do arquivo de upload c:/documentos e configurações/thinkpad/desktop/1.txt filename = filename.substring (filename.lastindexof ("//")+1); InputStream in = item.getInputStream (); // GOT DATA DE ATUALIZAÇÃO INT LEN = 0; buffer de byte [] = novo byte [1024]; String savePath = this.getServletContext (). GetRealPath ("/upload"); FileOutputStream Out = new FileOutputStream (SavePath + "//" + FileName); // Escreva o arquivo no diretório de upload while ((len = in.read (buffer))> 0) {out.write (buffer, 0, len); } in.close (); out.Close (); }}} catch (Exceção e) {e.printStackTrace (); }Testando que os campos comuns e os arquivos enviados podem ser lidos e obtidos!
SmartUpload
Para usar o componente SmartUpload, você precisa importar o pacote de desenvolvimento SmartUpload.jar
Início rápido
// componente instanciado SmartUpload smartUpload = new SmartUpload (); // inicialize a operação de upload smartupload.initialize (this.getServletConfig (), solicitação, resposta); tente {// upload de preparação smartupload.upload (); // Para dados comuns, é tão simples que o objeto de solicitação não pode obter os parâmetros enviados. Além disso, você precisa confiar na senha SmartUpload = SmartUpload.getRequest (). GetParameter ("senha"); System.out.println (senha); // upload para fazer o upload Filer SmartUpload.save ("UploadFile"); } catch (smartUploadexception e) {e.printStackTrace (); }teste
Da mesma forma, podemos fazer upload de arquivos para a pasta UploadFile. A quantidade de código é realmente muito reduzida!
Você também pode obter parâmetros de campos normais
Mudei o nome do arquivo para o código ilegal chinês e o código chinês iluminado para fazer upload de dados, e foi um código distorcido:
Os dados chineses enviados pelo formulário também são distorcidos.
Como mencionado acima, o formulário de carregamento dos dados do arquivo é encapsulado em binário; portanto, usando a solicitação para codificar os dados não funcionará para os dados enviados pelo formulário!
O FileUpload resolve o código Gledled
Usar o FileUpload para resolver problemas ilegais é muito simples
Resolva o nome de arquivo chinês ilegal. Depois de obter o analisador, basta definir a codificação do analisador como UTF-8!
// Defina a codificação do upload fileUpload.setheadeRencoding ("UTF-8");Resolva os dados de formulário distorcidos. Ao obter valores de formulário, use a codificação UTF-8 para obtê-los.
String value = FILEITEM.GETSTRING ("UTF-8");Efeito:
SmartUpload resolve o código Gledled
Este componente é um pouco problemático para resolver o problema do código ilegal. Encontrei várias soluções online, mas não consegui encontrar uma simples ...
Portanto, se os dados não envolverem chinês, use o componente SmartUpload e, se envolver dados chineses, use o componente FileUpload!
Carregue vários arquivos, adicione dinamicamente controles de upload
Suponha que eu tenha vários arquivos para fazer upload agora, e o número de arquivos a serem enviados é incerto. Então, o que devemos fazer? ? ?
É impossível listar muitos controles para fazer upload de arquivos na página, o que não é bonito. Se o usuário não puder usar tantos controles, é um desperdício.
Portanto, queremos adicionar controles dinamicamente para fazer upload de arquivos. Se o usuário também deseja fazer upload de arquivos, ele só precisará gerar controles dinamicamente!
analisar
Para gerar controles dinamicamente na página, nada mais é do que usar o código JavaScript.
Então, o que fazemos? ?
Vamos fazer isso: quando o usuário quiser fazer upload de um arquivo, clique no botão e o botão ligue o evento para gerar o controle para o upload do arquivo.
Para fazer mais perfeitamente, sempre que um controle de upload de arquivo é gerado, um botão de exclusão também é fornecido para excluir o controle!
Devemos usar o DIV para carregar os controles e excluir botões que queremos gerar. Quando o usuário clicar para excluir, ele deve ocultar o botão Excluir e o upload de arquivos controles. Então, é melhor usar divs aninhados!
Código da página de código:
<table> <tr> <td>Upload user: </td> <td><input type="text" name="username"></td> </tr> <tr> <td>Add upload file</td> <td><input type="button" value="Add upload file"> </td> </tr> <tr> <td> <div> </div> </td> </td> </tr> </tabela>
Código JavaScript
<script type = "text/javascript"> function adwupLoadfile () {// gerar controle de arquivo de controle var input = document.createElement ("input"); input.type = 'arquivo'; input.name = 'nome do arquivo'; // gerar botão de exclusão var del = document.createElement ("input"); del.Type = 'Button'; del.value = 'excluir'; // gerar div vars interno var nobrista = document.createElement ("div"); // liga dois controles ao inerdiv.appendChild (entrada); Innerdiv.AppendChild (Del); // Obtenha o controle de div e ligue a div e ligue o div inteiro à div vartterDiv = document.getElementById ("arquivo"); outterdiv.appendChild (Innerdiv); // Bind Event del.OnClick = function DELETE () {// chamando o método Remover da div externa para matar a div this.parentnode.parentnode.removeChild (this.parentNode); }} </script>Detalhes do upload do arquivo Se o tamanho do arquivo carregado for maior que o tamanho do arquivo que definimos, o arquivo usará um arquivo temporário para salvar os dados carregados ao fazer o upload. Após o upload, devemos excluir o arquivo temporário. O local em que o arquivo de upload não pode ser gerenciado pelo servidor da Web, caso contrário, pode causar problemas de segurança [outros podem modificar o arquivo de upload através dos meios] Se o nome do arquivo de upload for o mesmo, o arquivo de upload original será substituído. Queremos gerar um nome de arquivo exclusivo. Se o número de usuários for grande, existem muitos arquivos enviados. Em seguida, não devemos salvar todos os arquivos de upload em um diretório, o que provavelmente fará com que o disco trave. Portanto, temos que dispersar os arquivos enviados para diretórios diferentes. analisar
O problema de excluir arquivos temporários é muito simples. Você só precisa ligar para o método de exclusão () do FileItem após a conclusão de todas as operações.
Para impedir que o arquivo carregado seja gerenciado pelo servidor da Web, podemos apenas colocar o local do arquivo carregado no Web-Inf/ Diretório!
Para o mesmo nome do arquivo, podemos usar o nome do arquivo UUID+ carregado pelo usuário como nosso nome de arquivo Salvar upload. Esse nome de arquivo é único.
Para interromper os arquivos enviados, precisamos usar o algoritmo HashCode para quebrar.
Os quatro bits inferiores geram diretório de primeiro nível 5-8 bits geram código de diretório de segundo nível
Vamos escrever um código de arquivo de upload relativamente completo
Use o algoritmo HashCode para quebrar diretórios salvos
private string makedirPath (nome do arquivo da string, caminho da string) {// calcule os diretórios primário e secundário através do nome do arquivo int hashcode = filename.hashcode (); int dir1 = hashcode & 0xf; int dir2 = (hashcode & 0xf0) >> 4; String dir = caminho + "//" + dir1 + "//" + dir2; // Se o diretório não existir, crie o arquivo de diretório Arquivo = novo arquivo (dir); if (! file.exists ()) {file.mkdirs (); } // retorna o caminho completo retornar dir; }Gerar nomes de arquivos exclusivos
private string makefilename (string filename) {// use sublscore para separar o nome do uuid e o arquivo, e o nome do arquivo pode ser analisado posteriormente. return uuid.randomuuid (). ToString () + "_" + nome do arquivo; }Código carregado
// Crie fábrica em fábrica fileItemFactory Factory = new DiskFileItemFactory (); // Crie um analisador através do Factory ServletFileUpload fileUpload = new ServletFileUpload (Factory); // Defina o código de upload fileUpload.setheadeRencoding ("UTF-8"); // julgue o tipo de formulário de upload if (! FileUpload.ismultipartContent (request)) {// carrega o formulário como um formulário normal e, em seguida, obtenha os dados da maneira tradicional para retornar; } tente {// analisar o objeto de solicitação para obter list [carregar toda a lista de conteúdo carregado] <FileItem> list = fileUpload.parserequest (request); // Viaje através da lista para determinar se o conteúdo carregado é um campo normal ou um arquivo de upload para (FileItem FileItem: List) {// se for um item de entrada normal se (fileItem.isformfield ()) {// obtenha o nome e o valor do item de entrada Nome da string = FileItem.getFieldName (); String value = FILEITEM.GETSTRING ("UTF-8"); System.out.println (nome + "=" + valor); } else {// se for um arquivo de upload // Obtenha o nome de upload [incluindo o nome do caminho] string filename = FILEITEM.getName (); // interceptar o nome do arquivo FILENAME = FILENAME.SUBSTRING (FILENAME.LASTIndexOf ("//") + 1); // gerar um nome de arquivo exclusivo nome do arquivo = makefilename (nome do arquivo); InputStream inputStream = fileItem.getInputStream (); // Obtenha o caminho do projeto e escreva o arquivo enviado no projeto da string do projeto = this.getServletContext (). GetRealPath ("/web-inf/uploadfile"); // Obtenha o caminho do diretório disperso string realpath = makedirpath (nome do arquivo, caminho); FileOutputStream outputStream = new FileOutputStream (RealPath + "//" + nome do arquivo); byte [] bytes = novo byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {outputStream.write (bytes, 0, len); } inputStream.close (); outputStream.Close (); // exclua os dados do arquivo temporário fileItem.Delete (); }}} catch (fileUploadexception e) {e.printStackTrace (); }Efeito: O diretório foi interrompido com sucesso e o nome do arquivo era único.
Liste os arquivos no diretório carregado e forneça downloads
Ao explicar o objeto Response, o download do arquivo foi explicado. Desta vez, escreveremos um pequeno caso para consolidar o download do arquivo.
Existem 3 arquivos no diretório de upload
analisar
Primeiro, liste todos os arquivos no diretório. Como precisamos baixar o arquivo de acordo com o nome do arquivo mais tarde, usamos uma coleção de mapa para salvar todos os arquivos
A parte de download também é muito simples. Encontre o arquivo correspondente de acordo com o nome do arquivo e faça o upload da localização do arquivo, leia e escreva e modifique o cabeçalho da mensagem para obter download.
Obtenha o caminho para carregar e fazer upload de arquivos, descubra todos os arquivos recursivamente (julgando se é um arquivo ou é uma saída recursiva), carregue -o na coleção de mapas e passe a coleção de mapas para a recepção para exibir quando o usuário clicar para baixar e obtenha o caminho absoluto de acordo com o nome original. Se o recurso existir, o usuário poderá baixar o código e colocar todos os arquivos armazenados no diretório Web-Inf/ na coleção de mapas.
DoPost nocivo protegido (solicitação httpServletRequest, resposta httpSertletResponse) lança servletexception, ioexception {// obtenha o diretório em que o arquivo carregado é string filepath = this.getServletContext (). Mapa mapa = new hashmap (); // Use a recursão para obter todos os arquivos e adicioná -los ao mapa Getallfiles (novo arquivo (filepath), mapa); request.setAtattribute ("mapa", mapa); request.getRequestDispatcher ("/listfile.jsp"). Forward (solicitação, resposta); } private void getallfiles (arquivo filepath, mapa mapa) {// Se não for um arquivo, é uma pasta se (! filepath.isfile ()) {// lista todos os arquivos na pasta (talvez um arquivo, talvez uma pasta) arquivos [] arquivos = filepath.listfiles (); para (arquivo de arquivo: arquivos) {// julgue o arquivo obtido (ou pasta) e getallfiles (arquivo, mapa); }} else {// Digite a instrução else, ele deve ser um arquivo // obtenha o nome do arquivo string filename = filepath.getName (). substring (filepath.getName (). lastIndexof ("_") + 1); // Salvamos o nome completo do arquivo como a chave e o nome do arquivo como o valor no mapa de coleta do mapa.put (filepath.getName (), nome do arquivo); }}Mostrar arquivos para download na página JSP
<c: foreach itens = "$ {map}" var = "me"> <c: url var = "url" value = "/downFileServlet"> <c: param name = "filename" value = "$ {me.key}"> </c: param> </c: url> $ {me.value} <ahref " </a> <br> </c: foreach>Implementar o servlet baixado
Protegido void DoPost (solicitação httpServletRequest, httpServletResponse resposta) lança servletexception, ioexception {// obtenha o nome completo do arquivo string filename = request.getParameter ("nome do arquivo"); // Se forem dados chineses, a transcodificação é necessária. FILENAME = new String (FILENAME.GETBYTES ("ISO8859-1"), "UTF-8"); // Obtenha o local onde o arquivo é salvo String Path = this.getServletContext (). GetRealPath ("/web-inf/uploadfile"); // O arquivo é salvo através do nome do arquivo por HashCode, e o arquivo é obtido através do nome do arquivo string filerealPath = makefilepath (nome do arquivo, caminho); System.out.println (FileRealPath); // julga se o arquivo existe arquivo de arquivo = novo arquivo (FileRealPath); if (! file.exists ()) {request.setAttribute ("mensagem", "o recurso que você deseja baixar não existe!"); request.getRequestDispatcher ("/message.jsp"). Forward (solicitação, resposta); retornar ; } // existir // Leia o arquivo e grave os dados no navegador FileInputStream inputStream = new FileInputStream (FileRealPath); byte [] bytes = novo byte [1024]; int len = 0; while ((len = inputStream.read (bytes))> 0) {Response.getOutputStream (). write (bytes, 0, len); } inputStream.close (); // Defina o cabeçalho da mensagem para informar ao navegador que este é o nome da string do arquivo baixado = filename.substring (filename.lastIndexOF ("_") + 1); Response.setheader ("Content-Disposition", "Applement; filename =" + urlencoder.encode (nome, "utf-8")); } private string makefilepath (string filename, string path) {int hashcode = filename.hashcode (); int dir1 = hashcode & 0xf; int dir2 = (hashcode & 0xf0) >> 4; String dir = caminho + "//" + dir1 + "//" + dir2 + "//" + nome do arquivo; retornar dir; }Efeito
Se houver algum erro no artigo, corrija eu e todos se comunicarão. Obrigado pelo seu apoio ao wulin.com.