Jsp--文件上传upload

页面的设置:

  1. 必须使用表单,而不能是超链接;
  2. 表单的method必须是POST,而不能是GET;
  3. 表单的enctype必须是multipart/form-data(字符);默认值: application/x-www-form-urlencoded(字节)
  4. 在表单中添加file表单字段,即<input type=”file”…/>文件域
 <form action="${pageContext.request.contextPath }/FileUploadServlet"         
     method="post" enctype="multipart/form-data">
     用户名:<input type="text" name="username"/><br/>
     文件1:<input type="file" name="file1"/><br/>
     文件2:<input type="file" name="file2"/><br/>
     <input type="submit" value="提交"/>
 </form>

 后台的要求:

1、导入jar包commons-fileupload.jar,核心包;  commons-io.jar,依赖包。

2、request.getParameter(String)方法失效:获取指定的表单字段字符内容,

  但文件上传表单已经不在是字符内容,而是字节内容,所以失效

fileupload简单应用

fileupload的核心类有:DiskFileItemFactory、ServletFileUpload、FileItem

  1. 创建工厂类DiskFileItemFactory对象:DiskFileItemFactory factory = new DiskFileItemFactory()
  2. 使用工厂创建解析器对象:ServletFileUpload fileUpload = new ServletFileUpload(factory)
  3. 使用解析器来解析request对象:List<FileItem> list = fileUpload.parseRequest(request)

常用方法:

  • String getName():获取文件字段的文件名称***
  • String getString():获取字段的内容,如果是文件字段,那么获取的是文件内容,当然上传的文件必须是文本文件;
  • String getFieldName():获取字段名称,例如:<input type=”text” name=”username”/>,返回的是username;
  • String getContentType():获取上传的文件的类型,例如:text/plain。
  • int getSize():获取上传文件的大小;
  • boolean isFormField():判断当前表单字段是否为普通文本字段,如果返回false,说明是文件字段;
  • InputStream getInputStream():获取上传文件对应的输入流;
  • void write(File):把上传的文件保存到指定文件中

上传文件的细节处理

1、把上传的文件放到WEB-INF目录下

  如果没有把用户上传的文件存放到WEB-INF目录下,那么用户就可以通过浏览器直接访问上传的文件,这是非常危险的。

通常我们会在WEB-INF目录下创建一个uploads目录来存放上传的文件,而在Servlet中找到这个目录需要使用ServletContext的getRealPath(String)方法,例如在我的upload1项目中有如下语句:

ServletContext servletContext = this.getServletContext();

String savepath = servletContext.getRealPath(“/WEB-INF/uploads”);

 其中savepath为:F:\tomcat6_1\webapps\upload1\WEB-INF\uploads。

2、中文乱码问题

  fileItem.getString(“utf-8”)来处理编码

3、上传文件同名问题

  当前毫秒值

//得到上传文件的文件名
String fileName = fileItem.getName();
//得到后缀名
String subfix =  fileName.substring(fileName.lastIndexOf("."));
//获取当前毫秒值
long timer = new Date().getTime();
//写入文件
fileItem.write(new File(savePath+"/"+timer+subfix));

  使用UUID

//定义文件夹位置
String savePath = "d:/upload/";
//使用uuid随机保存文件名(去除中间的-,全部变为大写)
String fileName = UUID.randomUUID().toString()
                            .replace("-","").toUpperCase();                                
//后缀名
String uploadFileName = fileItem.getName();
String sufix = uploadFileName.substring(uploadFileName.lastIndexOf("."));
//写入文件
fileItem.write(new File(savePath+fileName+sufix));

4、上传的单个文件的大小限制

  ServletFileUpload类的setFileSizeMax(long)

FileUpload.setFileSizeMax(1024*10)表示上限为10KB(推荐)

上传的文件超出了上限,那么就会抛出FileUploadBase.FileSizeLimitExceededException异常
if(e instanceof FileUploadBase.FileSizeLimitExceededException) {
             // 在request中保存错误信息
request.setAttribute("msg", "上传失败!上传的文件超出了10KB!");

总大小限制fileUpload.setSizeMax(1024 * 10);(不推荐)

 代码:

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { //1.创建工厂对象 DiskFileItemFactory factory = new DiskFileItemFactory(); //2.由工厂对象得到ServletFileUpload对象 ServletFileUpload fileUpload = new ServletFileUpload(factory); //限制上传文件大小 //fileUpload.setFileSizeMax(300*1024); //3.解析request对象 try { List<FileItem> fileItems = fileUpload.parseRequest(request); //4.遍历List集合 for (FileItem fileItem : fileItems) { //判断fileItem是否是一个文件域 //boolean isFormField() true 不是一个文件域 false 是一个文件域 if(fileItem.isFormField()){ // 不是一个文件域 //获取input的name getFieldName() String name = fileItem.getFieldName(); //获取input的value getString(编码) String value = fileItem.getString("UTF-8"); }else{//文件域表单

将文件保存到服务器硬盘、在WebContent创建一个upload目录(服务器重启数据丢失)

}else{//文件域表单
    //保存到服务器硬盘
    //1)保存到项目发布的目录
    //a.得到上传文件的文件名  getName()    xxx.jpg
    String fileName = fileItem.getName();
    //得到后缀名
    String subfix =  fileName.substring(fileName.lastIndexOf("."));
    if(".jpg".equals(subfix) || ".png".equals(subfix) || ".gif".equals(subfix)){
        //b.把文件保存到硬盘    FileItem# void    write(java.io.File file)
        //File对象对应的文件, 不能是文件夹
        //ServletConfig
        // 这个项目发布的文件夹的路径, 通过ServletContext对象的getRealPath()
        String savePath = this.getServletContext().getRealPath("/upload");
        // 取文件名两种策略:  1)  当前系统的毫秒值
        long timer = new Date().getTime();
        fileItem.write(new File(savePath+"/"+timer+subfix));
        
    }else{
    }

将文件保存到硬盘任意的目录(推荐)

String savePath = "d:/upload/";
//使用uuid随机保存文件名
String fileName = UUID.randomUUID().toString()
            .replace("-","").toUpperCase();
//后缀名
String uploadFileName = fileItem.getName();
String sufix = uploadFileName.substring(uploadFileName.lastIndexOf("."));

//写入服务器硬盘目录
fileItem.write(new File(savePath+fileName+sufix));

数据库中保存文件名,(当前毫秒值/UUID+后缀名)

页面展示图片数据

 <img src="/img/ ${photoPath} " />

D:\tomcat\apache-tomcat-7.0.82\webapps\les18   -->    /les18     映射
   /项目名      对服务器硬盘某个路径的映射

/img  -->d:upload    (eclipse  配置虚拟的文件路径)

1、

 2、 

 其他开发工具需要自己手动添加

 <Context docBase="D:\upload" path="/img" reloadable="true"/></Host>

添加数据包含头像的servlet代码

protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        //1、创建工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //2、通过工厂对象创建servletFileUpload对象,上传对象
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        //3、解析request对象FileItem
        List<FileItem> fileItems;
        try {        
            fileItems = fileUpload.parseRequest(request);
            //创建一个客户对象
            Client c = new Client();
            for (FileItem fileItem : fileItems) {
                if(fileItem.isFormField()){
                    //返回true表示非文件域,获取value值
                    if("cname".equals(fileItem.getFieldName())){
                        c.setCname(fileItem.getString("UTF-8"));
                    }
                    if("gender".equals(fileItem.getFieldName())){
                        c.setGender(fileItem.getString("UTF-8"));
                    }
                    if("birthday".equals(fileItem.getFieldName())){
                        c.setBirthday(fileItem.getString("UTF-8"));
                    }
                    if("cellphone".equals(fileItem.getFieldName())){
                        c.setCellphone(fileItem.getString("UTF-8"));
                    }
                    if("email".equals(fileItem.getFieldName())){
                        c.setEmail(fileItem.getString("UTF-8"));
                    }
                    if("description".equals(fileItem.getFieldName())){
                        c.setDescription(fileItem.getString("UTF-8"));
                    }
                }else{
                    //false表示保存文件域
                    //保存文件
                    String savePath = "d:/upload/";
                    //使用uuid随机保存文件名
                    String fileName = UUID.randomUUID().toString()
                                                    .replace("-","")
                                                    .toUpperCase();
                    //后缀名
                    String uploadFileName = fileItem.getName();
                    String sufix = uploadFileName.substring(uploadFileName.lastIndexOf("."));
                    //写入服务器硬盘目录
                    fileItem.write(new File(savePath+fileName+sufix));
                    //给Client对象的photopath属性赋值,文件名
                    c.setPhotoPath(fileName+sufix);
                }
            }
            
            //调用业务层获取数据
            ClientService cs = new ClientServiceImpl();
            boolean b = cs.insert(c);
            if(b){
                request.setAttribute("msg", "添加成功");
            }else{
                request.setAttribute("msg", "添加失败");
            }
            //转发执行结果页面
            request.getRequestDispatcher("/msg.jsp").forward(request, response);
            
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
View Code

页面显示代码

<td>
     <img src="
     <c:choose>
<c:when test="${empty client.photoPath }">./images/photo.jpg</c:when>
<c:otherwise>/img/${client.photoPath}</c:otherwise>
    </c:choose>
      " width="60" height="60" />
</td>
View Code

 

posted @ 2020-05-20 20:23  64Byte  阅读(475)  评论(0编辑  收藏  举报