图片服务器目录:

一:项目背景:

我们平常写博客或者github,本质上是往文章中放了一个url ,这个链接对应的资源在另一个服务器上。而我们这个项目就是实现这样一个服务器,可以存储和展示我们的珍贵相片。

二:开发环境:

  • 操作系统:windows10
  • 开发工具:IDEA专业版
  • web服务器:Tomcat 8.5.51
  • JDK: java 1.8

    三:图片功能:

    服务器有上传图片,展示图片,删除图片,查询图片,并且实现一个简单的前端网页去呈现我们这些操作。

    四:技术亮点:

    1. 使用HttpServlet类并覆写其中的一些方法,实现服务器端根据请求计算生成响应的过程
  • 2.MySQL存储上传的图片,及图片各属性。(简单,容易上手)
    文件上传---使用第三方依赖commons-fileupload(这个库为我们封装了一些上传文件所需要的类,方法)
  • 3.MD5:校验和,通过图片内容hash出一串数字串。我们可以通过一个短的字符串来验证整体数据的正确性。

    选用MD5的原因:

    • 原 来字符串的长度不回影响最终MD5的值,MD5是一个定长32长(16进制)。而 且 原字符串一点点的改动就会导致MD5变化很大。
    • 两个相同内容的字符计算出的MD5一定是一样的。
    • 两个一样的MD5值大概率下原字符串是一样的。根据这个特点我们可以对图片的内 容 进行加密,然后判断变化之后的字符串是否相等,如果相等,说明有重复的图片,那 我们只需在磁盘中存储一份,优化磁盘存储空间。
  • 4 . json数据传输----Gson第三方库
    我们的请求和响应都是以json格式进行解析和生成响应。
  • 5.前后端交互-----Ajax异步提交
    异步提交可以局部刷新页面,可以减轻服务器的负担。
    异步提交,通过jQuery实现非常方便。

    五:数据库设计:

    我们要实现图片服务器,必须有存储图片的列表。
    图片表的属性如下:
    项目:图片服务器(图床)_第1张图片

属性解释:
imgeId:图片存入数据的自增主键
imageName:图片的名字
size:图片的大小
uploadTime:图片的上传时间,格式为(yyyyMMdd)
contentType:图片类型,image/jpeg,如果不是图片类型则不上传。
path:磁盘的相对存储路径。图片的内容是存储在硬盘上。
md5:根据图片内容计算MD5,如果上传的两张图片内容一样,那么在硬盘中只存储一份即可。

六:图片的具体实现细节:

  • 上传图片:我们利用form表单提交数据实现的。
    注意:type=file.表示上传文件
    enctype=multipart/form-data,否则提交不了二进制数据的,图片内容是以二进制形式存储。
    method=post 请求方法是post,因为post方法带请求体。
    项目:图片服务器(图床)_第2张图片

    后端代码:利用fileupload拿到文件对象FileItem的集合。我们这里只上传一个文件。根据FileItem对象,我们可以获取上传上来的文件的大小,格式等数据。我们将这些数据和自己设置的图片存储路径封装为一个Image对象将该对象存入数据库。之后再创建一个File对象,将图片的二进制内容写入磁盘。

  • 删除图片
    1.删除图片是根据用户传来的参数imageId来进行选定的,找出数据库中符合imageId的图片,删除数据库存储。
    2.根据imageId封装Image对象,再根据image对象删除磁盘存储。
  • 展示图片:
    1.前端代码利用一个Vue对象的data属性存储一个images集合(这里存储的是从后台查询到的图片的集合)。通过V-for遍历images集合,每一个image发起一个Ajax异步请求去请求展示图片的servlet.
    2.后台的servlet根据前端传来的imageId查询到指定图片,根据图片属性(path)去找到磁盘中的图片内容(二进制形式存储),再以字节流的方式传回前端展示。
    3.以流的方式写回的时候,指定图片的格式为数据库中记录的格式。

    七:效果展示:

    首先展示已经存在数据库的图片:
    项目:图片服务器(图床)_第3张图片

上传一张新图:
1.点击上传按钮,选择图片
项目:图片服务器(图床)_第4张图片

2.点击“打开”,进入到此页面

项目:图片服务器(图床)_第5张图片

3.点击提交按钮,相册中新增一张图片
项目:图片服务器(图床)_第6张图片

删除图片功能:
选择一张图片,点击“删除”按钮
项目:图片服务器(图床)_第7张图片

弹出alart(),确认删除操作,请点击“确认”
项目:图片服务器(图床)_第8张图片

返回到首页,返现图片删除成功
项目:图片服务器(图床)_第9张图片

查看图片属性功能:查看数据库中已有的所有图片属性:

项目:图片服务器(图床)_第10张图片
查看图片属性功能:根据id查看指定图片属性:
项目:图片服务器(图床)

七:项目亮点:

一:简单的防盗链机制****

我的服务器链接可能会被其他人使用,如果请求服务器的人数过多,会导致服务器崩溃。
解决方法:请求中加一个referer字段,如果这个referer在我的白名单中,就允许访问。
白名单:hashset中添入允许的referer字段,展示图片的时候只需判断一下当前的referer是否再我的hashset中,
项目:图片服务器(图床)

referer:表示当前请求的上个页面的地址。
项目:图片服务器(图床)_第11张图片

二:优化磁盘存储空间****

如果两个图片的内容一样,就在磁盘上只存储一份文件即可。
通过计算MD5来判断两个图片的内容是否一样。
实现思路
上传图片的时候,先判定新图片的MD5值(数据库的一个字段)在数据库中是否存在。如果存在,就不把内容写到磁盘上;如果不存在,再写磁盘文件。
1)修改上传带码的逻辑。磁盘文件名用MD5值表示。
2)修改ImageDao,新增一个接口,能够按照MD5值查找数据库内容。
3)修改上传代码的逻辑,根据MD5值判定,当前图片是否要写磁盘。

八:过程中遇到的问题:

1.HTML文件Vue对象的methods属性拼写有误,导致其中的app.getImages()不能被识别;(由此可见,这种细节性错误一定要认真,很难再次察觉)
项目:图片服务器(图床)_第12张图片

2.因为我的dao层连接数据库的ip和port为远端不在本地,导致数据库连接失败,前端网页也因此加载不出来。(我们建议数据连接本地主机就行,连接远端需要权限设置,比较麻烦)
项目:图片服务器(图床)_第13张图片

项目:图片服务器(图床)_第14张图片

服务器端代码没有和数据连接成功,导致上传照片出现500.
项目:图片服务器(图床)_第15张图片

还有,连接port时候记得该端口的安全组一定要打开,否则也是连接不上的。(如图示)
项目:图片服务器(图床)_第16张图片

经过一番折腾,数据库终于连接成功,前端加载很成功。
项目:图片服务器(图床)_第17张图片