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


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

    1. 封装文件信息

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

    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. 完成文件上传工具类

    //文件上传工具类接口  
    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中实现文件上传的功能了:

    @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中的代码量就很少了,这也是封装带来的优点。

    @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);  
        }  
    }  

    需要在bean.xml中加入

    conn.properties

    public.properties 

    同时还要在category service层和impl 以及action加入query方法

    源代码见原来的 

    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. }  
  • 相关阅读:
    win10家庭版安装Docker for Windows
    docker镜像拉取速度过慢的解决
    解决docker: error pulling image configuration: Get https://registry-1.docker.io/v2/library/mysql/: TLS handshake timeout.
    ubuntu16.04下安装docker
    Ubuntu 16.04执行 sudo apt-get update非常慢解决方案
    [转载]MySQL存储过程详解  mysql 存储过程
    除非 Windows Activation Service (WAS)和万维网发布服务(W3SVC)均处于运行状态,
    windows资源管理器已经停止工作
    Shell脚本sqlldr导入数据压缩文件截断
    oracle 日常运维
  • 原文地址:https://www.cnblogs.com/shanheyongmu/p/5807740.html
Copyright © 2020-2023  润新知