springboot+vue个人博客系统(三)文件上传及回显

一、文件上传

文件上传是将用户放入在博文中的图片上传到服务器中。

1.前端

在mavon-editor中绑定imgAdd,imgDel事件。

<div id="editor" v-on:mousedown="onWrite" v-on:mouseleave="onRead">
      <mavon-editor ref=md :ishljs="true" @imgAdd="imgAdd" @imgDel="imgDel" v-model="content" v-bind:style="styleChange" ></mavon-editor>
    </div>
// 绑定@imgAdd event
        imgAdd(pos, $file) {
          // 第一步.将图片上传到服务器.
          this.img_file[pos] = $file;
          let formdata = new FormData();
          formdata.append('image', $file);

          fetch("/api/blog/uploadImg",{
            method: 'post',
            body: formdata
          }).then(result => {
            if (!result.ok) {
              alert("通信失败,请联系管理员!");
            }
            return result.json()
          }).then((res) => {
            if(res.result === true){
              // 第二步.将返回的url替换到文本原位置![...](0) -> ![...](url)
              this.$refs.md.$img2Url(pos, res.url);
            }

          })
        },
        imgDel(pos) {
          delete this.img_file[pos];
        },

前端将后台返回的文件url地址替换文本原来的位置。就可以回显了。

2.后端

后端保存文件到磁盘,并且返回改地址的url

/**
     * 文件上传
     * @param image image
     * @return Map<String, Object>
     */
    @RequestMapping(value = "/uploadImg", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> uploadFile(MultipartFile image) {

        Map<String, Object> map = new HashMap<>(2);
        //本地使用,上传位置
        String rootPath = null;
        if(System.getProperty("os.name").startsWith("Windows")) {
            rootPath = "D:\\Users\\Documents\\uploads\\";
        }else if (System.getProperty("os.name").startsWith("Linux")){
            rootPath = "/usr/local/upLoads/";
        }

        //文件的完整名称,如spring.jpeg
        String filename = image.getOriginalFilename();
        //文件后缀,如.jpeg
        String suffix = filename.substring(filename.lastIndexOf("."));

        //创建年月文件夹
        Calendar date = Calendar.getInstance();
        File dateDirs = new File(date.get(Calendar.YEAR) + File.separator + (date.get(Calendar.MONTH) + 1));

        //目标文件
        File descFile = new File(rootPath + File.separator + dateDirs + File.separator + filename);

        String newFilename = UUID.randomUUID() + suffix;
        String parentPath = descFile.getParent();
        descFile = new File(parentPath + File.separator + newFilename);

        //判断目标文件所在的目录是否存在
        if (!descFile.getParentFile().exists()) {
            //如果目标文件所在的目录不存在,则创建父目录
            descFile.getParentFile().mkdirs();
        }

        //将内存中的数据写入磁盘
        try {
            image.transferTo(descFile);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传失败,cause:{}", e);
            map.put("result", false);
            return map;
        }
        //完整的url
        String fileUrl = "http://www.sustly.xyz:8081/blog/getImg?url=" + descFile;
        log.info(fileUrl);
        map.put("result", true);
        map.put("url", fileUrl);
        return map;
    }

注意:

 String fileUrl = "http://www.sustly.xyz:8081/blog/getImg?url=" + descFile;

这一句非常重要,getImg是回显的请求url则是请求的参数。

二、回显

前端只需要一些样式即可

<div id="content" v-highlight v-html="blog.content"  class="markdown-body"></div>

因为前端的img标签的src中就是我们上面完整的url,我们只需将这个get请求返回一个图片文件即可。

@RequestMapping(value = "/getImg", method = RequestMethod.GET)
    public void getFile(@RequestParam("url")String url,
                        HttpServletResponse response) throws IOException {
        File file = new File(url);
        log.info(url);
        ServletOutputStream outputStream = response.getOutputStream();
        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] bytes = new byte[1024];

        while (fileInputStream.read(bytes) != -1){
            outputStream.write(bytes);
        }

        outputStream.flush();
        fileInputStream.close();
        outputStream.close();
    }

 

后端代码实现: 1.引入相关依赖 ```xml <!-- 文件上传 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> ``` 2.配置文件上传相关信息 ```yaml # 文件上传限制 spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB spring.servlet.multipart.enabled=true ``` 3.编写文件上传接口 ```java @RestController @RequestMapping("/api/file") public class FileController { @PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile file) throws IOException { if (file.isEmpty()) { return "文件为空"; } String fileName = file.getOriginalFilename(); String filePath = "D:\\temp\\"; File dest = new File(filePath + fileName); file.transferTo(dest); return "上传成功"; } } ``` 前端代码实现: 1.安装 axios 和 element-ui ```bash npm install axios element-ui --save ``` 2.编写文件上传组件 ```vue <template> <div> <el-upload class="upload-demo" action="/api/file/upload" :auto-upload="false" :on-change="handleChange" > <el-button slot="trigger" type="primary">选取文件</el-button> <el-button v-if="imageUrl" type="success" @click="handleUpload">上传到服务器</el-button> <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过10MB</div> </el-upload> <img v-if="imageUrl" :src="imageUrl" style="max-width: 100%;"> </div> </template> <script> import axios from 'axios'; import { Message } from 'element-ui'; export default { data() { return { imageUrl: '', file: null, }; }, methods: { handleChange(file) { this.file = file.raw; this.imageUrl = URL.createObjectURL(this.file); }, handleUpload() { const formData = new FormData(); formData.append('file', this.file); axios.post('/api/file/upload', formData, { headers: { 'Content-Type': 'multipart/form-data', }, }).then(() => { Message.success('上传成功'); }).catch(() => { Message.error('上传失败'); }); }, }, }; </script> ``` 至此,图片上传及回显的代码实现就完成了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值