JAVA EE-文件上传
来源:互联网 发布:安卓开发java基础 编辑:程序博客网 时间:2024/05/17 15:03
JAVA EE-文件上传
应该相信,自己是生活的战胜者。 —— 雨果
文件下载
首先我们复习一下文件下载的内容
静态下载
public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1 准备工作 //设置content-type response.setContentType(getServletContext().getMimeType("xxx.zip")); //添加响应头 content-disposition response.setHeader("Content-Disposition", "attachment;filename=apache-tomcat-6.0.35.zip"); //2 获得输入流 InputStream is = getServletContext().getResourceAsStream("/WEB-INF/apache-tomcat-6.0.35.zip"); //3 获得输出流 OutputStream os = response.getOutputStream(); //4 两个流对接 IOUtils.copy(is, os); }}
根据用户的选择来获取下载
JSP文件:
<body> <a href="/day12-download/AServlet" >点击下载</a><br> <a href="/day12-download/BServlet?name=apache-tomcat-6.0.35.zip" >apache-tomcat-6.0.35.zip</a><br> <a href="/day12-download/BServlet?name=激活软件_v10.0.0.exe" >激活软件_v10.0.0.exe</a><br> </body>
业务处理的Servlet
public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1 获得参数,拿到用户需要下载的文件名称 String fileName = request.getParameter("name"); fileName = new String(fileName.getBytes("ISO-8859-1"),"UTF-8"); //2 准备工作 //设置content-type response.setContentType(getServletContext().getMimeType(fileName)); //添加响应头 content-disposition response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8")); //2 获得输入流 InputStream is = getServletContext().getResourceAsStream("/WEB-INF/"+fileName); //3 获得输出流 OutputStream os = response.getOutputStream(); //4 两个流对接 IOUtils.copy(is, os); //关闭输出流 is.close(); os.close(); }}
下载的乱码问题
客户端的超连接中如果包含了中文,会出现get请求方式乱码问题
<a href="${pageContext.request.contextPath}/download?filename=天空.mp3">下载王非天空.mp3</a> String filename = request.getParameter("name"); // yog.rar / 她说.mp3 byte[] b = filename.getBytes("ISO-8859-1"); filename = new String(b,"UTF-8"); 实际上Get提交时包含中文乱码的解决。
如果下载文件名称中出现了中文乱码问题
<a href="${pageContext.request.contextPath}/download?filename=天空.mp3">下载王非天空.mp3</a> String filename = request.getParameter("name"); // yog.rar / 她说.mp3 byte[] b = filename.getBytes("ISO-8859-1"); filename = new String(b,"UTF-8"); 实际上Get提交时包含中文乱码的解决。
文件上传
为什么使用文件上传?
- 例如社交网站需要提供用户照片.
- 很多企业内部,商品网站维护时需要上传一些文件
- 邮箱需要上传附件….
文件上传的操作
- 请求方式必须是post
- 需要使用组件
- 表单必须设置encType=”multipart/form-data”
- 上传文件的input 中,name属性必须要填写,不然不会上传.
这样一来,通过request对象,获取InputStream,可以将浏览器提交的所有请求正文读取到.
文件上传需要的插件
commons-fileupload 它是常用的一个文件上传工具 使用时要导入两个jar包 commons-fileupload-1.2.1.jar commons-io-1.4.jar
一个上传的浏览器端代码
<body> <!-- 1.文件上传,表单必须是post提交 2.文件上传,还需要在表单上加上enctype属性(提交请求正文的类型) *application/x-www-form-urlencoded(默认取值,普通提交) *multipart/form-data(多段式提交) 3. 文件上传,使用<input type="file" name="photo" /> 标签,并且必须有name属性 --> <form action="/day12-upload/BServlet" method="post" encType="multipart/form-data" > 用户名:<input type="text" name="name" /><br> 个人近照:<input type="file" name="photo" /><br> <input type="submit" value="上传" /> </form> </body>
下面演示如何使用第三方的jar包来优化文件上传处理
public class BServlet extends HttpServlet { //使用文件上传工具类(第三方) // 导包 => commons-fileupload-1.2.1.jar // => commons-io-1.4.jar public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1 创建配置工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //2 根据配置工厂创建解析请求中文件上传内容的解析器 ServletFileUpload upload = new ServletFileUpload(factory); //3 判断当前请求是否是多段式提交 if(!upload.isMultipartContent(request)){ //普通表单提交 throw new RuntimeException("不是多段式提交!"); } try { //4 解析request对象 List<FileItem> list = upload.parseRequest(request); if(list!=null){ for(FileItem item : list){ //判断当前上传段是普通字段,还是文件上传 if(!item.isFormField()){//文件上传段 String fName = item.getFieldName(); InputStream is = item.getInputStream();//获得文件上传段中,文件的流 FileOutputStream fos = new FileOutputStream("d://upload/xxx.jpg"); IOUtils.copy(is, fos); fos.close(); }else{//普通字段段 String name = item.getFieldName(); String value = item.getString(); System.out.println(name+"==>"+value); } } } } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
文件上传段与普通表单段的区别如下
fileupload工具类详解
public class CServlet extends HttpServlet { //fileupload 工具类使用详解 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1 创建配置工厂=> 有参的构造可以 直接设置下面两个配置 DiskFileItemFactory factory = new DiskFileItemFactory(); //1.1 设置文件上传临时目录 => 默认位置 => tomcat/temp factory.setRepository(new File("d:/temp")); //1.2 设置文件写入硬盘的缓冲区大小=>默认值=>10k factory.setSizeThreshold(10240); //2 根据配置工厂创建解析器(解析request对象) ServletFileUpload upload = new ServletFileUpload(factory); //2.1 判断当前请求是否是多段式提交 upload.isMultipartContent(request); //2.2 设置多段中每段 段头 在解析时,使用什么码表解码 => 当段头中出现中文时,一定要调用该方式指定段头码表 upload.setHeaderEncoding("UTF-8"); //2.3 设置文件最大上传大小 (单位:字节) upload.setSizeMax(1024*1024*10); //单次请求,总上传大小限制 10兆 upload.setFileSizeMax(1024*1024);// 每个文件上传段,大小限制 1兆 List<FileItem> list = null; try { //2.4 解析request,将每个分段中的内容封装到FileItem中 list = upload.parseRequest(request); } catch (FileUploadException e) { e.printStackTrace(); } if(list!=null){ for(FileItem item : list){ //3.1 item 判断当前分段是否是普通表单段 boolean flag = item.isFormField(); //普通段 //3.2获得 表单提交的键.(input元素,name属性的值) String fname = item.getFieldName(); //3.3 返回文件名称 String name = item.getName(); //3.4 获得文件上传中的正文 //item.getInputStream(); //3.5 以字符串形式返回段体中的内容 注意:文件上传段不建议使用该方法. String content= item.getString(); //3.6 删除上传的临时文件 item.delete(); System.out.println("是否是普通表单提交:"+flag+",表单提交的键:"+fname+",文件名称:"+name+",文件内容:"+content); } } }}
关于乱码问题的研究
当上传的文件名中有中文时,如果码表不当就会造成乱码问题的产生。
public class DServlet extends HttpServlet { //上传文件名称是中文,乱码问题 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1 创建配置工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //2 根据配置工厂创建解析请求中文件上传内容的解析器 ServletFileUpload upload = new ServletFileUpload(factory); //解决文件名称中文乱码 upload.setHeaderEncoding("UTF-8"); //3 判断当前请求是否是多段式提交 if(!upload.isMultipartContent(request)){ //普通表单提交 throw new RuntimeException("不是多段式提交!"); } try { //4 解析request对象 List<FileItem> list = upload.parseRequest(request); if(list!=null){ for(FileItem item : list){ //判断当前上传段是普通字段,还是文件上传 if(!item.isFormField()){//文件上传段 String fileName = item.getName(); System.out.println(fileName); } } } } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
设置上传文件的最大大小
public class FServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1 创建配置工厂 DiskFileItemFactory factory = new DiskFileItemFactory();//2 根据配置工厂创建解析请求中文件上传内容的解析器 ServletFileUpload upload = new ServletFileUpload(factory); //设置文件上传大小限制 upload.setFileSizeMax(1024); try { upload.parseRequest(request); } catch (FileUploadException e) { e.printStackTrace(); throw new RuntimeException("文件大小不能超过1kb!"); }}}
可以设置上传文件大小,如果超过设置大小.将会抛出异常(默认没有最大值) void setFileSizeMax(long fileSizeMax) 设置单个文件上传大小 void setSizeMax(long sizeMax) 设置总文件上传大小
如何实现保存的文件名不会重复
public class GServlet extends HttpServlet { //如果将文件全部保存 => 保证文件名称不能重复 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1 创建配置工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //2 根据配置工厂创建解析请求中文件上传内容的解析器 ServletFileUpload upload = new ServletFileUpload(factory); //3 判断当前请求是否是多段式提交 if(!upload.isMultipartContent(request)){ //普通表单提交 throw new RuntimeException("不是多段式提交!"); } try { //4 解析request对象 List<FileItem> list = upload.parseRequest(request); if(list!=null){ for(FileItem item : list){ //判断当前上传段是普通字段,还是文件上传 if(!item.isFormField()){//文件上传段 String fName = item.getFieldName(); InputStream is = item.getInputStream();//获得文件上传段中,文件的流 //保存之前,生成文件名称( 保证永远不重复) //生成随机字符串即可 String fileName = UUID.randomUUID().toString(); FileOutputStream fos = new FileOutputStream("d:/upload/"+fileName); IOUtils.copy(is, fos); fos.close(); } } } } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
如何防止同一个目录之下上传文件数量过多?
public class HServlet extends HttpServlet { //如何将上传文件分目录保存 // 使用登录用户的用户名 来创建不同的文件夹. 每个用户上传的文件就放到自己的文件夹中 // 按照日期分目录=> d:/upload/2015/08/24/ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1 创建配置工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //2 根据配置工厂创建解析请求中文件上传内容的解析器 ServletFileUpload upload = new ServletFileUpload(factory); //3 判断当前请求是否是多段式提交 if(!upload.isMultipartContent(request)){ //普通表单提交 throw new RuntimeException("不是多段式提交!"); } try { //4 解析request对象 List<FileItem> list = upload.parseRequest(request); if(list!=null){ for(FileItem item : list){ //判断当前上传段是普通字段,还是文件上传 if(!item.isFormField()){//文件上传段 String fName = item.getFieldName(); InputStream is = item.getInputStream();//获得文件上传段中,文件的流 // 生成日期目录 //1 获得当前日期=>目录结构 的 路径 SimpleDateFormat format = new SimpleDateFormat("/yyyy/MM/dd/"); String datepath = format.format( new Date()); // /2015/08/24/ //拼接完整保存目录路径 String wholePath = "d:/upload"+datepath;// d:/upload/2015/08/24/ //确保文件夹存在 File directory = new File(wholePath); if(!directory.exists()){//如果文件夹结构不存在 directory.mkdirs(); //创建文件夹结构 } //保存之前,生成文件名称( 保证永远不重复) //生成随机字符串即可 String fileName = UUID.randomUUID().toString(); FileOutputStream fos = new FileOutputStream(wholePath+fileName); IOUtils.copy(is, fos); fos.close(); } } } } catch (FileUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
0 0
- Java EE文件上传
- JAVA EE-文件上传
- <JAVA EE>文件上传
- java ee简单文件上传
- Java EE - Spring MVC 文件上传
- JAVA EE项目常用之 struts1.2 文件上传的两种方法
- 【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【控制文件上传和下载】
- java EE中读取properties文件
- Java EE
- java EE
- Java EE
- Java EE
- java-ee
- java ee
- java EE
- Java EE
- Java EE
- JAVA EE
- The Suspects poj1611(并查集的深度理解) 16.9.21
- 生成36位全局唯一数(GUID、UUID)
- n皇后问题
- 4种PHP异步执行的常用方式
- Could not Create the Java Virtual Machine or Unhandled Event Loop Exception
- JAVA EE-文件上传
- 按键事件
- V尼熊的java之旅——面向对象篇
- poj 1275 Cashier Employment
- 2016华为上机题:计算下一秒
- apt-get 机制详解
- hdu4802(stl)
- Android异步下载网络图片(其一:Handler)
- 3.25