JSP/Servlet --- 上传文件

本篇是servlet和jsp学习指南一书的示例代码加上自己理解,以及在写的过程中遇到的问题

servlet 4.0文档

javax.servlet.http.Part(Interface)

This class represents a part as uploaded to the server as part of a multipart/form-data request body. The part may represent either an uploaded file or form data.

自从servlet3.0开始就有了这个接口,该接口表示上传到服务器的multipart/form-data请求的主体部分。该部分可能是上传的文件或是表单数据

下面使用了write方法

void write(java.lang.String fileName)
    throws java.io.IOException

这是一种将上传的part写入磁盘的一种便捷方法。客户端代码并不关心该part是存储在内存中,还是在临时位置上的磁盘上。他们只是想把上传的部分写入文件。如果同一个part调用多次的write方法,则该方法不能保证成功。这允许特定的实现在可能的情况下使用文件重命名,而不是复制所有底层数据,从而获得显著的性能效益。(这句话不知道什么意思,猜测是可以通过进行文件重命名来赋值文件,而不是重新copy所有底层数据)

其中有个方法是servlet3.1新出的

java.lang.String getSubmittedFileName()
返回上传文件的名字,若不存在则返回null,所以这里需要进行判断

上传单个文件

uploadfile.jsp页面

<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<head>
<title>upload file</title>
</head>
<body>
	<!-- enctype规定在发送到服务器之前应该如何对表单数据进行编码 -->
	<!-- multipart/form-data不对字符编码,在使用包含文件上传控件的表单时,必须使用该值 -->
	<form method="post" action="/ServletModel/model/UploadServlet" enctype="multipart/form-data">
		作者: <input type="text" name="author"/><br/>
                选择文件:
		<input type="file" name="upload_file">
		<input type="submit" value="上传"/>
	</form>
        <br/>${hint}
</body>
</html>

UploadServlet.java,servlet

package com.xck.model.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(name="UploadServlet", urlPatterns={"/model/UploadServlet"})
//说明该Servlet处理的是multipart/form-data类型的请求,是Servlet3.0提供的对文件上传的支持
@MultipartConfig
public class UploadServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
		//Servlet3.0中新引入的方法,用来处理multipart/form-data类型编码的表单
		//可以用request.getPart("..")方法获得name为upload—_file的上传附件
		//多文件上传request.getParts(),然后通过循环分别处理每一个上传附件
		request.setCharacterEncoding("UTF-8");
		//通过html标签name属性值获取
                Part part = request.getPart("upload_file");
		String fileName = getFileName(part);
		if(fileName!=null && !fileName.isEmpty()){
                    String path = request.getServletContext().getRealPath("\\upload") + "\\" + fileName;
		    System.out.println(path);
		    part.write(path);
		    //响应 这里同样要设置编码
                    response.setContentType("text/html; charset=UTF-8");
                    PrintWriter writer = response.getWriter();
                    writer.print("<br/>Uploaded file name: " + fileName);
                    writer.print("<br/>file size: " + part.getSize());
                    String author = request.getParameter("author");
                    writer.print("<br/>author: " + author);
                }else{
                    request.setAttribute("hint", "上传失败,上传文件名或路径有问题");
                    //这里若没有加上/会跳转到 /model/uploadfile.jsp多了个model
                    request.getRequestDispatcher("/uploadfile.jsp").forward(request, response);
                }
	}
	
        /**
         * 获取上传的文体名
         * @param part
         * @return 上传文件名
         */
	private String getFileName(Part part){
		if(part == null){
			return null;
		}
		//Tomcat7下并没有getSubmittedFileName方法可以直接获取名字
		//上传文件请求头中会有content-disposition
		//获取请求头中的Content-Disposition,里面有表单信息,标签name属性值,filename上传文件的路径+文件名
		/*
		content-disposition example:
		
		form-data; name="upload_file"; 
		filename="D:\spring-framework-4.3.2.RELEASE-dist\spring-framework-4.3.2.RELEASE\libs\spring-webmvc-4.3.2.RELEASE-sources.jar"
		 */
		String contentDisposition = part.getHeader("Content-Disposition");
		String[] elements = contentDisposition.split(";"); //以分号作为分隔符
		for(String element : elements){
			if(element.trim().startsWith("filename")){
				//+1是为了跳过\,且字符串最后一个是引号,也要跳过,之前写的时候没注意,一直报错FileNoFound
				return element.substring(element.lastIndexOf("\\")+1, element.length()-1);
			}
		}
		return null;
	}
}
还可以限制文件上传的大小和类型等功能。。

猜你喜欢

转载自blog.csdn.net/qq_24986539/article/details/79392578