Web---文件上传-用apache的工具处理、打散目录、简单文件上传进度(2)

简介: Web---文件上传-用apache的工具处理、打散目录、简单文件上传进度

上传二个file项


index.jsp:


<!-- 下面那个=号,代表整个输出request.getContextPath()的值   -->
    <form action="<%= request.getContextPath() %>/upload" method="post" enctype="multipart/form-data">
        文件1:<input type="file" name="file"/><br/>
        文件1的说明:<input type="text" name="desc1"/><br/> 
        文件2:<input type="file" name="file2"/><br/>
        文件2的说明:<input type="text" name="desc2"/><br/>
        <input type="submit" value="提交"/>
    </form>

其他的相对前面的都没改动~

演示结果:

image.png

image.png

image.png

上传文件最终版:

index.jsp:

<h2>进一步演示文件上传用法</h2>
    <form action="<%= request.getContextPath() %>/upload2" method="post" enctype="multipart/form-data">
        文件1:<input type="file" name="file"/><br/>
        文件1的说明:<input type="text" name="desc1"/><br/>
        文件2:<input type="file" name="file2"/><br/>
        文件2的说明:<input type="text" name="desc2"/><br/>
        <input type="submit" value="提交"/>
    </form>

web.xml:


<servlet>
    <servlet-name>UploadServlet2</servlet-name>
    <servlet-class>cn.hncu.servlets.upload.UploadServlet2</servlet-class>
  </servlet>
<servlet-mapping>
    <servlet-name>UploadServlet2</servlet-name>
    <url-pattern>/upload2</url-pattern>
  </servlet-mapping>


UploadServlet2.java:

package cn.hncu.servlets.upload;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class UploadServlet2 extends HttpServlet {
    //防黑1---在地址栏直接提交的-我们要防住
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("不支持GET方式上传!!!");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        final PrintWriter out = response.getWriter();//等会内部类需要用到这个变量,所以定义成final
        //防黑2--非multipart表单提交
        //手动方式
        String type = request.getContentType();
        if(!type.contains("multipart/form-data")){//如果此字符串包含 s,则返回 true,否则返回 false 
            out.print("不支持普通表单提交");
            return;
        }
        DiskFileItemFactory fiFactory = new DiskFileItemFactory();
        fiFactory.setSizeThreshold(1024*8);//8k,缓存区大小
        File file = new File("d:/a");
        if(!file.exists()){
            file.mkdir();
        }
        fiFactory.setRepository(file);//设置缓存区
        /*
         ServletFileUpload类是Apache文件上传组件处理文件上传的核心高级类(所谓高级就是不需要管底层实现,暴露给用户的简单易用的接口)。
         使用其 parseRequest(HttpServletRequest) 方法可以将通过表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回。
         */
        ServletFileUpload upload = new ServletFileUpload(fiFactory);
        upload.setHeaderEncoding("utf-8");//用于设置文件名的编码,相当于:request.setCharacterEncoding("utf-8");
        String path = getServletContext().getRealPath("/imgs");
        //文件上传进度功能---设置监听器
        upload.setProgressListener(new ProgressListener() {
            private int pre=0;
            //参数解析---pBytesRead:已上传字节数 pContentLength:上传的总字节数 pItems:文件序号(从1开始的)
            @Override
            public void update(long pBytesRead, long pContentLength, int pItems) {
                double d = pBytesRead*100.0/pContentLength;//计算百分比
                int dd = (int)d;
                if(pre!=dd){//防范输出一样的百分比
                    out.print(dd+"%<br/>");
                    pre=dd;
                }
            }
        });
        FileItem fi=null;
        try {
            List<FileItem> list = upload.parseRequest(request);
            for(FileItem fi2:list){
                fi=fi2;//相当于传指针,同一个对象
                if(fi.isFormField()){//普通表单组件
                    String str = fi.getString("utf-8");
                    System.out.println("普通表单组件提交的内容:"+str);
                }else{//表单中的:file组件
                    //防黑3--在file组件中不选择文件
                    if(fi.getSize()==0){
                        continue;
                    }
                    //文件名
                    String fileName = fi.getName();
                    fileName = fileName.substring( fileName.lastIndexOf("\\")+1 );//这里就是文件名(后缀名也在的)
                    String ext = fileName.substring( fileName.lastIndexOf(".") );// .*  后缀名
                    //文件名不能用中文,必须转换成ascii码的格式,而且文件名不能重复(必须保证唯一),因此采用UUID来实现
                    String newFileName = UUID.randomUUID().toString().replace("-", "");//去掉'-'
                    newFileName = newFileName+ext;
                    //打散目录(因为对于普通的机器,一个文件夹如果存储的文件个数超过1000个,性能就会急剧下降!!!)、
                    String dir1 = Integer.toHexString( fileName.hashCode() & 0xf );
                    String dir2 = Integer.toHexString( (fileName.hashCode() & 0xf0)>>4 );//右移四位
                    String dir3 = Integer.toHexString( ( fileName.hashCode() & 0xf00 )>>8);
                    File dir = new File(path+"/"+dir1+"/"+dir2+"/"+dir3);//16*16*16个文件夹
                    if(!dir.exists()){
                        dir.mkdirs();
                    }
                    File f = new File(dir+"/"+newFileName);
                    fi.write(f);
                }
            }
        }catch (FileUploadException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally{
            if(fi!=null){
                fi.delete();//清临时文件
            }
        }
    }
}

演示结果:

进行了一个文字型的文件上传进度,没办法啊,现在还没学AJax,做不了同步~~理解理解,后面会学到的。

image.png

image.png

注意看文件的保存目录!!!!(0-f)16进制的文件名~

我做了三层~

image.png

image.png

目录
相关文章
|
11天前
|
安全 搜索推荐 应用服务中间件
Web安全-目录遍历漏洞
Web安全-目录遍历漏洞
17 2
|
15天前
|
开发框架 安全 .NET
Web安全-文件上传漏洞与WAF绕过
Web安全-文件上传漏洞与WAF绕过
22 4
|
18天前
|
机器学习/深度学习 算法 开发工具
Python Web开发工具
Python Web开发工具
17 3
|
24天前
|
安全 前端开发 JavaScript
Web安全-网页开发者工具
Web安全-网页开发者工具
38 7
|
1月前
|
Java API Apache
从零到英雄的蜕变:如何用Apache Wicket打造你的第一个Web应用——不仅是教程,更是编程之旅的启航
【9月更文挑战第4天】学习Apache Wicket这一开源Java Web应用框架是一段激动人心的旅程。本文将指导你通过Maven搭建环境,并创建首个“Hello, World!”应用。从配置`pom.xml`到实现`HelloWorldApplication`类,再到`web.xml`的设置,一步步教你构建与部署简单网页。适合初学者快速上手,体验其简洁API与强大组件化设计的魅力。
23 1
|
2月前
|
测试技术
基于LangChain手工测试用例转Web自动化测试生成工具
该方案探索了利用大模型自动生成Web自动化测试用例的方法,替代传统的手动编写或录制方式。通过清晰定义功能测试步骤,结合LangChain的Agent和工具包,实现了从功能测试到自动化测试的转换,极大提升了效率。不仅减少了人工干预,还提高了测试用例的可维护性和实用性。
44 4
|
2月前
|
前端开发 安全 开发者
JSF文件上传,让Web应用如虎添翼!一招实现文件上传,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,文件上传是重要功能之一。JSF(JavaServer Faces)框架提供了强大的文件上传支持,简化了开发流程。本文将介绍JSF文件上传的基本步骤:创建前端表单、处理上传文件的后端Action类、将文件保存到服务器指定目录以及返回结果页面。通过示例代码,我们将展示如何利用JSF实现文件上传功能,包括使用`h:inputFile`控件和`ManagedBean`处理上传逻辑。此外,JSF文件上传还具备类型安全、解耦合和灵活性等优点,有助于提升程序的健壮性和可维护性。
27 0
|
2月前
|
Java Spring Apache
Spring Boot邂逅Apache Wicket:一次意想不到的完美邂逅,竟让Web开发变得如此简单?
【8月更文挑战第31天】Apache Wicket与Spring Boot的集成提供了近乎无缝的开发体验。Wicket以其简洁的API和强大的组件化设计著称,而Spring Boot则以开箱即用的便捷性赢得开发者青睐。本文将指导你如何在Spring Boot项目中引入Wicket,通过简单的步骤完成集成配置。首先,创建一个新的Spring Boot项目并在`pom.xml`中添加Wicket相关依赖。
58 0
|
2月前
|
Apache 开发者 Java
Apache Wicket揭秘:如何巧妙利用模型与表单机制,实现Web应用高效开发?
【8月更文挑战第31天】本文深入探讨了Apache Wicket的模型与表单处理机制。Wicket作为一个组件化的Java Web框架,提供了多种模型实现,如CompoundPropertyModel等,充当组件与数据间的桥梁。文章通过示例介绍了模型创建及使用方法,并详细讲解了表单组件、提交处理及验证机制,帮助开发者更好地理解如何利用Wicket构建高效、易维护的Web应用程序。
25 0
|
2月前
|
Java 前端开发 Apache
Apache Wicket与Spring MVC等Java Web框架大PK,究竟谁才是你的最佳拍档?点击揭秘!
【8月更文挑战第31天】在Java Web开发领域,众多框架各具特色。Apache Wicket以组件化开发和易用性脱颖而出,提高了代码的可维护性和可读性。相比之下,Spring MVC拥有强大的生态系统,但学习曲线较陡;JSF与Java EE紧密集成,但在性能和灵活性上略逊一筹;Struts2虽成熟,但在RESTful API支持上不足。选择框架时还需考虑社区支持和文档完善程度。希望本文能帮助开发者找到最适合自己的框架。
31 0

推荐镜像

更多
下一篇
无影云桌面