使用vue+Element的Upload+formData实现图片传到SpringBoot,再上传到fastdfs

前端部分: 

<template>
    <div>
        <el-row>
            <el-col :span="12" :offset="6">
                <div id="demo">
                    <el-row>
                        <el-col :span="24">
                            <div>
                                <el-upload
                                  action=""
                                  list-type="picture-card"
                                  :auto-upload="false"
                                  :limit="5"
                                  :on-preview="handlePictureCardPreview"
                                  :on-remove="handleRemove"
                                  :on-change="fileChange"
                                  :multiple="true"
                                  :file-list="fileList">
                                  <i class="el-icon-plus"></i>
                                </el-upload>

                                <el-dialog :visible.sync="dialogVisible">
                                  <img width="100%" :src="dialogImageUrl" alt="">
                                </el-dialog>
                                
                            </div>
                        </el-col>
                    </el-row>   
                    <el-row>
                        <el-col :span="3" :offset="15">
                            <el-button type="primary" class="btn_pos" @click="uploadImage">上传</el-button>
                        </el-col>
                    </el-row>
                </div>
            </el-col>
        </el-row>
    </div>
</template>

<script>
    import axios from 'axios'
    export default {
        data () {
            return {
                dialogImageUrl: '',
                dialogVisible: false,
          //用来接收缓存中的图片
                fileList: []
            };
        },

        methods: {
            handleRemove(file, fileList) {
                this.fileList = fileList;
            },
            fileChange(file, fileList){
                this.fileList = fileList;
            },
            handlePictureCardPreview(file) {
                this.dialogImageUrl = file.url;
                this.dialogVisible = true;
            },

            uploadImage(){
                let formData = new FormData();
                for(let i = 0; i < this.fileList.length; i++){
                    //this.fileList[i].raw:获取图片格式
                    //这里的file必须和后端Controller中的requestparam参数一致,才能上传成功,否则会报400错误
                    formData.append("file", this.fileList[i].raw, this.fileList[i].name);
                }
          //这里重新创建了一个axios实例,是因为我在全局配置里的Content-type是appliacation/json,而这里我想要使用multipart/form-data
                const http1 = axios.create({
                    headers: {
                        // 'Content-Type': 'multipart/form-data'
                        "Content-Type": "multipart/form-data"
                    }
                })
                http1({
                    url: 'http://localhost:8081/lunbo/upload',
                    method: 'post',
                    data: formData
            
                })
                    .then((res) => {
                        console.log(res.data);
                    })
                    .catch((err) => {
                        console.log(err);
                    });
            }
            
        }
    }
</script>
<style scoped>
    .btn_pos{
        margin-top: 0px;
    }
</style>
View Code

后端部分:

pom文件:  

        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.27.2</version>
        </dependency>

controller部分:   

@RestController
@RequestMapping("/lunbo")
public class LunboController {

    @Autowired
    private UploadUtill uploadUtill;

    /**
     * 图片(文件上传),并返回图片地址
     */
    @RequestMapping("/upload")
    @ResponseBody //返回界面一个map<"path","....">
    public Map<String,Object> uploadImage(@RequestParam("file") MultipartFile file){

        //判断文件是否为空(防止出现空指针异常)
        if(file.isEmpty()){
            System.out.println("文件不存在");
        }else{
            System.out.println(file.getOriginalFilename());
        }
        //创建一个HashMap对象
        Map<String, Object> upload =new HashMap<>();
        //返回的fastdfs的路径
        String path = uploadUtill.uploadImage(file);
        upload.put("path",path);
        return upload;
    }
}
View Code

配置文件部分:

# FastDFS
fdfs:
  so-timeout: 1501
  connect-timeout: 601
  thumb-image: # 缩略图
    width: 60
    height: 60
  tracker-list: ip:22122

upload:
  base-url: http://ip:8888/
  allow-types:
    - image/jpeg
    - image/jpg
    - image/png
    - image/bmp
    - image/gif

配置类部分:

//@Component
@ConfigurationProperties(prefix = "upload")
public class UploadProperties {

//    @Value("${baseUrlt}")
    private String baseUrl;
    private List<String> allowTypes;

    public String getBaseUrl() {
        return baseUrl;
    }

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public List<String> getAllowTypes() {
        return allowTypes;
    }

    public void setAllowTypes(List<String> allowTypes) {
        this.allowTypes = allowTypes;
    }

工具类部分:(因为要经常使用所以把它抽取出来做工具类)

  思路:图片上传到fastdfs,然后获取路径,在拼接基本的路径(在application.yml中配置的)   

@Component
@EnableConfigurationProperties(UploadProperties.class)
public class UploadUtill {

//    Log log= LogFactory.getLog(UploadUtill.class);
    Log log= LogFactory.getLog(UploadProperties.class);

    @Autowired
    FastFileStorageClient storageClient;

    @Autowired
    UploadProperties prop;

    @Autowired
    LunboDao lunboDao;

    public String uploadImage(MultipartFile file) {

        // 1、校验文件类型
        String contentType = file.getContentType();
        if (!prop.getAllowTypes().contains(contentType)) {
            throw new RuntimeException("文件类型不支持");
        }

        // 2、校验文件内容
        try {
            BufferedImage image = ImageIO.read(file.getInputStream());
            if (image == null || image.getWidth() == 0 || image.getHeight() == 0) {
                throw new RuntimeException("上传文件有问题");
            }
        } catch (IOException e) {
            log.error("校验文件内容失败....{}", e);
            throw new RuntimeException("校验文件内容失败"+e.getMessage());
        }
        try {

            // 3、上传到FastDFS
            // 3.1、获取扩展名
            String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
            // 3.2、上传
            StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), extension, null);

            // 返回路径
            String path = prop.getBaseUrl() + storePath.getFullPath();
            //存入数据库
            LunboEntity lunboEntity = new LunboEntity();
            lunboEntity.setImgUrl(path);
            lunboEntity.setId(3);
            lunboDao.insert(lunboEntity);
            return path;


        } catch (IOException e) {
            log.error("【文件上传】上传文件失败!....{}", e);
            throw  new RuntimeException("【文件上传】上传文件失败!"+e.getMessage());
        }
    }
}
View Code

 注意:

  如果业务中不需要点击按钮,这时候可以使用  :http-request="uploadImage" 来直接触发该方法

posted @ 2021-01-15 10:42  潜跃  阅读(860)  评论(0编辑  收藏  举报