在之前的章节中,我们介绍了客户端浏览器向服务器端发起get/post请求,但是这些请求数据还局限在“文本”字符串形式。如果我们需要向服务器端提交文件,例如一张图片,该如何处理?很早之前,处理文件上传需要借助第三方组件,例如commons fileupload等等。但是,在Servlet 3.0之后提供了@MultipartConfig注解和Request.getPart方法,可以方便的处理文件上传。
接下来,我们创建“FileDemo”工程演示如何进行图片的上传。如何创建JavaWeb工程请查看前几章节的内容。工程创建完毕后,我们创建UploadServlet类,对应的请求映射为“/upload”,如下所示
接下来,我们修改UploadServlet类的doGet方法
// 得到文件对象,参数为<input type="file">的name属性值
Part part = request.getPart("img_file");
// 获取文件全名称,包含文件类型后缀
// 请求头的格式:form-data; name="file"; filename="html.png"
String header = part.getHeader("content-disposition");
String[] tempArr1 = header.split(";");
String[] tempArr2 = tempArr1[2].split("=");
String realName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\")+1).replaceAll("\"", "");
System.out.println("文件名称:" + realName);
// 获取 WebContent 绝对路径
String realPath = request.getServletContext().getRealPath("/");
System.out.println("WebContent路径:" + realPath);
// 文件保存全路径
part.write(realPath + realName);
// 返回图片地址
String webPath = request.getContextPath() + "/" + realName;
request.setAttribute("imgAddress", webPath);
request.getRequestDispatcher("/upload.jsp").forward(request, response);
上述代码我们简单介绍一下。首先,前端页面需要使用“<input type="file" name="img_file">”进行文件上传,后端使用“Part part = request.getPart("img_file");”就可以获取文件对象,其中getPart方法的参数就是“<input type="file"”标签的name属性。接下来,我们获取上传文件的真正名称realName。这里我们要上传一个名称为“html.png”的图片,因此这里获取的realName就是“html.png”。接下来,我们需要将图片保存到WebContent根目录下,所以我们需要获取该目录的绝对路径realPath。有了realPath绝对路径和realName图片名称,我们就可以将其保存了。最后,我们要返回上传图片的Web访问路径,也就是webPath。
接下来,我们创建“index.jsp”文件,代码如下
<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
<p>上传图片:<input type="file" name="img_file"></p>
<p><input type="submit" value="上传"></p>
</form>
接下来,就是图片文件上传成功后的显示页面“upload.jsp”
<img src="${requestScope.imgAddress}" />
我们运行项目,
点击“选择文件”按钮,选择我们的“html.png”图片文件
点击“上传”按钮
正确显示我们上传的图片,访问地址为:/FileDemo/html.png
我们在Eclipse中查看控制台
我们之前介绍过,Eclipse下的项目运行目录是在工作空间下的“.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps”目录。这里打印出了它的完整路径是“E:\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FileDemo”。我们去这个目录下查看一下。
这里我们说明一下图片保存路径的问题。我们为什么要将其保存到WebContent根目录下,因为这个目录是对用户访问时开放的。也就是说,我们将“html.png”放置在WebContent根目录下后,就可以通过“http://localhost:8080/FileDemo/html.png”访问到这张图片。
我们还可以在WebContent下创建一个“images”目录,然后将图片保存到这里。那么我们访问的地址就是“http://localhost:8080/FileDemo/images/html.png”,这个也没有问题。但是,如果我们将图片保存到“WEB-INF”下,我们就不能通过“http://localhost:8080/FileDemo/WEB-INF/html.png”访问到了,因为“WEB-INF”目录是受保护的,不允许用户直接访问。或者说,我们干脆将图片保存到Tomcat之外的目录,那么用户就更无法直接访问了。注意,我只的是“直接访问”,而不是无法访问。因为,有时候,我们需要对文件做权限限制,允许部分身份的用户可以访问,其他则不行。显然这种情况下,我们不可以将图片直接保存到WebContent根目录下或其子目录下。那怎么办呢?很简单,用户不能直接访问,但是我们可以通过java代码读取并返回给用户啊。
接下来,我们将“html.png”放置到“WEB-INF”下,
我们无法通过“http://localhost:8080/FileDemo/WEB-INF/html.png”访问到它。
但是它的确存在于“WEB-INF”目录
接下来,我们创建DownloadServlet类,对应的请求映射为“/download”
接下来,我们直接修改DownloadServlet类的doGet方法
// 获取图片流
InputStream in = getServletContext().getResourceAsStream("/WEB-INF/html.png");
// 图片响应头信息
response.setContentType("image/png");
// 输入文件内容(二进制)
OutputStream out = response.getOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while((len = in.read(buffer)) != -1){
out.write(buffer, 0, len);
}
in.close();
out.close();
代码中给出了一部分注释,其实就是读取文件内容,以“流”的形式返回给客户端浏览器。但是,需要大家注意的是,我们需要指定返回客户端的内容类型为“image/png”图片格式。
接下来,我们就可以直接使用“http://localhost:8080/FileDemo/download”访问图片了。
由于是代码控制图片文件的输出,因此我们可以增加自己的业务逻辑代码,控制用户是否有权访问这张图片。关于图片的上传和下载就简单介绍到这里了。
标签:文件,07,html,png,上传,我们,下载,图片 From: https://blog.csdn.net/richieandndsc/article/details/137408107