项目:妍妍的相册4——扩展

一、简单的防盗链

考虑到图片的链接可能会被其他人使用,所以决定通过一定的机制来限制其他人来使用图片(怕使用图片人太多,服务器挂掉)

实现:
1、可以判定当前请求的referer字段(HTTP请求协议中的header 的部分),是不是在代码指定的白名单中,如果是,才允许访问
2、可在代码中用一个hashSet存一下允许的referer就可以了,展示图片的时候判断一下是否存在hashSet中即可

//防盗链机制:白名单
    static private HashSet<String> whiteList = new HashSet<>();

    static {
        whiteList.add("http://127.0.0.1:8080/java_image_server/index.html");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //判断是否在白名单之中
        String referer = req.getHeader("Referer");
        if (!whiteList.contains(referer)) {
            resp.setContentType("application/json; charset: utf-8");
            resp.getWriter().write("{ \"ok\": false, \"reason\": \"未授权的访问\" }");
            return;
        }

二、优化磁盘的存储空间

	我发现同一张图片存在硬盘中还是会存两份,所以为了优化磁盘的存储空间,就决定将两份完全一样的图片在磁盘只存一份。
	那怎么判断两个图片内容是否一样呢?这就要用到MD5了!
	图片文件虽然是二进制数据,但本质上也是字符串,针对图片内容计算MD5。如果两个图片内容相同,得到的MD5一定相同,反之大致也可以。
MD5的特点:
1、不管原串多长,得到的MD5值是固定的长度
2、原串哪怕变动一点,MD5值变动很大
3、计算MD5值的过程很简单,但是通过MD5值无法推测出原字符串的(应用在密码学)

实现思路:
1、上传图片的时候,先判定下新图片的MD5在数据库中是否存在
2、如果已经存在了,就不把图片内容写到磁盘上,如果不存在,才写磁盘

// MD5 计算
        image.setMd5(DigestUtils.md5Hex(fileItem.get()));
        image.setPath("./image/" + image.getMd5());
        // 存到数据库中
        ImageDao imageDao = new ImageDao();

        // 看看数据库中是否存在相同的 MD5 值的图片, 不存在, 返回 null
        Image existImage = imageDao.selectByMd5(image.getMd5());

        imageDao.insert(image);

        // 2. 获取图片的内容信息, 并且写入磁盘文件
        if (existImage == null) {
            File file = new File(image.getPath());
            try {
                fileItem.write(file);
            } catch (Exception e) {
                e.printStackTrace();

                resp.setContentType("application/json; charset=utf-8");
                resp.getWriter().write("{ \"ok\": false, \"reason\": \"写磁盘失败\" }");
                return;
            }
        }
但后续发现,如果有多张图片对应同一个磁盘文件,删除任何一个图片,磁盘文件都被删除了,剩余图片无法正常显示

解决办法:通过selectByMD5看看当前MD5值对应的图片在数据库中是否存在,如果不存在,才真正删除磁盘文件!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值