zoukankan      html  css  js  c++  java
  • 第十章_文件上传

    10.1、client编程

    要上传文件,必须利用multipart/form-data设置HTML表单的enctype的属性值,像以下这样:

    <form action="action" enctype="multipart/form-data" method="post">
      		Select a file<input type="file" name="fieldName" />
      		<input type="submit" value="Upload" />
      	</form>

    10.2、server端编程

    Servlet中的server端文件上传编程主要环绕着MultipartConfig注解类型和javax.servlet.http.Part接口进行。

    处理上传文件的Servlet必须用@MultipartConfig进行标注。MultipartConfig能够带有下面属性。这些都是可选的。

    maxFileSize,表示最多可上传的文件容量。超过设定值的文件将会遭到拒绝。

    默认值为-1,表示不受限制。

    maxRequestSize。表示同意多部分HTTP请求的最大容量。

    它的默认值为-1。不受限制。

    Location。上传的文件保存到磁盘的指定位置,调用Part中的write方法将用到它。

    fileSizeThreshold。设定一个溢出尺寸,超过这个值之后。上传的文件将被写入磁盘。

    在一个由多部分组成的请求中,每个表单域,包含非文件域,都会被转换成一个PartHttpServletRequest接口定义了下面方法来处理多部分的请求:

    Part getPart(java.lang.String name)

    返回与指定名称相关的Part

    java.util.Collection<Part> getParts()

    返回这个请求中全部的part

    Part接口中还具有下面方法:

    java.lang.String getName()

    获取到这部分的名称。比如相关表单域的名称

    java.lang.String getContentType()

    假设Part是一个文件,那么将返回Part的内容类型,否则返回null

    java.util.Collection<java.lang.String> getHeaderNames()

    返回这个Part中的全部标头名称

    java.lang.String getHeader(java.lang.String headerName)

    返回指定标头名称的值

    java.util.Collection<java.lang.String> getHeaders(java.lang.String headerName)

    返回这个Part中全部标头的名称

    Void write(java.lang.String path)

    将上传的文件写入磁盘中。假设path是一个绝对路径,那么将写入指定的路径。

    假设path是一个相对路径。那么将被写入相对于MultiConfig注解的location属性值的指定路径。

    Void delete()

    删除该文件相应的存储,包含相关的暂时文件。

    java.io.InputStream getInputStream()

    inputStream的形式返回上传文件的内容

    假设相关的HTML输入时一个文件input元素,则Part将返回这些标头:

    content-type:contentType

    content-disposition:form-data; name=”fieldName”; fileName=”fileName” 

    比如,上传输入域中一个名称documentnote.txt文件时,将导致相关的部门也具有这些标头:

    content-type:text/plain

    content-disposition:form-data; name=”document”; fileName=”note.txt”

    假设没有选择不论什么文件,还是会为该文件域创建一个Part。可是相关标头例如以下:

    content-type:application/octet-stream

    content-disposition:form-data; name=”document”; fileName=””

    Part接口的getName返回与这部分有关的域的名称,而不是上传文件的名称。要想返回后者,须要解析content-disposition标头,其格式例如以下:

    content-disposition:form-data; name=”fieldName”

    Servlet中处理上传文件时,须要:

    1、查看石头存在content-type标头。检验一个Part是属于普通的表单域买还是文件域。你也能够通过在Part中调用getContentType方法或者getHeader(“content-type”)来完毕检查。

    2、假设有content-type标头,那么将查看上传文件名称称是否为空。文件名称为空,表示有文件类型的域存在,可是没有选择要上传的文件。

    3、假设文件存在。就能够调用Part中的write方法来写入磁盘。调用时同一时候传递一个绝对路径,或是相对于MultipartConfig注解的location属性的路径。

    11.3、上传Servlet范例

    SingleUploadServlet.java

    package app11a.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.MultipartConfig;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.Part;
    @WebServlet(urlPatterns = {"/singleUpload"})
    @MultipartConfig
    public class SingleUploadServlet extends HttpServlet{
    	private static final long serialVersionUID = 1L;
    	/**
    	 * 通过part过得文件名
    	 * @param part
    	 * @return
    	 */
    	private String getFileName(Part part){
    		String contentDispositionHeader = part.getHeader("content-disposition") ;
    		String[] elements = contentDispositionHeader.split(";") ;
    		for(String element: elements){
    			if(element.trim().startsWith("filename")){
    				return element.substring(element.indexOf('=') + 1).trim().replace(""", "") ;
    			}
    		}
    		return null ;
    	}
    	@Override
    	public void doPost(HttpServletRequest req, HttpServletResponse resp)
    			throws ServletException, IOException {
    		req.setCharacterEncoding("utf-8") ;
    		resp.setCharacterEncoding("utf-8") ;
    		Part part = req.getPart("filename") ;
    		String fileName = getFileName(part) ;
    		if(fileName != null && !fileName.isEmpty()){
    			part.write(getServletContext().getRealPath("/WEB-INF") + "/" + fileName) ;
    		}
    		resp.setContentType("text/html") ;
    		PrintWriter writer = resp.getWriter() ;
    		writer.print("<br/>Upload file name: " + fileName) ;
    		writer.print("<br/>Size: " + part.getSize()) ;
    		String author = req.getParameter("author") ;
    		writer.print("<br/>Author: " + author) ;
    	}
    	
    }
    

    singleUplpad.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <html>
      <head>
        <title>My JSP 'singleUpload.jsp' starting page</title>
      </head>
      
      <body>
      	<h1>Select a file to upload</h1>
      	<form action="singleUpload" method="post" enctype="multipart/form-data">
      		Author: <input type="text" name="author"/><br/>
      		Select file to upload <input type="file" name="filename"/><br/>
      		<input type="submit" value="上传"/>
      	</form>
      </body>
    </html>
    



    11.4、多文件上传

    MultipleUploadsServlet.java

    package app11a.servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Collection;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.MultipartConfig;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.Part;
    @WebServlet(urlPatterns = {"/multipleUploads"})
    @MultipartConfig
    public class MultipleUploadsServlet extends HttpServlet{
    	
    	private static final long serialVersionUID = 1L;
    	
    	private String getFileName(Part part){
    		String contentDispositionHeader = part.getHeader("content-disposition") ;
    		String[] elements = contentDispositionHeader.split(";") ;
    		for(String element: elements){
    			if(element.trim().startsWith("filename")){
    				return element.substring(element.indexOf('=') + 1).trim().replace(""", "") ;
    			}
    		}
    		return null ;
    	}
    	
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    		throws ServletException, IOException{
    		request.setCharacterEncoding("utf-8") ;
    		response.setCharacterEncoding("utf-8") ;
    		response.setContentType("text/html") ;
    		PrintWriter writer = response.getWriter() ;
    		
    		Collection<Part> parts = request.getParts() ;
    		for(Part part : parts){
    			//通过getContentType获得是否是文件域
    			if(part.getContentType() != null){
    				String fileName = getFileName(part) ;
    				//通过文件名称获得是否有文件
    				if(fileName != null && ! fileName.isEmpty()){
    					part.write(getServletContext().getRealPath("/WEB-INF") + "/" + fileName) ;
    					writer.print("<br/>Uploaded file name: " + fileName) ;
    					writer.print("<br/>Size: " + part.getSize()) ;
    				}
    			}else{
    				String partName = part.getName() ;
    				String fieldValue = request.getParameter(partName) ;
    				writer.print("<br/>" + partName + ": " + fieldValue) ;
    			}
    		}
    	}
    	
    }
    

    multipleUploads.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <html>
      <head>
        <title>My JSP 'multipleUploads.jsp' starting page</title>
      </head>
      
      <body>
        <h1>Select a file to upload</h1>
        <form action="multipleUploads" enctype="multipart/form-data" method="post">
        	Author: <input name="author"/><br/>
        	First file to upload <input type="file" name="uploadFile"/>
        	<br/>
        	Second file to upload <input type="file" name="uploadFile2"/>
        	<br/>
        	<input type="submit" value="上传"/>
        </form>
      </body>
    </html>
    

    执行截图:



    11.5、上传client

    本例中利用javascriptHTML5 File API来提供进度条。以报告上传的进度。

    html5.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <html>
      <head>
        <title>My JSP 'html5.jsp' starting page</title>
        <script type="text/javascript">
        	var totalFileLength, totalUploaded, fileCount, filesUploaded ;
        	window.onload = function(){
        		document.getElementById("files").addEventListener('change', onFileSelect, false) ;
        		document.getElementById("uploadButton").addEventListener('click', startUpload, false) ;
        	}
        	function onFileSelect(e){
        		var files = e.target.files ;//FileList object
        		var output = [] ;
        		fileCount = files.length ;
        		totalFileLength = 0 ;
        		for( var i=0; i<fileCount; i++){
        			var file = files[i] ;
        			output.push(file.name, ' (', file.size, ' bytes, ',
        				file.lastModifiedDate.toLocaleDateString(), ')');
        			output.push("<br/>") ;
        			debug('add ' + file.size) ;
        			totalFileLength += file.size ;
        		}
        		document.getElementById("selectedFiles").innerHTML = output.join('') ;
        		debug('totalFileLength:' + totalFileLength) ;
        	}
        	function debug(s){
        		var debug = document.getElementById("debug") ;
        		if(debug){
        			debug.innerHTML = debug.innerHTML + '<br/>' + s ;
        		}
        	}
        	function startUpload(){
        		totalUploaded = filesUploaded = 0 ;
        		uploadNext() ;
        	}
        	function uploadNext(){
        		var xhr = new XMLHttpRequest() ;
        		var fd = new FormData() ;
        		var file = document.getElementById('files').files[filesUploaded] ;
        		fd.append("fileToUpload", file) ;
        		xhr.upload.addEventListener("progress", onUploadProgress, false) ;
        		xhr.addEventListener("load", onUploadComplete, false) ;
        		xhr.addEventListener("error", onUploadFailed, false) ;
        		xhr.open("POST", "multipleUploads") ;
        		debug("uploading " + file.name) ;
        		xhr.send(fd) ;
        	}
        	function onUploadProgress(e){
        		if(e.lengthComputable){
        			var percentComplete = parseInt(e.loaded + totalUploaded) * 100/totalFileLength ;
        			var bar = document.getElementById("bar") ;
        			bar.style.width = percentComplete + "%" ;
        			bar.innerHTML = percentComplete + " %complete" ;
        		}else{
        			debug("unable to compute") ;
        		}
        	}
        	function onUploadComplete(e){
        		totalUploaded += document.getElementById("files").files[filesUploaded].size ;
        		filesUploaded ++ ;
        		debug("complete " + filesUploaded + " of " + fileCount) ;
        		debug("totalUploaded: " + totalUploaded) ;
        		if(filesUploaded < fileCount){
        			uoloadNext() ;
        		}else{
        			alert("Finished uploading file(s)") ;
        		}
        	}
        	function onUploadFailed(e){
        		alert("Error uploading file") ;
        	}
        </script>
      </head>
      
      <body>
        <h1>Multiple file uploads with progress bar</h1>
        <div id="progressBar" style="height:20px;border:2px solid green">
        	<div id="bar" style="height:100%;background:#33dd33;0%">
        	</div>
        </div>
        <form id="form1" action="multipleUploads" enctype="multiple/form-data" method="post">
        	<input type="file" id="files" multiple/>
        	<br/>
        	<output id="selectedFiles"></output>
        	<input id="uploadButton" type="button" value="Upload"/>
        </form>
        <div id="debug" style="height:100px; border:2px solid green; overflow:auto"></div>
      </body>
    </html>
    


  • 相关阅读:
    SAP MM 启用批次管理的物料MB21创建预留单据时批次号可以为空!
    强化学习十大原则
    新手必看:生成对抗网络的初学者入门指导
    华为云总裁郑叶来:易获取、用得起、方便用的算力是人工智能发展的关键
    贝叶斯、香农、奥卡姆合写博客「机器学习是什么」
    诗人般的机器学习,ML工作原理大揭秘
    为什么AI的翻译水平还远不能和人类相比?
    2018-8-10-wpf-DoEvents-
    2018-2-13-win10-uwp-iot
    2019-9-11-.NET-Standard
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6800777.html
Copyright © 2011-2022 走看看