JavaEE-2020-05-文件上传

文件上传和服务器端存储

文件上传

上传文件到服务器上指定目录存储. 这里假定上传到web应用的上下文路径下的data文件夹.

网页端

提交上传文件的form. 其中,

  • action="UploadServlet"表示接收文件上传的servlet的URL是相对当前页面所在URL的UploadServlet.
  • method=“POST”. POST方式可以传二进制文件.
  • enctype=“multipart/form-data”. form提交的数据有多个部分. 服务器端要求传文件需要使用这个enctype.
<form action="UploadServlet" method="POST" enctype="multipart/form-data" >
  <input type="file" name="file1"/>
  <input type="submit" value="上传" />
</form>

服务器端

接收multipart的UploadServlet.

@WebServlet(name = "UploadServlet", urlPatterns = {"/UploadServlet"})
@MultipartConfig(location = "d:/upload/", fileSizeThreshold = 1000_000_000, maxFileSize = 1000_000_000, maxRequestSize = 2000_000_000)
public class UploadServlet extends HttpServlet {}

注解@MultipartConfig的参数

  • location是指定存储上传文件的默认实际目录, 也是上传文件的临时目录.

    • 建议练习时为location指定带有盘符的绝对路径. 如果没有盘符, 则是一个由tomcat启动配置的一个目录下的相对路径. 例如, location = "/upload/"可能代表路径C:\Users\subo1\AppData\Roaming\NetBeans\8.2\apache-tomcat-8.0.27.0_base\work\Catalina\localhost\JEE2020-05-fileUpload\upload
  • fileSizeThreshold用于当上传文件的字节数过大时, 用临时文件缓存, 减少占用过多内存. 即大于fileSizeThreshold时, 从内存写入临时文件.

  • maxFileSize是传输的多个文件中每个文件允许的最大字节数.

  • maxRequestSize是一次请求允许的最大字节数.

UploadServlet的方法processRequest()接收上传的多个文件, 然后写入location指定的本地目录.

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {    
    Collection<Part> parts = request.getParts();
    for (Part part : parts) {
        part.write(part.getSubmittedFileName());
    }
}

getParts()返回代表网页上传的各个文件. 对于每个文件, 用文件的原始名称, 写入location指定的本地目录.

  • getSubmittedFileName()获得文件在客户端上传时的原始文件名.
  • write()写入文件到指定的目录. 默认目录是location指定的本地目录.
getParts()

Gets all the Part components of this request, provided that it is of type multipart/form-data.

Part

This class represents a part or form item that was received within a multipart/form-data POST request.

文件上传的完整示例

浏览器端网页上传文件

网页uploadfile.html内容如下

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="GB18030">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <form action="upload" method="POST" enctype="multipart/form-data" >
            <input type="file" name="file1"/>
            <input type="submit" value="上传" />
        </form>
    </body>
</html>

服务器端Servlet接收保存文件

服务器端UploadServlet.java内容如下

import java.io.IOException;
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(name = "UploadServlet", urlPatterns = {"/upload"})
@MultipartConfig(location = "d:/upload/", fileSizeThreshold = 1000_000_000, maxFileSize = 1000_000_000, maxRequestSize = 2000_000_000)
public class UploadServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Collection<Part> parts = request.getParts();
        for (Part p : parts) {
            p.write(p.getSubmittedFileName());
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
}

运行结果

项目开始运行, 打开上传文件的URL

在这里插入图片描述

打开文件管理器, upload文件夹中是空的.

在这里插入图片描述

点击"选择文件", 选择一个文件.

在这里插入图片描述

点击上传. 打开文件管理器, upload文件夹中由上传完成的文件.

在这里插入图片描述

根据实际上传的文件, 显示内容可能不同.

上传图像并显示示例

创建上传文件的目录

找到当前项目的目录, 例如:

C:\Users\subo1\Documents\NetBeansProjects\JEE2020-05-fileUpload\

找到其中的Java Web项目运行的目录build\web\. 网页就存储在这个目录.

在其中创建目录jpg用于存储上传的jpg文件.

C:\Users\subo1\Documents\NetBeansProjects\JEE2020-05-fileUpload\build\web\jpg\

浏览器端网页

用于上传jpg文件并显示的网页文件uploadjpg.html内容如下

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="GB18030">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <form action="uploadjpg" method="POST" enctype="multipart/form-data" >
            <input type="file" name="file1"/>
            <input type="submit" value="上传" />
        </form>
        <br/>
        <img src="jpg/pic00.jpg" alt="upload a jpg"> 
    </body>
</html>

其中

<img src="jpg/pic00.jpg" alt="upload a jpg"> 

为在网页中添加一个图片, 其相对网页uploadjpg.html所在路径的文件名为: jpg/pic00.jpg.

服务器端Servlet

服务器端用于接收图片并存储为jpg/pic00.jpgUploadJpgServlet.java内容如下

import java.io.IOException;
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(name = "UploadJpgServlet", urlPatterns = {"/uploadjpg"})
@MultipartConfig(location = "d:/upload/", fileSizeThreshold = 1000_000_000, maxFileSize = 1000_000_000, maxRequestSize = 2000_000_000)
public class UploadJpgServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Collection<Part> parts = request.getParts();
        for (Part p : parts) {
            String realPath = this.getServletContext().getRealPath("/jpg/");
            p.write(realPath + "pic00.jpg");
        }
        request.getRequestDispatcher("uploadjpg.html").forward(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
}

运行结果

项目开始运行, 打开上传jpg文件的URL
在这里插入图片描述
点击"选择文件", 选择一个jpg文件.
在这里插入图片描述
点击"上传". 显示出我的blog截屏.

在这里插入图片描述

web项目中的目录

上传文件位置为web应用的上下文路径下的jpg文件夹. 注意, data文件夹的正确写法是"/jpg/". 如果写成jpg会找不到目录.

  • getRealPath(“jpg”)返回null
  • getRealPath(“jpg/”)返回null
  • getRealPath("/jpg/")返回
    • C:\Users\subo1\Documents\NetBeansProjects\JEE2020-05-fileUpload\build\web\jpg\
    • 对应的在实际文件系统中的目录 - 格式准确
    • 根据实际情况, "/jpg/"对应的在实际文件系统中的目录会, 有所不同.
  • getRealPath("/jpg")返回
    • C:\Users\subo1\Documents\NetBeansProjects\JEE2020-05-fileUpload\build\web\jpg
    • 注意末尾没有\, 会导致连接文件名时, 产生错误的文件名.
  • getRealPath("/")返回
    • C:\Users\subo1\Documents\NetBeansProjects\JEE2020-05-fileUpload\build\web\
    • 是web应用的上下文路径(context path)对应的在实际文件系统中的目录

NetBeans在运行tomcat时, 会使用NetBeans的默认目录. 例如项目JEE2020-05-fileUpload的默认上传位置

C:\Users\subo1\AppData\Roaming\NetBeans\8.2\apache-tomcat-8.0.27.0_base\work\Catalina\localhost\JEE2020-05-fileUpload

等价于

$CATALINA_BASE\work\Catalina\localhost\JEE2020-05-fileUpload

其中CATALINA_BASE是tomcat启动参数, 在此示例中为

C:\Users\subo1\AppData\Roaming\NetBeans\8.2\apache-tomcat-8.0.27.0_base"

附录: ContextPath与实际路径

getContextPath
String getContextPath()

Returns the context path of the web application.

The context path is the portion of the request URI that is used to select the context of the request. The context path always comes first in a request URI. If this context is the “default” context rooted at the base of the Web server’s URL name space, this path will be an empty string. Otherwise, if the context is not rooted at the root of the server’s name space, the path starts with a / character but does not end with a / character.

It is possible that a servlet container may match a context by more than one context path. In such cases the HttpServletRequest.getContextPath() will return the actual context path used by the request and it may differ from the path returned by this method. The context path returned by this method should be considered as the prime or preferred context path of the application.

  • Returns:

    The context path of the web application, or “” for the default (root) context

  • Since:

    Servlet 2.5

getRealPath
String getRealPath(String path)

Gets the real path corresponding to the given virtual path.

For example, if path is equal to /index.html, this method will return the absolute file path on the server’s filesystem to which a request of the form http://://index.html would be mapped, where `` corresponds to the context path of this ServletContext.

The real path returned will be in a form appropriate to the computer and operating system on which the servlet container is running, including the proper path separators.

Resources inside the /META-INF/resources directories of JAR files bundled in the application’s /WEB-INF/lib directory must be considered only if the container has unpacked them from their containing JAR file, in which case the path to the unpacked location must be returned.

This method returns null if the servlet container is unable to translate the given virtual path to a real path.

  • Parameters:

    path - the virtual path to be translated to a real path

  • Returns:

    the real path, or null if the translation cannot be performed


参考文献: https://docs.oracle.com/javaee/7/api/toc.htm

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值