SpringMVC的文件上传

作者: 奔跑的Libra | 来源:发表于2016-09-08 18:57 被阅读697次

    SpringMVC的文件上传

    本篇文章主要解决两个问题

    • 怎么使用springMVC 框架上传文件
    • 怎么在服务器上的指定路径保存文件,是它成为一个小型的文件服务

    1.文件的上传

    1.1 上传文件需要的组件

    • SpringMVC 框架
    • form-components.js组件

    1.2 HTML页面的实现

    我们以一个form的表单为例,在这个表单中除了上传文件的选项外,还有其他的input选项,当点击提交按钮的时候,这些都会被提交到后台进行处理。下面是html的代码:

    <form class="form-horizontal" id="add-blog-form" name="add-blog-form" enctype="multipart/form-data">
     <div class="control-group">
          <label class="control-label">博客名</label>
             <div class="controls">
                 <input type="text" placeholder="请输入博客名" class="m-wrap medium" name="add-blogName">
                 <span class="help-inline"></span>
             </div>
     </div>
    <div class="control-group" >
        <label class="control-label">博客上传</label>
             <div class="controls">
                <input type="file"  placeholder=""  class="m-wrap medium" name="add-blog">
                <span class="help-inline"></span>
             </div>
     </div>
    <div class="control-group" >
         <label class="control-label">图片上传</label>
             <div class="controls">
                 <input type="file"  placeholder=""  class="m-wrap medium" name="add-fig">
                 <span class="help-inline"></span>
             </div>
     </div>
     </form>
    

    注意: form 标签中必须要有这句enctype="multipart/form-data .在这个html中,还需引入form-components.js :

    <script src="../js/jquery-form.js" ></script>
    

    1.3 javaScript 的实现

    jQuery Form插件是一个优秀的Ajax表单插件,可以非常容易地、无侵入地升级HTML表单以支持Ajax。我们使用它的ajaxSubmit()方法来提交表单。代码如下:

    $("#add-blog-form").ajaxSubmit({
                        dataType: 'json',
                        url: '../blog/upload.do',
                        type: 'POST',
                        contentType: "application/x-www-form-urlencoded; charset=utf-8",
                        success:function(data){
                                $("#add-responsive").modal('hide');
                                var r ;
                                console.log("su"+data)
                                if(data=="success"){
    
                                    r = "添加成功!";
                                    showRow();
                                }else{
                                    r = "添加失败!";
                                }
                                $("h2#all-result").html(r);
                                $("#result-responsive").modal('show');
                            },
                        error:function(){
                        //输出错误信息
                        } 
    

    1.4 后台的处理

    首先配置spring-mvc 的xml文件如下:

    <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->
           <bean id="multipartResolver"
                 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
                  <!-- 默认编码 -->
                  <property name="defaultEncoding" value="utf-8" />
                  <!-- 文件大小最大值 -->
                  <property name="maxUploadSize" value="10485760000" />
                  <!-- 内存中的最大值 -->
                  <property name="maxInMemorySize" value="40960" />
           </bean>
    

    后台使用的是SpringMVC 来进行处理,代码如下:

    @Value("#{configProperties['mdFile.path']}")
        private String mdFilePath;
    @Value("#{configProperties['imgFile.path']}")
        private String imgFilePath;
    @RequestMapping(value="/upload" ,method = RequestMethod.POST, produces = "application/json;charset=utf8")
    @ResponseBody
    public String upload(@RequestParam(value="add-blog") MultipartFile file1,@RequestParam(value="add-fig", required=false) MultipartFile file2,
    @RequestParam(value="add-blogName") String blogName ) throws IOException {
        if (!file1.isEmpty()) {
            InputStream in1 = null;
            OutputStream out1 = null;
            String imgRealPath=null;
            try {
                    // 获得在tomcat中项目的路径, 需要在web.xml配置ft.webapp
                    //String webRootPath = System.getProperty("ft.webapp");
                    String html = null;
                    //logger.info(webRootPath);
                    // String rootPath = System.getProperty("catalina.home");
                    //File dir = new File(webRootPath + File.separator + "uploadFiles");
                    File dirMd = new File(mdFilePath+blogName);
                    if (!dirMd.exists())
                        dirMd.mkdirs();
                    File serverFile = new File(dirMd.getAbsolutePath() + File.separator + file1.getOriginalFilename());
                    in1 = file1.getInputStream();
                    out1 = new FileOutputStream(serverFile);
                    byte[] b = new byte[1024];
                    int len = 0;
                    while ((len = in1.read(b)) > 0) {
                        html += new String(b,0,len,"UTF-8");
                        out1.write(b, 0, len);
                    }
                    out1.close();
                    in1.close();
                    if(file2!=null){
                        InputStream inImg = null;
                        OutputStream outImg = null;
                        try {
                            File dirImg = new File(imgFilePath+blogName);
                            if (!dirImg.exists())
                                dirImg.mkdirs();
                            imgRealPath = dirImg.getAbsolutePath() + File.separator + file2.getOriginalFilename();
                            File serverFileImg = new File(imgRealPath);
                            inImg = file2.getInputStream();
                            outImg = new FileOutputStream(serverFileImg);
                            byte[] b2 = new byte[1024];
                            int len2 = 0;
                            while ((len2 = inImg.read(b2)) > 0) {
                                outImg.write(b2, 0, len2);
                            }
                            outImg.close();
                            inImg.close();
                        }catch (Exception e){
                            return "fail";
                        }finally {
                            if (outImg != null) {
                                outImg.close();
                                outImg = null;
                            }
    
                            if (inImg != null) {
                                inImg.close();
                                inImg = null;
                            }
                        }
                    }
                    html = blogService.renderToHtml(html);
                    System.out.println("++++++++++++"+html);
                    String noNeed = "<p>null</p>";
                    String newHtml="";
                    if(html.startsWith(noNeed)){
                        newHtml = html.replaceFirst(noNeed," ");
                    }
                    System.out.println("=========="+newHtml);
            
                    //insert form to database
                    blogService.insertBlog2database(blogName,  newHtml,  imgRealPath);
                    //update tags info
                    tagService.updateTagofBlogId(blogName);
                    return "success";
    
                } catch (Exception e) {
    
                    return "fail";
                } finally {
                    if (out1 != null) {
                        out1.close();
                        out1 = null;
                    }
    
                    if (in1 != null) {
                        in1.close();
                        in1 = null;
                    }
                }
            } else {
    
                return null;
            }
        }
    

    上面代码最主要的是对接收的文件进行按字节流的读入和写出,关于写出文件的相关问题会在下面章节进行详细的介绍。其他的是一些业务的逻辑代码,可以跳过。

    2. 上传后文件的处理

    在前一节中,我们通过前端处理把要上传的文件信息传到了后端,并在后端写入的指定的路径,一般来说上传的文件都会在tomcat的工程路径下,但是这样有一定的局限性,比如我们读取文件又要写一些读入的代码,做一些判断。因此,我们会使用Tomcat做一个简单的文件服务器,这样只需要在数据库中存储文件的路径,然后使用代码访问这个路径就可以访问到文件了。

    2.1 Tomcat 的相关配置

    server.xml中的Host标签中加入Context标签的内容 , 如下所示:

    <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true">
    
            <!-- SingleSignOn valve, share authentication between web applications
                 Documentation at: /docs/config/valve.html -->
            <!--
            <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
            -->
    
            <!-- Access log processes all example.
                 Documentation at: /docs/config/valve.html
                 Note: The pattern used is equivalent to using pattern="common" -->
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                 prefix="localhost_access_log." suffix=".txt"
                 pattern="%h %l %u %t "%r" %s %b" />
            <Context path="/root/blogfile" docBase="/root/blogfile" />
    </Host>
    

    注: 使用的是Tomcat8.0版本,这里实际上配置的是虚拟目录,<Context>是Host标记的子元素,表示一个虚拟目录,它主要有两个属性,path就相当于虚拟目录名字,而 docbase则是具体的文件位置。这样设置后就可以访问到了,如果想在浏览器中看到文件还需要设置web.xml, 把listings设置为true

    <servlet>
            <servlet-name>default</servlet-name>
            <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
            <init-param>
                <param-name>debug</param-name>
                <param-value>0</param-value>
            </init-param>
            <init-param>
                <param-name>listings</param-name>
                <param-value>true</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet> ```
    这样访问`host+路径`就可以访问到文件,如果不配置会出现404.
    
     ![uploadfile.png](http:https://img.haomeiwen.com/i1814710/f221e7535f611499.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    #### 2.2 后台的配置处理
    在1.4 中,我们刚开始使用了@Value注解进行了配置:
    ``` java
    @Value("#{configProperties['mdFile.path']}")
        private String mdFilePath;
    @Value("#{configProperties['imgFile.path']}")
        private String imgFilePath;
    

    它的作用是获取配置文件的key所对应的值,我们知道,在java中一些变化的量,尤其是路径,最好写在配置文件中,这样发生变化只修改配置文件就可以了,不用动代码。我们的配置文件如下:文件名:filePath.properties内容:

    mdFile.path = /root/blogfile/md
    imgFile.path = /root/blogfile/fig
    

    文件名:applicationContext.xml追加内容:

    <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
            <property name="locations">
                <list>
                    <value>classpath:filePath.properties</value>
                </list>
            </property>
    </bean>
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
            <property name="properties" ref="configProperties"/>
    </bean>
    

    至此,SpringMVC的上传文件以及后期的处理已经完成。

    相关文章

      网友评论

        本文标题:SpringMVC的文件上传

        本文链接:https://www.haomeiwen.com/subject/blasettx.html