servlet文件上传与下载

您所在的位置:网站首页 servlet上传下载 servlet文件上传与下载

servlet文件上传与下载

#servlet文件上传与下载| 来源: 网络整理| 查看: 265

文件上传:     RFC1867协议的请求与响应的特点:

                   通过浏览器上传文件给服务器,与正常的访问不同,用户通过浏览器给服务器发送的比较复杂,而向浏览器返回的信息

            可能是简单的信息,为了规范通过浏览器上传文件到服务器的行为,就设计了一个RFC1867协议,约定上传文件所需要尊守

            的规则。

   文件上传的本质:

           从客户端复制文件到服务端指定目录下面的过程

   文件上传表单三要素:

           1,使用post方式提交表单

           2,为上传表单的每个表单项添加name属性,便于服务器收集

           3,在form标签中,加上enctype="multipart/form-data" 只有在上传文件时使用

   

为了便于上传,需在项目中引入:commons-fileupload-1.2.1.jar和commons-io-1.4.jar两个包

下面演示FileUpload包API的使用:

upload.jsp

My JSP upload page .container{ width:400px; margin:100px auto; } ul li{ width:350px; height:50px; list-style:none; } ul li span{ color:red; font-size:30px; } 上传文件 var count = 0 ; document.getElementById("addLineID").onclick = function(){ if(count 200*1024){ request.setAttribute("message","上传文件大 小必须小于或等于200k 继续上传浏览列表"); request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response); continue ; } String contentType = fileItem.getContentType(); String agent = request.getHeader("USER-AGENT"); //获取agent参数,IE有MSIE参数,FF没有该参数 System.out.println(contentType); if(!"image/pjpeg".equals(contentType) && !"image/jpeg".equals(contentType) &&  !"application/octet-stream".equals(contentType)){ request.setAttribute("message","上传文件类型 必须是jpg继续上传 浏览列表"); request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response); continue ; } String filename = fileItem.getName(); filename = WebUtil.makeUuidFileName(filename); //创建目录把文件分散在2级子目录下 String uploadPath = WebUtil.makeSubUploadPath(this.getServletContext().getRealPath("/WEB-INF/upload"),  filename); //把文件写到服务器自定服务器下面 InputStream is = fileItem.getInputStream(); OutputStream os = new FileOutputStream(new File(uploadPath+"/"+filename)); WebUtil.writeToFile(is, os); fileItem.delete();//删除缓存的临时文件 } } } }catch(Exception e){ } request.setAttribute("message","上传文件成功 继续上传浏览列表"); request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response); } } WebUtil中部分代码:

public static String makeUuidFileName(String filename){ return UUID.randomUUID().toString()+"_"+filename; } /* * 该方法是把上传的文件打散在不同的子目录里面 */ public static String makeSubUploadPath(String path,String name){ int code = name.hashCode(); int dir1 = Math.abs(code % 16); //第一级目录 int dir2 = Math.abs((code >> 1) % 16); //第二级目录 File file = new File(path+"/"+dir1+"/"+dir2); if(!file.exists()){ //如果目录不存在就创建该目录 file.mkdirs(); } return file.getPath(); } /** * 把输入流写到输出流里面 * @param is * @param os */ public static void writeToFile(InputStream is,OutputStream os){ try{ int len = 0; byte[] buf = new byte[2048]; while((len = is.read(buf)) > 0){ os.write(buf, 0, len); } }catch(Exception e){ e.printStackTrace(); }finally{ try { if(is != null){ is.close(); } if(os != null){ os.close(); } } catch (IOException e) { e.printStackTrace(); } } } public static String getFileName(String filename){ return filename.substring(filename.indexOf("_")+1); } }

               上面例子中,在WEB-INF中创建了一个upload文件夹,同时在为了解决不同用户上传相同文件名的问题,使用UUID分别

       为每个文件区分,同时为了在upload中的文件夹打散在子文件夹,利用了添加UUID后的UUID文件名的哈希码,得到一个子目

       录路径,这样做的好处是:在下载的时候可以通过UUID文件名调用相同的方法获取子目录路径,从而获取输入流。

ListFileServlet

import itcast.util.WebUtil; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.LinkedHashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ListFileServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取上传文件存放路径 String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload"); //定义一个集合将文件名存放好 Map map = new LinkedHashMap(); //递归遍历所有文件 getAllFile(uploadPath,map); //将map保存到request中 request.setAttribute("MAP", map); //转发到list.jsp 页面 request.getRequestDispatcher("/WEB-INF/list.jsp").forward(request, response); } public void getAllFile(String uploadPath, Map map) { File file = new File(uploadPath); if(file.isFile()){ String uuidFileName = file.getName(); //从uuidName 中截取出filename String filename = WebUtil.getFileName(uuidFileName); map.put(uuidFileName, filename); }else if(file.isDirectory()){ //如果是目录的话 File[] files = file.listFiles(); for(File f : files){ getAllFile(f.getPath(), map); } } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } list.jsp

My JSP 'list.jsp' starting page .container{ width:500px; margin:0px auto; } .container ul li{ margin:0px auto; width:400px; list-style:none; height:50px; } .container ul li span{ width:200px; height:50px; text-align: center; display:inline-block; line-height:50px; } 文件名下载 ${item.value}下载

FileDownloadServlet

import itcast.util.WebUtil; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class FileDownloadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //解决中文乱码问题 //获取参数中的文件名称 String uuidFileName = request.getParameter("name"); uuidFileName = new String(uuidFileName.getBytes("ISO8859-1"),"UTF-8"); //从uuid文件名中获取文件名 String filename = WebUtil.getFileName(uuidFileName); System.out.println(filename); //因为是中文,要进行URL编码,该方法在Firefox Netscape 5.0 (Windows) 失效 filename = URLEncoder.encode(filename,"UTF-8"); System.out.println(filename); //获取上传文件的根目录 String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload"); //内部是通过uuidFileName的hasCode编码的,所以相同的文件名,可以获取相同的子路径 String path = WebUtil.makeSubUploadPath(uploadPath, uuidFileName); //通知浏览器以下载的方式打开 response.setHeader("content-disposition","attachment;filename="+filename); //从实际文件中读取流 InputStream is = new FileInputStream(path+"/"+uuidFileName); OutputStream os = response.getOutputStream(); //把内容写到浏览器 WebUtil.writeToFile(is, os); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } JAVA中的注解

                   注解是JDK5,新增的语法功能,就是用@来标识该类,方法,属性的相关信息

                  注解的作用:通知编译器如何处理被注解修饰过的内容,在某种情况下,可以替代原来的XML或properties等文本文件,

                  例如hibernate,spring,android 中会证明。

    1,@Override

               复写父类方法

    2,@Deprecated

               废弃方法,已经过时。

    3,@SuppressWarnings (value="unchecked")

              表示通知编译器不要警告

JDK5中的内置注解,不能瞒住企业方方面面的业务续修,所以的按规则,开发注解

自定义注解的生命周期

              SOURCE:有且只有在源码级别可见,(不推荐使用)

              CLASS:  有且只有在源码和字节码级别可见,(默认),但在运行时,不可见

              RUNTIME:在整个类的运行期周,都可见。(即源码,字节码,运行时)

元注解的作用

                 修饰其它注解的注解,注意:元注解也可以被其它注解修饰

                 @Retention(RetentionPolicy.RUNTIME):表示该注解可以在运行时,可见

                 @Target(ElementType.METHOD):表示该注解可以用在哪些地方,默认情况下,该注解可以出现在任何地方

自定义注解应用示例:

DB.java

@Target({METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface DB { String driver() default "com.mysql.jdbc.Driver"; String url() default "jdbc:mysql://127.0.0.1:3306/jdbc"; String user() default "root"; String password() default "root"; } Demo03.java public class Demo03 { @DB public Connection getConnection() throws Exception { Class clazz = this.getClass(); Method getConnectionMethod = clazz.getMethod("getConnection",null); DB dbAnnotation = getConnectionMethod.getAnnotation(DB.class); String driver = dbAnnotation.driver(); String url = dbAnnotation.url(); String user = dbAnnotation.user(); String password = dbAnnotation.password(); Class.forName(driver); return DriverManager.getConnection(url,user,password); } public static void main(String[] args) throws Exception { Demo03 test = new Demo03(); Connection conn = test.getConnection(); System.out.println(conn!=null?"连接成功":"连接失败"); conn.close(); } }



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3