【SSH网上商城项目实战13】Struts2实现文件上传功能

        上一节我们做完了添加和更新商品的功能,这两个部分里有涉及到商品图片的上传,并没有详细解说。为此,这篇文章详细介绍一下Struts2实现文件上传的功能。

1. 封装文件信息

        我们首先得有一个Model来封装文件的信息,这个Model里需要有三个属性:文件、文件类型和文件名。针对我们要传的图片,我们新建一个Model如下:

  1. public class FileImage {  
  2.     private File file;  
  3.     private String contentType;  
  4.     private String filename;  
  5.       
  6.     public File getFile() {  
  7.         return file;  
  8.     }  
  9.   
  10.     public String getContentType() {  
  11.         return contentType;  
  12.     }  
  13.   
  14.     public String getFilename() {  
  15.         return filename;  
  16.     }  
  17.   
  18.     public void setUpload(File file) { //set方法可以不用和属性名一样,但是前台传进来时的参数得和set方法名相同。即前台传的参数为fileImage.upload  
  19.         this.file = file;  
  20.     }  
  21.       
  22.     public void setUploadContentType(String contentType) {  
  23.         this.contentType = contentType;  
  24.     }  
  25.       
  26.     public void setUploadFileName(String filename) {  
  27.         this.filename = filename;  
  28.     }  
  29. }  
public class FileImage {
    private File file;
    private String contentType;
    private String filename;

    public File getFile() {
        return file;
    }

    public String getContentType() {
        return contentType;
    }

    public String getFilename() {
        return filename;
    }

    public void setUpload(File file) { //set方法可以不用和属性名一样,但是前台传进来时的参数得和set方法名相同。即前台传的参数为fileImage.upload
        this.file = file;
    }

    public void setUploadContentType(String contentType) {
        this.contentType = contentType;
    }

    public void setUploadFileName(String filename) {
        this.filename = filename;
    }
}
       这样Model就写好了,考虑到文件上传的逻辑不是单个Action所特有的,所以我们将文件上传的逻辑写到工具类中,这样可供所有的Action调用。所以我们新建一个文件上传工具类(为了面向接口编程,我们也将工具类抽出个接口):

2. 完成文件上传工具类

  1. //文件上传工具类接口  
  2. public interface FileUpload {  
  3.   
  4.     //实现文件上传的功能,返回上传后新的文件名称  
  5.     public abstract String uploadFile(FileImage fileImage);  
  6.   
  7. }  
  8.   
  9. //文件上传工具类具体实现  
  10. @Component(“fileUpload”)  
  11. public class FileUploadUtil implements FileUpload {  
  12.       
  13.     private String filePath;  
  14.     @Value(“#{prop.filePath}”)   
  15.     //@Value表示去beans.xml文件中找id=”prop”的bean,它是通过注解的方式读取properties配置文件的,然后去相应的配置文件中读取key=filePath的值  
  16.     public void setFilePath(String filePath) {  
  17.         System.out.println(filePath);  
  18.         this.filePath = filePath;  
  19.     }  
  20.   
  21.     //1. 通过文件名获取扩展名  
  22.     private String getFileExt(String fileName) {  
  23.         return FilenameUtils.getExtension(fileName);  
  24.     }  
  25.       
  26.     //2. 生成UUID随机数,作为新的文件名  
  27.     private String newFileName(String fileName) {  
  28.         String ext = getFileExt(fileName);  
  29.         return UUID.randomUUID().toString() + “.” + ext;  
  30.     }  
  31.       
  32.     //实现文件上传的功能,返回上传后新的文件名称  
  33.     @Override  
  34.     public String uploadFile(FileImage fileImage) {  
  35.         //获取新唯一文件名  
  36.         String pic = newFileName(fileImage.getFilename());  
  37.         try {  
  38.             FileUtil.copyFile(fileImage.getFile(), new File(filePath, pic));//第一个参数是上传的文件,第二个参数是将文件拷贝到新路径下  
  39.             return pic;  
  40.         } catch (Exception e) {  
  41.             throw new RuntimeException(e);  
  42.         } finally {  
  43.             fileImage.getFile().delete();  
  44.         }  
  45.     }  
  46. }  
//文件上传工具类接口
public interface FileUpload {

    //实现文件上传的功能,返回上传后新的文件名称
    public abstract String uploadFile(FileImage fileImage);

}

//文件上传工具类具体实现
@Component("fileUpload")
public class FileUploadUtil implements FileUpload {
    
    private String filePath;
    @Value("#{prop.filePath}") 
    //@Value表示去beans.xml文件中找id="prop"的bean,它是通过注解的方式读取properties配置文件的,然后去相应的配置文件中读取key=filePath的值
    public void setFilePath(String filePath) {
        System.out.println(filePath);
        this.filePath = filePath;
    }

    //1. 通过文件名获取扩展名
    private String getFileExt(String fileName) {
        return FilenameUtils.getExtension(fileName);
    }
    
    //2. 生成UUID随机数,作为新的文件名
    private String newFileName(String fileName) {
        String ext = getFileExt(fileName);
        return UUID.randomUUID().toString() + "." + ext;
    }
    
    //实现文件上传的功能,返回上传后新的文件名称
    @Override
    public String uploadFile(FileImage fileImage) {
        //获取新唯一文件名
        String pic = newFileName(fileImage.getFilename());
        try {
            FileUtil.copyFile(fileImage.getFile(), new File(filePath, pic));//第一个参数是上传的文件,第二个参数是将文件拷贝到新路径下
            return pic;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            fileImage.getFile().delete();
        }
    }
}

        上面有个@Value注解,是从properties文件中获取文件要存入的路径的,具体可参见:Spring获取配置文件信息


3. 在Action中注入封装文件类和工具类

        写好了文件封装类和上传文件工具类后,我们需要将这两个对象注入到我们的Action中,这样就可以在Action中实现文件上传的功能了:

  1. @Controller(“baseAction”)  
  2. @Scope(“prototype”)  
  3. public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {  
  4.   
  5.     //封装了图片信息的类  
  6.     protected FileImage fileImage;  
  7.       
  8.     //上传文件工具类  
  9.     @Resource  
  10.     protected FileUpload fileUpload;  
  11.   
  12.     public FileImage getFileImage() {  
  13.         return fileImage;  
  14.     }  
  15.     public void setFileImage(FileImage fileImage) {  
  16.         this.fileImage = fileImage;  
  17.     }  
  18.     //省略其他无关代码……  
  19. }  
@Controller("baseAction")
@Scope("prototype")
public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {

    //封装了图片信息的类
    protected FileImage fileImage;

    //上传文件工具类
    @Resource
    protected FileUpload fileUpload;

    public FileImage getFileImage() {
        return fileImage;
    }
    public void setFileImage(FileImage fileImage) {
        this.fileImage = fileImage;
    }
    //省略其他无关代码……
}

4. 实现文件的上传

             好了,现在我们可以在ProductAction中去实现文件上传了,工具类写好的话,在Action中的代码量就很少了,这也是封装带来的优点。

  1. @Controller(“productAction”)  
  2. @Scope(“prototype”)  
  3. public class ProductAction extends BaseAction<Product> {  
  4.   
  5.         //省略其他无关代码……  
  6.       
  7.     public void save() throws Exception {  
  8.         //fileUpload工具类被抽取了,uploadFile方法直接接受一个fileImage对象,返回新的图片名  
  9.         String pic = fileUpload.uploadFile(fileImage);  
  10.           
  11.         model.setPic(pic);  
  12.         model.setDate(new Date());  
  13.         System.out.println(model);  
  14.         //商品信息入库  
  15.         productService.save(model);  
  16.     }  
  17.       
  18.     public void update() {  
  19.         String pic = fileUpload.uploadFile(fileImage);  
  20.         model.setPic(pic);  
  21.         model.setDate(new Date());  
  22.         System.out.println(model);  
  23.         //更新商品  
  24.         productService.update(model);  
  25.     }  
  26. }  
@Controller("productAction")
@Scope("prototype")
public class ProductAction extends BaseAction<Product> {

        //省略其他无关代码……

    public void save() throws Exception {
        //fileUpload工具类被抽取了,uploadFile方法直接接受一个fileImage对象,返回新的图片名
        String pic = fileUpload.uploadFile(fileImage);

        model.setPic(pic);
        model.setDate(new Date());
        System.out.println(model);
        //商品信息入库
        productService.save(model);
    }

    public void update() {
        String pic = fileUpload.uploadFile(fileImage);
        model.setPic(pic);
        model.setDate(new Date());
        System.out.println(model);
        //更新商品
        productService.update(model);
    }
}
       这样我们就完成了从前台上传文件的功能。


       相关阅读:http://blog.csdn.net/column/details/str2hiberspring.html

      整个项目的源码下载地址:http://blog.csdn.NET/eson_15/article/details/51479994

_____________________________________________________________________________________________________________________________________________________

—–乐于分享,共同进步!

—–更多文章请看:http://blog.csdn.net/eson_15


document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
    <div id="digg" articleid="51366384">
        <dl id="btnDigg" class="digg digg_enable" onclick="btndigga();">

             <dt>顶</dt>
            <dd>5</dd>
        </dl>


        <dl id="btnBury" class="digg digg_enable" onclick="btnburya();">

              <dt>踩</dt>
            <dd>0</dd>               
        </dl>

    </div>
 <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank">&nbsp;</a>   </div>
<div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank">&nbsp;</a></div>
<script type="text/javascript">
            function btndigga() {
                $(".tracking-ad[data-mod='popu_222'] a").click();
            }
            function btnburya() {
                $(".tracking-ad[data-mod='popu_223'] a").click();
            }
        </script>

<div style="clear:both; height:10px;"></div>


    <div class="similar_article" style="">
            <h4>我的同类文章</h4>
            <div class="similar_c" style="margin:20px 0px 0px 0px">
                <div class="similar_c_t">
                            <label class="similar_cur">
                                <span style="cursor:pointer" onclick="GetCategoryArticles('6228418','eson_15','foot','51366384');">●  框架技术<em>(45)</em></span>
                            </label>
                            <label class="">
                                <span style="cursor:pointer" onclick="GetCategoryArticles('6183974','eson_15','foot','51366384');">------【Struts2】<em>(5)</em></span>
                            </label>
                            <label class="">
                                <span style="cursor:pointer" onclick="GetCategoryArticles('6228419','eson_15','foot','51366384');">●  项目实战<em>(29)</em></span>
                            </label>
                            <label class="">
                                <span style="cursor:pointer" onclick="GetCategoryArticles('6214186','eson_15','foot','51366384');">------【SSH网上商城】<em>(29)</em></span>
                            </label>
                </div>

                <div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
                    <a href="http://blog.csdn.net" style="display:none" target="_blank">http://blog.csdn.net</a>
                    <ul class="similar_list fl"><li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/52270046" id="foot_aritcle_52270046undefined0470181063495545" target="_blank" title="【MyBatis】MyBatis分页插件PageHelper的使用">【MyBatis】MyBatis分页插件PageHelper的使用</a><span>2016-08-21</span><label><i>阅读</i><b>4952</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51743514" id="foot_aritcle_51743514undefined5058691526682662" target="_blank" title="【SpringMVC学习10】SpringMVC对RESTfull的支持">【SpringMVC学习10】SpringMVC对RESTfull的支持</a><span>2016-06-26</span><label><i>阅读</i><b>6414</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51736495" id="foot_aritcle_51736495undefined6858319986819688" target="_blank" title="【SpringMVC学习08】SpringMVC中实现文件上传">【SpringMVC学习08】SpringMVC中实现文件上传</a><span>2016-06-24</span><label><i>阅读</i><b>6064</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51725470" id="foot_aritcle_51725470undefined5983996170976444" target="_blank" title="【SpringMVC学习06】SpringMVC中的数据校验">【SpringMVC学习06】SpringMVC中的数据校验</a><span>2016-06-22</span><label><i>阅读</i><b>11339</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51700519" id="foot_aritcle_51700519undefined6075530957100506" target="_blank" title="【SpringMVC学习04】Spring、MyBatis和SpringMVC的整合">【SpringMVC学习04】Spring、MyBatis和SpringMVC的整合</a><span>2016-06-20</span><label><i>阅读</i><b>10295</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51694684" id="foot_aritcle_51694684undefined7738787089286265" target="_blank" title="【MyBatis学习15】MyBatis的逆向工程生成代码">【MyBatis学习15】MyBatis的逆向工程生成代码</a><span>2016-06-17</span><label><i>阅读</i><b>6096</b></label></li> </ul>

                    <ul class="similar_list fr"><li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51749880" id="foot_aritcle_51749880undefined5883359728929796" target="_blank" title="【SpringMVC学习11】SpringMVC中的拦截器">【SpringMVC学习11】SpringMVC中的拦截器</a><span>2016-06-28</span><label><i>阅读</i><b>6498</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51742864" id="foot_aritcle_51742864undefined40309340261560367" target="_blank" title="【SpringMVC学习09】SpringMVC与前台的json数据交互">【SpringMVC学习09】SpringMVC与前台的json数据交互</a><span>2016-06-25</span><label><i>阅读</i><b>7613</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51731567" id="foot_aritcle_51731567undefined4715729002159086" target="_blank" title="【SpringMVC学习07】SpringMVC中的统一异常处理">【SpringMVC学习07】SpringMVC中的统一异常处理</a><span>2016-06-23</span><label><i>阅读</i><b>13709</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51718633" id="foot_aritcle_51718633undefined9325877791308825" target="_blank" title="【SpringMVC学习05】SpringMVC中的参数绑定总结">【SpringMVC学习05】SpringMVC中的参数绑定总结</a><span>2016-06-21</span><label><i>阅读</i><b>10912</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/eson_15/article/details/51699103" id="foot_aritcle_51699103undefined5090026526294114" target="_blank" title="【SpringMVC学习03】SpringMVC中注解和非注解方式下的映射器和适配器总结">【SpringMVC学习03】SpringMVC中注解和非注解方式下的映射器和适配器总结</a><span>2016-06-19</span><label><i>阅读</i><b>7781</b></label></li> </ul>
                <a href="http://blog.csdn.net/eson_15/article/category/6228418" class="MoreArticle">更多文章</a></div>
            </div>
        </div>    
<script type="text/javascript">
    $(function () {
        GetCategoryArticles('6228418', 'eson_15','foot','51366384');
    });
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值