图片服务器

代码:picture_server: 图片服务器上传图片

一、前端

1.前端框架

vue jquery

2.前端执行流程

(1)获取图片列表

a.以下语句在script中,所以在页面初始化时就会执行,调用vue变量appd的getImage()函数

app.getImages();

b.在getImage()函数中发送ajax请求,接口的请求方法是GET,路径是image,响应成功将响应数据赋值给vue中的数组变量images(this指的就是vue对象),images数组刚开始是空的

<script>
    var app = new Vue({
        el:'#app',
        data: {
            images: [
            ],
            uploadImage: ''
        },
        methods: {
            getImages() {
                $.ajax({
                    url: "image",
                    type: "get",
                    context: this,
                    success: function(data, status) {
                        this.images = data;
                        $("#app").resize();
                    }
                })

c.此时vue双向绑定,当images数组发生改变对应的页面利用for循环获取到图片列表

(2)删除

删除按钮点击后,调用remove函数(传入imageId),发送ajax请求,响应状态码为200就刷新图片列表,提示删除成功

remove(imageId) {
                $.ajax({
                    url:"image?imageId=" + imageId,
                    type:"delete",
                    context: this,
                    success: function(data, status) {
                        app.getImages();
                        alert("删除成功");
                    }
                })
 }

(3)选择文件

form标签中input type=file是页面中的选择文件,点击后选择一个文件(发生改变),会触发change事件,进入changeImage函数,将文件数据赋值给uploadImage变量,以便上传函数判断

 <form class="am-topbar-form am-topbar-right am-form-inline" v-on:submit.prevent="imageUpload()">
                <div class="am-form-group">
                    <input type="file" v-on:change="changeImage($event)" class="am-form-field am-input-sm">
                </div>
                <div class="am-form-group">
                    <input type="submit" class="am-form-field am-input-sm"  style="height:41px" value="上传"/>
                </div>
 </form>

(4)上传图片

form标签中的input type=submit点击,就会发生表单提交事件,此时v-on:submit.prevent是禁止表单自动提交,而是要通过绑定的vue变量的imageUpload函数

根据changeImage函数中赋值过的uploadImage变量来判断是否选择了图片后进行的上传,如果该变量是空的,会弹出警告窗口提示“选择图片后上传”;如果非空,则构建formData对象,设置请求体,请求数据格式就是form-data;上传成功(即ok=true)后,调用getImages函数刷新图片列表,上传失败报错

imageUpload(){
                if(!app.uploadImage) {
                    alert("选择图片后上传");
                    return;
                }
                let data = new FormData();
                data.append("uploadImage", app.uploadImage);
                $.ajax({
                    url: "image",
                    type: "post",
                    processData: false,
                    contentType: false,
                    data: data,
                    // context: this,
                    success: function(data, status) {
                        if(data.ok){
                            app.getImages();
                        }else{
                            alert(data.msg);
                        }
                        // alert("上传成功");
                    },
                    error: function (err, textStatus, throwable) {
                        console.error(JSON.stringify(err))
                    }
                })
 }

二、后端

1.后端技术

servlet、jdbc、jackson、 commons-codec(apche提供的专门加密的,提供一系列api通过加密算法生成密文、校验。这个项目是用来生成md5,用来验证图片的唯一性)

<dependency>
  <groupId>commons-codec</groupId>
  <artifactId>commons-codec</artifactId>
  <version>1.13</version>
</dependency>

2.工具类

1)DBUtil(数据库连接工具类)

(1)封装数据库连接池(双重校验锁的线程安全的单例模式)方法:

a.volatile修饰的静态变量

b.两个if判断,中间进行synchronized加锁操作保证安全

(2)关闭连接

2)json操作工具类(WebUtil)

3.文件上传功能

提供图片上传接口:

a.获取请求数据,获取图片part对象(属于复杂数据,采用Part,将数据保存在服务端本地硬盘和数据库中,在保存之前要先验证md5值在数据库中是否存在,如果存在则是重复图片则不用保存。

b.保存在服务端本地硬盘

根据获取的请求数据,利用md5Hex方法生成md5值

String md5= DigestUtils.md5Hex(p.getInputStream());
p.write(LOCAL_PATH_PREFIX+"/"+md5);

c.保存在数据库

先构造一个ImageInfo对象,保存插入数据库的数据;

设置图片名、大小、上传日期、md5、数据格式、路径;

进行插入数据库操作,调用ImageDao的insert,将图片数据插入;

d.返回响应数据,根据前端代码需要两个数据(ok,msg),转换为json返回

获取图片列表接口:

调用ImageDao的selectAll获取数据库中的所有图片数据,多行数据转换为List<ImageInfo>,并设置响应体

此时运行,并不会显示图片内容。

显示图片内容接口:ImageShowServlet

4.删除图片

在ImageServlet中写删除图片接口,要删除数据库中的和本地硬盘中的图片文件

5.解决图片重复上传问题:比较md5值

上传重复的数据,数据库会新增数据,本地硬盘虽然不会新增文件,但是进行了覆盖式的写入数据,会导致性能变差

在生成md5值后,根据数据库查询操作验证,如果重复则弹出警告框提示

 String md5= DigestUtils.md5Hex(p.getInputStream());
        //根据md5值在数据库查询是否存在,存在返回报错信息
        ImageInfo imageInfo=ImageDao.selectByMd5(md5);
        //图片已存在
        if(imageInfo!=null){
            Map<String,Object> data=new HashMap<>();
            data.put("ok",false);
            data.put("msg","上传的图片已存在");
            WebUtil.serialize(resp,data);
            return;
        }
        p.write(LOCAL_PATH_PREFIX+"/"+md5);

6. 防盗链

根据http请求refer请求头,可以知道http请求是哪个页面发起的,根据refer值判断是否允许访问

白名单:提供数组/列表,在范围内,可访问

黑名单:提供数组/列表,在范围内,不可访问

三、结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值