【Java实战项目】【超详细过程】—大饼的图片服务器4

本文主要讲述了大饼的图片服务器基于servlet创建不同接口并绑定URL,包括ImageServlet和ImageShowServlet。


1.引入servlet依赖

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <!--表示在开发阶段需要此依赖,部署到Tomcat后就不需要了-->
      <scope>provided</scope>
    </dependency>

2.处理客户端请求

在这里插入图片描述

在最开始设计时我们将功能分为以下几个模块:上传图片,查看图片属性(全部和部分),查看图片内容,删除图片。我们将请求设计成了两种形式,其中上传图片,查看图片属性(全部和部分),删除图片的请求的URL均为./image,查看图片属性和查看图片内容方法相同所以设计请求时将URL部分设计的不一样。
所以我们需要两个类,ServletImage绑定的URL为:./image,ServletImageShow绑定的URL为:./imageShow
可以在Java目录下创建一个api的包,里面新建两个类ServletImage和ServletImageShow,都继承自HttpServlet

2.1 上传图片

上传图片用的是Post方法,所以重写doPost方法
上传一张图片可以分为以下步骤:
1.获取请求中的图片属性存入数据库
2.将图片存入磁盘
3.告诉客户端上传成功

2.1.1.获取图片属性写入数据库

首先我们要获取到客户端上传的图片信息,这里使用FileUpload来获取文件的信息,首先我们需要导入FileUpload依赖,在pom.xml中加入依赖:

    <!--上传文件的第三方仓库FileUpload-->
    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>

导入依赖后我们需要:
(1)创建factory对象和fileUpload对象为获取图片信息做准备(固定逻辑)
(2)将获取到的文件信息存到列表items中
(3)获取列表items中第一个文件的信息存入对象fileimage中
(4)在fileiteam中的信息取出分别存储到image中的各种属性中(这个过程中构造出文件存储路径)
(5)调用ImageDao中的存储方法,将image存储到数据库

(1)创建factory对象和fileUpload对象为获取图片信息做准备
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload fileUpload = new ServletFileUpload(factory);
(2)将获取到的文件信息存到列表items中

用fileUpload.parseRequest(req)方法来获取请求中的文件信息,返回值为List类型

List<FileItem> items = fileUpload.parseRequest(req);

处理异常try/catch,若代码抛出异常说明在这里解析文件内容存入items时出错了,让其抛出异常信息:

resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write("{\"ok\":false ,\"reason\":\"请求解析失败\"}");
(3)获取列表items中第一个文件的信息存入对象fileImage中
FileItem fileItem = items.get(0);
(4)在fileiteam中的信息取出分别存储到image中的各种属性中
            Image image = new Image();
            image.setImageName(fileItem.getName());//将取出的数据中文件名赋值给ImageName
            image.setSize((int) fileItem.getSize());
            //获取当前时间作为存储时间,存储于image中的UploadTime
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            image.setUploadTime(simpleDateFormat.format(new Date()));
            image.setContentType(fileItem.getContentType());
            //构造一个路径:./image+图片名
            //但是这个文件存储路径会导致文件名相同时文件路径就会相同,无法存储,
            //所以可以在这个路径中加入时间戳(毫秒级)来分开两个文件
            image.setPath("./image/"+System.currentTimeMillis()+"_"+fileItem.getName());
            image.setMd5("12903421");//当前先写死,后面加上计算md5
(5)调用ImageDao中的存储方法,将image存储到数据库
ImageDao imageDao = new ImageDao();
imageDao.insert(image);

2.1.2.将图片存入磁盘

将 image 的 path 元素内容传给 File 的对象 file (指定文件保存的路径为 image.path),然后将 fileItem 中存储的文件存储在 file 中指定的文件路径中

File file =new File(image.getPath());
fileItem.write(file);

记得处理异常,用try/catch,若执行出错抛出异常说明文件存入磁盘出错,在catch中加入错误信息:

resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write("{\"ok\":false ,\"reason\":\"写入磁盘失败\"}");

2.1.3.告诉客户端上传成功

根据最开始设计的响应书写
在这里插入图片描述

resp.setContentType("application/json;charset=utf-8");
resp.getWriter().write("{\"ok\":true }");

2.1.4.上传图片全部代码:

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //1.获取图片属性数据存入数据库
        //(1)创建一个factory对象和fileUpload对象,为获取图片属性做的准备工作(固定逻辑)
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload fileUpload = new ServletFileUpload(factory);

        //(2)fileUpload对象进一步解析,将数据存入items
        try {
            List<FileItem> items = fileUpload.parseRequest(req);
            //此时Itmes已经把图片信息获取到了(此时获取到图片信息的可能不止一个图片的,所以用列表存储)

            //(3)将fileUpload解析得到的信息存入image
            FileItem fileItem = items.get(0);
            //取出items中存储的众多图片中的第一个图片的信息存储于fileItem
            Image image = new Image();
            image.setImageName(fileItem.getName());//将取出的数据中文件名赋值给ImageName
            image.setSize((int) fileItem.getSize());
            //获取当前时间作为存储时间,存储于image中的UploadTime
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            image.setUploadTime(simpleDateFormat.format(new Date()));
            image.setContentType(fileItem.getContentType());
            //构造一个路径:./image+图片名,但是这个文件存储路径会导致文件名相同时文件路径就会相同,无法存储,所以可以在这个路径中加入时间戳(毫秒级)来分开两个文件
            image.setPath("./image/"+System.currentTimeMillis()+"_"+fileItem.getName());
            image.setMd5("12903421");//当前先写死

            //(4)将数据存入数据库,利用imageDao中的insert方法
            ImageDao imageDao = new ImageDao();
            imageDao.insert(image);

            //2.将图片内容存入磁盘
            File file =new File(image.getPath());
            try {
                fileItem.write(file);
            } catch (Exception e) {
                resp.setContentType("application/json;charset=utf-8");
                resp.getWriter().write("{\"ok\":false ,\"reason\":\"写入磁盘失败\"}");
            }

        } catch (FileUploadException e) {
            //解析失败的情况
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write("{\"ok\":false ,\"reason\":\"请求解析失败\"}");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }


        //3.给客户端返回一个结果
        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().write("{\"ok\":true }");
    }

2.2 查看图片属性

查看图片属性为使用GET方法,所以需要重写doGet方法
查看图片属性分两种情况:1.查看所有图片属性;2.查看部分图片属性,可以根据请求有没有imageId属性判断为查看什么照片的属性,所以我们需要有两个方法分别为查看全部图片和查看部分图片,用if判断一下imageId是否为空,为空使用查看所图片的方法

2.2.1 doGet方法

   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //将URL中的imageId参数的值赋值给imageId
        String imageId = req.getParameter("imageId");
        //imageId.equals("") 条件判断语句,检查变量 imageId 是否等于空字符串。
        // 如果 imageId 等于空字符串,那么条件为真,执行 if 语句块中的代码;
        // 否则,跳过 if 语句块。
        if (imageId == null || imageId.equals("")){
            //根据设计好的API,imageId为空时为查找全部图片信息
            try {
                selectAll(req,resp);//(调用下面的查找所有图片的方法)
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }else {
            try {
                selectOneId(imageId,resp);//(调用下面的查找一个图片的方法)
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }

        }
    }

2.2.2 查看所有图片

    private void selectAll(HttpServletRequest req ,HttpServletResponse resp) throws SQLException, IOException {
        //1.创建Image对象并查找数据库(查找数据库需要ImageDao类中的selectAll()方法,所以需要先创建imageDao对象)
        ImageDao imageDao =new ImageDao();
        List<Image> images = imageDao.selectAll();
        //2.将gson数组转成Json字符串
        //(1)创建一个gson对象
        Gson gson = new GsonBuilder().create();
        //(2)利用gson.toJson方法将gson转换成json格式的字符串
        String jsonData = gson.toJson(images) ;
        //3.将Json字符串写入返回值resp中
        resp.getWriter().write(jsonData);

    }

1.创建列表images(List< Image >),用于存储调用ImageDao中的selectAll方法的返回值
2.用new GsonBuilder().create();创建Gson对象,因为此时查到的数据还是Java对象,要将其以json格式传输给resp,此时就需要用到gson对象
3.将Java对象转换成json格式的String对象gson.toJson(images) ;
4.将转换后得到的json格式的字符串写入resp中resp.getWriter().write(jsonData);

2.2.3 查看一张图片

    private void selectOneId(String imageId ,HttpServletResponse resp) throws SQLException, IOException {
        //1.创建Image对象并查找数据库
        ImageDao imageDao = new ImageDao();
        Image image = imageDao.selectOneId(Integer.parseInt(imageId));

        //2.将gson数组转成Json字符串
        //(1)创建一个gson对象
        Gson gson = new GsonBuilder().create();
        //(2)利用gson.toJson()方法将gson转换成json字符串
        String jsonData = gson.toJson(image);
        //3.将Json字符串写入返回值resp中
        resp.getWriter().write(jsonData);
    }

1.创建Image对象image,用于存储调用ImageDao中的selectOneId方法的返回值(传入参数imageId将转为Int类型)
2.用new GsonBuilder().create();创建Gson对象,因为此时查到的数据还是Java对象,要将其以json格式传输给resp,此时就需要用到gson对象
3.将Java对象转换成json格式的String对象gson.toJson(image);
4.将转换后得到的json格式的字符串写入resp中resp.getWriter().write(jsonData);

2.2.4 查看图片属性所有代码

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //将URL中的imageId参数的值赋值给imageId
        String imageId = req.getParameter("imageId");
        //imageId.equals("") 条件判断语句,检查变量 imageId 是否等于空字符串。
        // 如果 imageId 等于空字符串,那么条件为真,执行 if 语句块中的代码;
        // 否则,跳过 if 语句块。
        if (imageId == null || imageId.equals("")){
            //根据设计好的API,imageId为空时为查找全部图片信息
            try {
                selectAll(req,resp);//(调用下面的查找所有的方法)
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }else {
            try {
                selectOneId(imageId,resp);//(调用下面的查找一个图片的方法)
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }

        }
    }
    private void selectAll(HttpServletRequest req ,HttpServletResponse resp) throws SQLException, IOException {
        //1.创建Image对象并查找数据库(查找数据库需要ImageDao类中的selectAll()方法,所以需要先创建imageDao对象)
        ImageDao imageDao =new ImageDao();
        List<Image> images = imageDao.selectAll();
        //2.将gson数组转成Json字符串
        //(1)创建一个gson对象
        Gson gson = new GsonBuilder().create();
        //(2)利用gson.toJson方法将gson转换成json格式的字符串
        String jsonData = gson.toJson(images) ;
        //3.将Json字符串写入返回值resp中
        resp.getWriter().write(jsonData);

    }

    private void selectOneId(String imageId ,HttpServletResponse resp) throws SQLException, IOException {
        //1.创建Image对象并查找数据库
        ImageDao imageDao = new ImageDao();
        Image image = imageDao.selectOneId(Integer.parseInt(imageId));

        //2.将gson数组转成Json字符串
        //(1)创建一个gson对象
        Gson gson = new GsonBuilder().create();
        //(2)利用gson.toJson()方法将gson转换成json字符串
        String jsonData = gson.toJson(image);
        //3.将Json字符串写入返回值resp中
        resp.getWriter().write(jsonData);
    }

2.3 删除图片

删除图片的方法:DELETE ,所以要重写doDelete方法
删除图片分为以下几步:
1.首先获取要删除的图片的imageId
2.根据获取的imageId在数据库中查找图片属性(包括存储路径等)用到ImageDao类中的selectOneId方法
3.根据在数据库中查找到的图片的存储路径找到图片文件,并删除用文件删除file.delete();
4.删除数据库中该图片的信息,用到ImageDao类中的deleteOneId方法

2.3.1 获取图片ID

从请求中获取图片imageId存储于imageId中

String imageId = req.getParameter("imageId");

判断imageId中是否有数据,若有则说明请求解析成功,没有则返回错误信息,所以此时加入一个if判断

        if(imageId == null || imageId.equals("")){
            resp.setStatus(200);
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write("{\"ok\":false ,\"reason\":\"解析请求失败\"}");
            return;

2.3.2 查找图片属性

实例化ImageDao对象用于调用seleceOneId方法查找图片属性,主要是存储路径,查到的结果放在Image对象image中

ImageDao imageDao = new ImageDao();
Image image = imageDao.selectOneId(Integer.parseInt(imageId));

处理异常try/catch
此时若image属性为空则说明数据库中没有这个图片,返回一个错误原因

        //若imageI的值为空或者imageId字符串等于空字符串,则返回一个错误信息
        if(imageId == null || imageId.equals("")){
            resp.setStatus(200);
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write("{\"ok\":false ,\"reason\":\"解析请求失败\"}");
            return;
        }

2.3.3 删除磁盘中文件

首先要根据数据库中存储的图片的存储路径找到图片并删除

File file = new File(image.getPath());
file.deleat();

2.3.4 删除数据库中属性

调用ImageDao类中的deleteOneId方法来删除数据库中的图片属性信息(参数为imageId,类型不同强转一下)

imageDao.deleteOneId(Integer.parseInt(imageId));

2.3.5 删除图片所有代码

    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取图片ID
        String imageId = req.getParameter("imageId");
        resp.setContentType("application/json;charset=utf-8");
        //若imageI的值为空或者imageId字符串等于空字符串,则返回一个错误信息
        if(imageId == null || imageId.equals("")){
            resp.setStatus(200);
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write("{\"ok\":false ,\"reason\":\"解析请求失败\"}");
            return;
        }

        //2.创建ImageDao对象,根据图片ID在数据库中查找到他的路径
        ImageDao imageDao = new ImageDao();
        try {
            Image image = imageDao.selectOneId(Integer.parseInt(imageId));
            if (image == null){
                //若image为空则说明URL中读到的imageId在数据库中没有没有,所以image中没有结果
                resp.setStatus(200);
                resp.setContentType("application/json;charset=utf-8");
                resp.getWriter().write("{\"ok\":false ,\"reason\":\"没有这张图片,不能删除\"}");
            }
            //3.删除数据库中的图片信息
            imageDao.deleteOneId(Integer.parseInt(imageId));
            //4.删除磁盘中的图片信息
            File file = new File(image.getPath());
            file.delete();
            resp.setStatus(200);
            resp.getWriter().write("{\"ok\":true}");

        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (JavaImageServerException e) {
            throw new RuntimeException(e);
        }


    }

2.4查看图片内容

根据前面的设计查看图片的路径和上面几个操作路径不相同,所以单独放在一个类里
在api包下面新建ImageShowServlet 类,继承自httpServlet 重写doGet方法
查看图片内容需要以下几步
1.获取被查看图片的Id
2.调用ImageDao中的方法以imagrId为参数,获取图片的属性信息
3.根据获取到的图片存储路径找到图片文件,获取到文件内容以字节流的方式返回给浏览器,同时返回文件类型

2.4.1.获取被查看图片的Id

从请求中获取imageId的值赋给String类型的imageId变量

String imageId = rep.getparameter("imageId");

在获取到imageId的值之后首先我们要判断它是否为空,为空说明请求解析出错,此时要给浏览器返回一个错误信息

if(imageId == null || imageId.equals("")){
    resp.setstatus(200);
    resp.setContentType("application/json;charset=utf-8");
    resp.getwriter().write("{\"ok\":false,\"reason\":\"解析请求出错\"}");
    return;
}

2.4.2.获取图片的属性信息

获取图片属性信息需要用到ImageDao中的selectOneId方法,所以要先实例化ImageDao类,调用selectOneId方法,获取的返回值存入Image对象image中

ImageDao imageDao = new ImageDao();
Image image = new Image();
image = imageDao.selectOneId(Integer.parseInt(imageId));

处理异常,使用try/catch
判断获取的image属性是否为空,为空说明属性获取失败(即当前imageId对应的图片在数据库中不存在),返回错误信息

            if(image ==null ){
                resp.setContentType("application/json;charset=utf-8");
                resp.getWriter().write("{\"ok\":false ,\"reason\":\"查找的imageId不存在\"}");
            }

2.4.3.获取到文件内容返回给浏览器

在读取文件内容时由获取文件内容的对象每次读取1024个比特的字符放在缓冲区,然后响应的输出流的对象读取缓冲区中的数据作为响应,直到获取文件内容的对象将文件内容读取结束(标志:读取到-1)时停止读取,浏览器按照图片的类型对独到的图片内容进行解析
所以:
(1)首先浏览器读取图片时需要知道要读取的的图片的类型
(2)其次我们还需要有一个FileInputStream对象来获取文件的内容
(3)然后要有一个获取响应输出流的对象outputStream
(4)最后我们还需要一个1024比特大小的缓冲区
(5)操作完成后记得关闭连接

            resp.setContentType(image.getContentType());
            //将文件类型传给浏览器
            File file = new File(image.getPath());
            //根据文件位置找到文件,并将其作为file对象
            OutputStream outputStream = resp.getOutputStream();
            //实例化响应的输出流对象,用来获取缓冲区中的文件内容
            FileInputStream fileInputStream = new FileInputStream(file);
            //实例化FileInputStream对象fileInputStream,用来读取文件内容
            byte[] bytes = new byte[1024];
            //创建一个1024byte大小的byte数组bytes用来作为放置获取到的文件内容
            while(true){
                int len = fileInputStream.read(bytes);
                //使用FileInputStream对象的read()方法读取文件内容,并将其存储到字节数组bytes中
                //read() 方法的返回值是实际读取到的字节数,若读取到文件末尾则返回值为-1
                if (len == -1) {
                    //读取结束
                    break;
                }
                outputStream.write(bytes);
                //将FileInputStream对象放入到bytes缓冲区中的文件内容写入响应的输出流对象outputStream中 
            }
            fileInputStream.close();
            outputStream.close();

2.4.4 查看图片内容完整代码

package api;

import dao.Image;
import dao.ImageDao;
import org.apache.commons.fileupload.FileItemFactory;
import sun.awt.image.ImageDecoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.sql.SQLException;
import java.util.HashSet;


//解析图片

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf-8");
        //1.获取ImageId
        String imageId = req.getParameter("imageId");
        if (imageId == null || imageId.equals("")) {
            resp.setStatus(200);
            resp.setContentType("application/json;charset=utf-8");
            resp.getWriter().write("{\"ok\":false ,\"reason\":\"imageId解析失败\"}");
            return;
        }
        //2.根据imageId查找数据库,图片类型和图片路径
        ImageDao imageDao = new ImageDao();
        Image image = new Image();
        try {
            image = imageDao.selectOneId(Integer.parseInt(imageId));
            //3.将查找出来的图片类型和图片内容(图片路径得出)返回给浏览器,图片内容(字节流)
            if(image ==null ){
                resp.setContentType("application/json;charset=utf-8");
                resp.getWriter().write("{\"ok\":false ,\"reason\":\"查找的imageId不存在\"}");
            }
            resp.setContentType(image.getContentType());
            File file = new File(image.getPath());
            OutputStream outputStream = resp.getOutputStream();
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] bytes = new byte[1024];
            while(true){
                int len = fileInputStream.read(bytes);
                if (len == -1) {
                    //读取结束
                    break;
                }
                outputStream.write(bytes);
            }
            fileInputStream.close();
            outputStream.close();


        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

    }
}

3.绑定URL

在WEB.xml文件中将类和URL绑定

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

  <servlet>
    <!--定义了一个叫ImageServlet的类映射到URL路径:/image-->
    <servlet-name>ImageServlet</servlet-name>
    <!--servlet类的完全限定名-->
    <servlet-class>api.ImageServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>ImageServlet</servlet-name>
    <!--URL路径:/image-->
    <url-pattern>/image</url-pattern>
  </servlet-mapping>

  <servlet>
    <!--定义了一个叫ImageShowServlet的类映射到URL路径:/imageShow-->
    <servlet-name>ImageShowServlet</servlet-name>
    <!--ImageShowServlet类的完全限定名-->
    <servlet-class>api.ImageShowServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>ImageShowServlet</servlet-name>
    <!--URL路径:/imageShow-->
    <url-pattern>/imageShow</url-pattern>
  </servlet-mapping>
  <servlet>

</web-app>


感谢您对大饼的支持
今天的你也很辛苦,晚安,明天见!

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值