zoukankan      html  css  js  c++  java
  • form表单上传文件使用multipart请求处理

    在开发Web应用程序时比较常见的功能之一,就是允许用户利用multipart请求将本地文件上传到服务器,而这正是Grails的坚固基石——spring MVC其中的一个优势。Spring通过对Servlet API的HttpServletRequest接口进行扩展,使其能够很好地处理文件上传。扩展后的接口名为org.springframework.web.multipart.MultipartHttpServletRequest,其内容如清单7-31所示。

    清单7-31  org.springframework.web.multipart.MultipartHttpServletRequest接口

    interface MultipartHttpServletRequest extends HttpServletRequest {

    public MultipartFile getFile(String name);

    public Map getFileMap();

    public Iterator getFileNames();

    }

    如清单所示,MultipartHttpServletRequest接口简单地扩展了默认的HttpServletRequest接口,并提供一些用来处理请求文件的方法。

    7.10.1  使用multipart请求

    实际上只要发现一个multipart请求,就表明在控制器实例中存在一个实现Multipart HttpServletRequest接口的request对象。我们可以通过清单7-31所示的方法来访问multipart请求中的上传文件,不过在处理上传文件之前,先来看一下上传表单的内容,如清单7-32所示。

    清单7-32  上传表单示例

    <form action="upload" enctype="multipart/form-data">

    <input type="file" name="myFile" />

    <input type="submit" value="Upload! " />

    </form>

    粗体显示的是需要注意的部分,实际上一个上传表单只需要满足如下两点。

    l  enctype属性的属性值设为multipart/form-data。

    l  input的type属性的属性值设为file。

    在前面的示例中,<input>标签中属性type的值为file,且name属性的值为myFile,之所以需要name属性值,是因为在使用接口MultipartHttpServletRequest的getFile方法时需要使用name属性的值。例如在清单7-33中,代码中的upload操作会从请求中读取上传文件。

    清单7-33  读取上传文件

    def upload = {

    def file = request.getFile('myFile')

    // 处理该文件

    }

    注意getFile方法不会返回一个Java.io.File的实例,而是返回org.springframework.web. multipart.MultipartFile的一个实例,关于org.springframework.web.multipart.MultipartFile的详细信息,请参考清单7-34。如果在请求中没有找到文件则getFile方法返回null。

    清单7-34  org.springframework.web.multipart.MultipartFile接口

    interface MultipartFile {

    public byte[] getBytes();

    public String getContentType();

    public java.io.InputStream getInputStream();

    public String getName();

    public String getOriginalFilename();

    public long getSize();

    public boolean isEmpty();

    public void transferTo(java.io.File dest);

    }

    在MultipartFile接口中定义了如下很多有用的方法。

    l  使用getSize()方法获得文件长度,以此决定允许上传的文件大小。

    l  使用isEmpty()方法判断上传文件是否为空文件,以此决定是否拒绝空文件。

    l  使用getInputStream()方法将文件读取为java.io.InputStream流对象。

    l  使用getContentType()方法获得文件类型,以此决定允许上传的文件类型。

    l  使用transferTo(dest)方法将上传文件写到服务器上指定的文件。

    例如,如果上传的文件不为空并且大小不小于1024字节,那么可以按照清单7-35中的代码来实现。

    清单7-35  文件上传示例

    def upload = {

    def file = request.getFile('myFile')

    if(file && !file.empty && file.size < 1024) {

    file.transferTo( new java.io.File( "/local/server/path/${file.name}" ) )

    }

    }

    直接使用MultipartHttpServletRequest实例可以用来管理文件上传,但实际应用常常需要读取文件内容。

    但如果有多个文件同时上传,则要用多功能上传了

    @RequestMapping("/stadium/addPic.json")
    @ResponseBody
    public void addPicStadium(HttpServletRequest request,
    HttpServletResponse response){
    Map<String, Object> messages = new HashMap<String, Object>();
    String imgurl = ""; 
    //创建一个通用的多部分解析器    
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());    
    //设置编码方式
    multipartResolver.setDefaultEncoding("utf-8");
    //判断 request 是否有文件上传,即多部分请求    
    if(multipartResolver.isMultipart(request)){    
    try{
    //转换成多部分request      
    MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;    
    //MultipartHttpServletRequest multiRequest = multipartResolver.resolveMultipart(request);
    //取得request中的所有文件名   
    List<MultipartFile> files =  multiRequest.getFiles("fileUpload");
    int len = files.size();
    //限制图片上传的个数
    if(len > 6){
    messages.put("success", false);
    messages.put("msg", "上传图片失败,一次只能上传6张及以下的图片!");
    toJson(response, messages);
    return;
    }
    //Iterator<String> iter = multiRequest.getFileNames(); 

    int i=0;
    Map<String, String> map = new HashMap<String, String>();
    //while(iter.hasNext()){ 
    JSONArray ja = new JSONArray();
    for(MultipartFile multiparfile:files){

    //记录上传过程起始时的时间,用来计算上传时间    
    int pre = (int) System.currentTimeMillis();    
    //取得上传文件    
    //MultipartFile file = multiRequest.getFile(iter.next());

    //获取上传文件的名称
    String clientName = multiparfile.getOriginalFilename();
    //System.out.println(clientName);
    //if(file != null){    
    //取得当前上传文件的文件名称    
    //String myFileName = file.getOriginalFilename();    
    //如果名称不为“”,说明该文件存在,否则说明该文件不存在    
    //if(myFileName.trim() !=""){   
    if(!clientName.equals("")){

    String fileName = multiparfile.getOriginalFilename();
    int lastNum = fileName.lastIndexOf(".");
    String houzhui = fileName.substring(lastNum, fileName.length());
    //重命名上传后的文件名    
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    String fileNewName = sdf.format(new Date())+System.currentTimeMillis()+houzhui;

    String fileUpdateName = fileName.replace(fileName, fileNewName);
    //System.out.println(fileUpdateName);

    //定义上传路径    
    String path = request.getSession().getServletContext().getRealPath("upload");
    imgurl += "upload/"+fileUpdateName+",";
    File localFile = new File(path,fileUpdateName);    
    multiparfile.transferTo(localFile); 
    //System.out.println("fileName:"+fileName);
    //System.out.println("imgurl:"+imgurl);
    JSONObject jo = new JSONObject();
    try {
    jo.put("fileName", fileUpdateName);
    jo.put("imgurll", imgurl);
    } catch (JSONException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }

    ja.put(jo);

    map.put(fileName, imgurl);
    }    
    }    
    //}
    messages.put("success", true);
    messages.put("msg", "上传图片成功!");
    messages.put("imgMap", ja);
    messages.put("length", len);
    }catch(IllegalStateException e){
    e.printStackTrace();
    messages.put("success", false);
    messages.put("msg", "上传图片失败!");
    }catch(IOException e){
    e.printStackTrace();
    messages.put("success", false);
    messages.put("msg", "上传图片失败!");
    }
    }
    toJson(response, messages);
    }

  • 相关阅读:
    字符读取流缓冲区
    Runtime、System类
    字符流和字节流
    将C盘一个文本文件复制到D盘。
    DateDemo
    Collection单列集合 Map双列集合
    泛型
    Collection接口
    String类
    Python代码约定
  • 原文地址:https://www.cnblogs.com/dzcWeb/p/7088358.html
Copyright © 2011-2022 走看看