项目之关于Summernote的图片处理和基于SpringMVC的文件上传(11)

简介: 项目之关于Summernote的图片处理和基于SpringMVC的文件上传(11)

最后,关于显示分页,首先要使得以前加载数据的函数是支持页码参数的:


loadMyQuestions: function (page) {
    if (!page || page < 1) {
        page = 1;
    }
    $.ajax({
        url: '/api/v1/questions/my',
        data: 'page=' + page,
        // 省略后续代码
    });
}

关于分页的页面部分的代码:

<nav aria-label="Page navigation example">
    <div class="pagination">
        <a class="page-item page-link" href="#"
           v-on:click.prevent="loadMyQuestions(pageInfo.prePage)">上一页</a>
        <a class="page-item page-link " href="#"
           v-for="i in pageInfo.navigatepageNums"
           v-on:click.prevent="loadMyQuestions(i)"
           v-bind:class="{ 'bg-primary text-light': i == pageInfo.pageNum }">
            <span v-text="i">1</span>
        </a>
        <a class="page-item page-link" href="#"
           v-on:click.prevent="loadMyQuestions(pageInfo.nextPage)">下一页</a>
    </div>
</nav>



在my.js中,在属性中声明pageInfo:


data: {

   questions: [],

   pageInfo: null

}


当获取数据后,添加:


questionsApp.pageInfo = data;


至此,页面的显示已完成,关于my.js的完整代码:

let questionsApp = new Vue({
    el: '#questionsApp',
    data: {
        questions: [
            {
                statusText: '已解决',
                statusClass: 'badge-success',
                title: '这是第1个问题',
                content: '很<b>严肃</b>的提出了第1个问题',
                tags: [
                    { id: 8, name: 'Java基础' },
                    { id: 12, name: 'Spring' },
                    { id: 15, name: 'SpringBoot' }
                ],
                userNickName: '天下第一',
                hits: '826',
                createdTimeText: '8小时之前',
                tagImage: '/img/tags/8.jpg'
            },
            {
                statusText: '未回复',
                statusClass: 'badge-warning',
                title: '这是第2个问题',
                content: '我也不告诉你是什么问题……',
                tags: [
                    { id: 10, name: 'MySQL' },
                    { id: 17, name: 'SpringSecurity' }
                ],
                userNickName: '天下第一',
                hits: '537',
                createdTimeText: '15小时之前',
                tagImage: '/img/tags/10.jpg'
            }
        ],
        pageInfo: null
    },
    methods: {
        loadMyQuestions: function (page) {
            if (!page || page < 1) {
                page = 1;
            }
            $.ajax({
                url: '/api/v1/questions/my',
                data: 'page=' + page,
                success: function (json) {
                    // json.data.list
                    let data = json.data;
                    let questions = data.list;
                    let statusTexts = ['未回复', '未解决', '已解决'];
                    let statusClasses = ['badge-warning', 'badge-info', 'badge-success'];
                    for (let i = 0; i < questions.length; i++) {
                        questions[i].statusText = statusTexts[questions[i].status];
                        questions[i].statusClass = statusClasses[questions[i].status];
                        questions[i].tagImage = '/img/tags/' + questions[i].tags[0].id + '.jpg';
                        let now = new Date().getTime();
                        let pastTime = (now - new Date(questions[i].createdTime).getTime()) / 1000;
                        let createdTimeText = "未知时间";
                        if (pastTime < 60) { // 不足1分钟
                            createdTimeText = "刚刚";
                        } else if (pastTime < 60 * 60) { // 不足1小时
                            createdTimeText = parseInt(pastTime / 60) + "分钟前";
                        } else if (pastTime < 60 * 60 * 24) {
                            createdTimeText = parseInt(pastTime / 60 / 60) + "小时前";
                        } else {
                            createdTimeText = parseInt(pastTime / 60 / 60 / 24) + "天前";
                        }
                        questions[i].createdTimeText = createdTimeText;
                    }
                    questionsApp.questions = questions;
                    questionsApp.pageInfo = data;
                }
            });
        }
    },
    created: function () {
        this.loadMyQuestions();
    }
});


46. 关于Summernote的图片处理


使用Summernote富文本编辑器时,当需要处理图片时,会自动将图片转换为Base64编码,当提交问题时,图片的Base64编码会作为“问题正文”的一部分提交到服务器端,最终,会被存储到数据库中!使用这种做法,会急剧增加数据库所占用的存储空间,对数据库的检索性能也会产生影响,不利于数据库的管理和维护,同时,由于图片已经转换为Base64编码作为正文的一部分数据,也不利于管理图片!


Summernote允许在配置Summernote富文本编辑器时自定义回调函数,该函数会在用户填写正文时选择图片会自动调用,则开发人员可以配置这个回调函数,当用户选择图片后,将图片以文件的形式直接上传到服务器端,当上传成功后,再将图片的路径返回到客户端,插入到Summernote中即可!


最后,在Summernote组织的“问题正文”中,关于图片可能就只是一段例如<img src="http://localhost:8080/1.jpg />这样的代码,就能够减少数据库的存储数据量,同时,对于文件的管理也会非常直观。


47. 基于SpringMVC的文件上传


【本知识点的案例为:fileupload】


关于文件上传,在HTTP协议中规定:


必须使用POST方式提交请求;

在HTML表单中必须配置enctype="multipart/form-data";

另外,在HTML表单中必须使用<input type="file" />控件。


所以,可以将页面设计为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传图片</title>
</head>
<body>
<h1>上传图片</h1>
<form action="/upload" method="post" enctype="multipart/form-data">
    <p>请选择您要上传的文件:<input type="file" name="image"></p>
    <p><input type="submit" value="上传"></p>
</form>
</body>
</html>


SpringMVC框架处理文件上传是基于commons-fileupload的,如果使用SpringMVC框架,需要自行添加这个依赖,如果使用SpringBoot框架则不需要,已经内置添加了。


在SpringMVC框架中,在控制器端会使用MultipartFile接口类型的参数来接收客户端提交的上传数据,在处理请求的方法中,直接声明这个接口类型的参数即可,参数名应该与客户端提交请求时的名称保持一致!在处理请求的过程中,调用MutlipartFile接口对象的void transferTo(File dest)方法就可以将图片保持到参数dest对应的文件位置。


可以在服务器端创建控制器处理上传请求:


@RestController
public class FileUploadController {
    @RequestMapping("/upload")
    public String upload(MultipartFile image) throws IOException {
        image.transferTo(new File("d:/1.jpg"));
        return "OK";
    }
}


注意:SpringBoot默认限制了上传文件的大小为1M / 10M(根据SpringBoot版本不同存在差异)。


关于文件名的处理:


文件名必须保证唯一,不要出现“覆盖上传”的现象(即使你认为原有的文件没有用了,也不要覆盖);

扩展名应该与原始扩展名(文件在客户端设备中的名称)保持一致,注意:如果某个文件全名中只有第1位是小数点,并没有更多的小数点,是表示该文件在Linux / MacOS中是隐藏文件,小数点右侧的并不是扩展名!

示例代码:

@RequestMapping("/upload")
public String upload(MultipartFile image) throws IOException {
    String parent = "d:/";
    // 处理文件名
    // 关于文件名的策略:时间 + 随机数
    // 无论当前上传功能是用于哪个用途,文件名必须唯一
    String filename = UUID.randomUUID().toString();
    // 处理扩展名
    // 获取原始文件名
    String originalFilename = image.getOriginalFilename();
    System.out.println("originalFilename=" + originalFilename);
    // 暂定扩展名空字符串
    String suffix = "";
    // 如果原始文件名中存在有效的扩展名,则截取
    int beginIndex = originalFilename.lastIndexOf(".");
    if (beginIndex > 0) {
        suffix = originalFilename.substring(beginIndex);
    }
    // 得到完整的文件名
    String child = filename + suffix;
    // 保存上传的文件
    image.transferTo(new File(parent, child));
    return "OK";
}



后续,使用以上parent作为上传的文件夹即可。


在处理上传时,关于MultipartFile的常用API有:


boolean isEmpty():判断上传的文件是否为空,如果在表单中没有选择文件,或选择的文件是0字节的,即为空;


long getSize():获取文件大小,以字节为单位;


String contentType:获取文档的MIME类型;


String getOriginalFilename():获取上传的文件的原始文件名;


void transferTo(File dest):保存上传的文件。


目录
相关文章
|
前端开发 应用服务中间件
SpringMVC 文件上传 消息 Required request part ‘file‘ is not present描述 由于被认为是客户端对错误(例如:畸形的请求语法、无效的请求信息帧或者
SpringMVC 文件上传 消息 Required request part ‘file‘ is not present描述 由于被认为是客户端对错误(例如:畸形的请求语法、无效的请求信息帧或者
2028 0
|
Java 数据库连接 数据库
SpringMVC之增删改查(CRUD)项目模拟
SpringMVC之增删改查(CRUD)项目模拟
102 0
|
前端开发 Java 应用服务中间件
SpringMVC之文件上传下载以及jrebel的使用
SpringMVC之文件上传下载以及jrebel的使用
79 0
|
2月前
|
设计模式 前端开发 Java
Spring MVC——项目创建和建立请求连接
MVC是一种软件架构设计模式,将应用分为模型、视图和控制器三部分。Spring MVC是基于MVC模式的Web框架,通过`@RequestMapping`等注解实现URL路由映射,支持GET和POST请求,并可传递参数。创建Spring MVC项目与Spring Boot类似,使用`@RestController`注解标记控制器类。
47 1
Spring MVC——项目创建和建立请求连接
|
2月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
65 2
|
7月前
|
前端开发 Java Apache
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
108 0
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
|
4月前
|
前端开发 Java 测试技术
单元测试问题之在Spring MVC项目中添加JUnit的Maven依赖,如何操作
单元测试问题之在Spring MVC项目中添加JUnit的Maven依赖,如何操作
|
6月前
|
Java 程序员
浅浅纪念花一个月完成Springboot+Mybatis+Springmvc+Vue2+elementUI的前后端交互入门项目
浅浅纪念花一个月完成Springboot+Mybatis+Springmvc+Vue2+elementUI的前后端交互入门项目
55 1
|
6月前
|
XML 前端开发 Java
SpringMVC的架构有什么优势?——异常处理与文件上传(五)
SpringMVC的架构有什么优势?——异常处理与文件上传(五)
|
7月前
|
JSON 前端开发 Java
SpringMVC概述、SpringMVC的工作流程、创建SpringMVC的项目
SpringMVC概述、SpringMVC的工作流程、创建SpringMVC的项目
50 2