基于Java Servlet图片服务器

项目简介

解决GitHub、博客中插入图片的问题;给定一个url,能够获得图片内容

项目功能

一个HTTP服务器,提供对图片的增删改查功能,同时能够完成上传图片,展示图片。

项目页面展示

选择图片界面
在这里插入图片描述
展示图片界面
在这里插入图片描述
删除图片界面
在这里插入图片描述
查看图片内容界面
在这里插入图片描述

数据库设计

设计一张图片表

MySQL脚本

drop table if exists `image_table`;
create table `image_table`(image_id int not null primary key auto_increment,
                          image_name varchar(50),
                          size bigint,
                          upload_time varchar(50),
                          md5 varchar(128),
                          content_type varchar(50) comment '图片类型',
                          path varchar(1024) comment '图片所在路径')

接口设计

下载一个前端代码和文档,根据前端分析来写后端业务

新增图片

在这里插入图片描述
根据前端代码,新增接口url为image,重写的是doPost方法
1.解析请求数据,获取图片的每个属性
2.根据md5校验码,验证是否上传过该图片

 //获取part(上传图片文件)的输入流
            InputStream is = p.getInputStream();//获取上传文件的输入流(数据)
            //根据输入流转md5校验码
            String md5 = DigestUtils.md5Hex(is);
            //如果已上传该图片(相同的md5),就不能插入数据和保存本地
            int num = ImageDAO.queryCount(md5);
            if(num >= 1){
                throw new AppException("上传图片重复");
            }

3.将上传图片保存到本地路径

p.write(IMAGE_DIR+"/"+md5);

4.将图片信息保存到数据库

 Image image = new Image();
            image.setImageName(name);
            image.setContentType(contentType);
            image.setSize(size);
            image.setUploadTime(uploadTime);
            image.setMd5(md5);
            image.setPath("/"+md5);
            int n = ImageDAO.insert(image);

查看所有图片元信息、查看指定图片元信息

在这里插入图片描述
这两个接口都是重写doGet方法,查看指定图片信息需要传参数,所以我们可以设计到一个方法中,根据有无参数来判断是查看所有图片还是指定图片

 String id = req.getParameter("imageId");
        Object o = null;
        //查询所有图片: o=List<Image>
        if(id == null){
            o = ImageDAO.queryAll();
        }else{//查询指定id的一个图片: o=image对象
            o = ImageDAO.queryOne(Integer.parseInt(id));
        }

查看图片内容

在这里插入图片描述
1.首先要设置响应返回的数据类型要和图片类型保持一致
2.因为图片内容是以二进制方式存储的,所以使用一个字节数组。输入流读出到数组中,输出流再写入
3.一定要刷新,并且关闭输入流、输出流,否则会出现缓冲或者读取不到的问题。

      String id = req.getParameter("imageId");
      Image image=ImageDAO.queryOne(Integer.parseInt(id));
      resp.setContentType(image.getContentType());
      String path = ImageServlet.IMAGE_DIR + image.getPath();
      FileInputStream fis = new FileInputStream(path);
      OutputStream os = resp.getOutputStream();
      byte[] bytes = new byte[1024*8];
      int len;
      while((len=fis.read(bytes)) != -1){
            os.write(bytes, 0, len);
        }
        os.flush();
        fis.close();
        os.close();

扩展功能:基于白名单方式的防盗链(简单方法)

通过 HTTP 请求头中的 Referer字段判定是否是指定网站请求图片.

1.使用HashSet来存储(有唯一性)

private static final Set<String> whiteList = new HashSet<>();
    static {
        whiteList.add("http://localhost:8082/java_image_server/");
        whiteList.add("http://localhost:8082/java_image_server/index.html");
    }

2.在方法中添加一处判断

 String referer = req.getHeader("Referer");
        if(!whiteList.contains(referer)){//白名单不包含当前请求的Referer,不允许访问
            resp.setStatus(403);
            //还可以设置响应体数据
            return;
        }

删除图片接口

在这里插入图片描述
重写doDelete方法
1.数据库根据id删除图片数据
2.本地磁盘删除图片(在数据库删除之前,先获取图片路径)
本地删除图片使用File

 File f = new File(path);
        f.delete();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值