• Java项目---图片服务器


    图片服务器--->服务器(图床)

    • 核心功能:上传图片、展示图片等

    比如:编写博客时我们会插入图片,本质上是往文章中放了一个链接(URL),这个URL资源在另外一个服务器上。

    • 核心知识点:

    (1)简单的Web服务器设计开发能力(Servlet)

    Web服务器--->HTTP服务器

    Servlet是Tomcat这个HTTP服务器所提供的一组编程接口

    (2)使用数据库来进行存储(MySQL)JDBC操作MySql

    (3)数据库设计(根据实际场景设计数据库表结构)

    (4)前后端交互的API的设计(基于HTTP协议)

    (5)认识JSON数据格式,学习使用Java中的Gson这个库操作JSON数据

    (6)学习测试一个HTTP服务器(Postman)

    (7)使用HTML CSS JavaScript技术构建一个简单的网页

    一、服务器设计

    1.数据库设计

    数据库中存储的是图片的属性(元信息);图片正文是以文件的形式直接存在磁盘上的;数据库中就记录一个path,path就对应到磁盘上的一个文件。

    • md5:图片的md5校验和(字符串哈希算法,哈希表)
    • 校验和:通过一个更短的字符串,来验证整体数据是否正确,短的字符串是根据原串内容通过一定的规则来计算出来的。

    2.服务器API设计(前后端交互接口设计)

    (1)JSON

    一种数据组织的格式,格式键值对的结构。JSON只是一种数据格式,和编程语言无关。

    JSON结构展示:

    1. {
    2. "name":"曹操",
    3. "skill1":"剑气",
    4. "skill2":"三段跳",
    5. "skill3":"加攻击和吸血",
    6. "skill4":"加攻速",
    7. }

    使用JSON完成数据的序列化方便完成网络传输。

    (2)Gson:google搞得一个开源的JSON解析库

    (3)文件上传操作在HTML中是如何完成的(用到form表单)

    文件上传在HTTP协议中是如何完成的

    • 开始设计前后端交互API

    1>新增图片

    请求:使用POST,POST到/image这个路径上

    Content-Type:multipart/from-data;

    (正文内容包含图片自身的一些信息)

    (图片正文的二进制内容)

    响应:(1)上传成功

    ①HTTP/1.1 200 OK 

    ②{

            "ok":true,

    }

    (2)上传失败

    ①HTTP/1.1 200 OK 

    ②{

            "ok":false,

            "reason":"具体的失败原因"

    }

    2>查看所有图片信息(数据库里面存的属性信息)

    请求:GET/image

    响应:①成功:HTTP/1.1 200 OK

    成功返回的数组:

    [

        {

              imageid:1,

              imageName:"1.png",

              contentType:"image/png",

              size:1000,

              uploadTime:"20200222",

              path:"./data/1.png",

              md5:"11223344",

         },

        {

             .........

        }

    ]

    ②:失败:HTTP/1.1 200 OK

    失败返回的数组:

    [](返回一个空数组)

    3>查看指定图片属性

    请求:GET/image?imageid=[具体的数值]

    响应:

    ①:成功

    HTTP/1.1 200 OK

    {

              imageid:1,

              imageName:"1.png",

              contentType:"image/png",

              size:1000,

              uploadTime:"20200222",

              path:"./data/1.png",

              md5:"11223344",

    }

    ②:失败

    HTTP/1.1 200 OK

    {

           ok:false,

           reason:"具体出错的原因"

    }

    4>删除指定图片

    请求:DELETE/image?image=[具体的图片id]

    响应:

    ①:成功

    HTTP/1.1 200 OK

    {

           ok:true,

    }

    ②:失败

    HTTP/1.1 200 OK

    {

            ok:false,

            reason:"具体的出错原因",

    }

    服务器实现代码的时候就可以判断方法,如果是DELETE方法就执行删除操作

    删除不一定非要用DELETE方法,也可以用:GET/image?image=xxx&delete=1

    5>查看指定图片内容

    请求:GET/imageShow?imageid=[具体的图片id]

    响应:

    ①:成功:

    HTTP/1.1 200 OK

    Content-Tpye:image/png

    [图片的二进制内容]

    ②:失败

    HTTP/1.1 200 OK

    {

          ok:false,

          reason:"[具体的出错原因]"

    }

    3.源码的开发

    1.数据库操作

    先创建DBUtil,封装一下获取数据库链接的过程

    dao--->数据访问层,这里面的类围绕着数据操作展开

    ctrl+alt+t--->选中一些代码,在这些代码外面包上一些其他代码

    二、实现代码

    1. package dao;
    2. public class Image {
    3. private int imageId;
    4. private String imageName;
    5. private int size;
    6. private String uploadTime;
    7. private String contentType;
    8. private String path;
    9. private String md5;
    10. public int getImageId() {
    11. return imageId;
    12. }
    13. public void setImageId(int imageId) {
    14. this.imageId = imageId;
    15. }
    16. public String getImageName() {
    17. return imageName;
    18. }
    19. public void setImageName(String imageName) {
    20. this.imageName = imageName;
    21. }
    22. public int getSize() {
    23. return size;
    24. }
    25. public void setSize(int size) {
    26. this.size = size;
    27. }
    28. public String getUploadTime() {
    29. return uploadTime;
    30. }
    31. public void setUploadTime(String uploadTime) {
    32. this.uploadTime = uploadTime;
    33. }
    34. public String getContentType() {
    35. return contentType;
    36. }
    37. public void setContentType(String contentType) {
    38. this.contentType = contentType;
    39. }
    40. public String getPath() {
    41. return path;
    42. }
    43. public void setPath(String path) {
    44. this.path = path;
    45. }
    46. public String getMd5() {
    47. return md5;
    48. }
    49. public void setMd5(String md5) {
    50. this.md5 = md5;
    51. }
    52. @Override
    53. public String toString() {
    54. return "Image{" +
    55. "imageId=" + imageId +
    56. ", imageName='" + imageName + '\'' +
    57. ", size=" + size +
    58. ", uploadTime='" + uploadTime + '\'' +
    59. ", contentType='" + contentType + '\'' +
    60. ", path='" + path + '\'' +
    61. ", md5='" + md5 + '\'' +
    62. '}';
    63. }
    64. }

    1.封装数据库操作(DAO层)

    DBUtil封装获取数据库链接的操作;

    Image对应到一个图片对象(包含图片的相关属性);

    ImageDao Image对象管理器,借助这个类完成Image对象的增删改查操作;

    ImageDao有一个selectAll方法,查找出所有数据库中的数据,但是如果有上亿条数据这样查找很低效,更科学的方法可以指定一些其他筛选条件(分页);

    • 出现异常之后的具体措施:
    • 1.当前接触过的大部分都是打印调用栈
    • 2.让程序直接终止
    • 3.通过监控报警通知程序员

    (JAR:类似于zip这样的压缩包,一大堆.class文件放在一起,打包成一个文件)

    ImageDao:
    1. package dao;
    2. import common.JavaImageServerException;
    3. import java.sql.Connection;
    4. import java.sql.PreparedStatement;
    5. import java.sql.ResultSet;
    6. import java.sql.SQLException;
    7. import java.util.ArrayList;
    8. import java.util.List;
    9. public class ImageDao {
    10. //把image对象插入到数据库中
    11. public void insert(Image image) {
    12. //1.获取数据库连接
    13. Connection connection=DBUtil.getConnection();
    14. //2.创建并拼装SQL语句
    15. String sql="insert into image_table values(null,?,?,?,?,?)";
    16. PreparedStatement statement=null;
    17. try {
    18. statement=connection.prepareStatement(sql);
    19. statement.setString(1, image.getImageName());
    20. statement.setInt(2,image.getSize());
    21. statement.setString(3,image.getUploadTime());
    22. statement.setString(4,image.getContentType());
    23. statement.setString(5,image.getPath());
    24. statement.setString(6,image.getMd5());
    25. //3.执行SQL语句
    26. int ret=statement.executeUpdate();
    27. if(ret!=1){
    28. //程序出现问题,抛出一个异常
    29. throw new JavaImageServerException("插入大户巨款出错");
    30. }
    31. } catch (SQLException e) {
    32. e.printStackTrace();
    33. }catch (JavaImageServerException e){
    34. e.printStackTrace();
    35. }finally{
    36. //4.关闭连接和statement对象
    37. DBUtil.close(connection,statement,null);
    38. }
    39. }
    40. //查找数据库中的所有图片的信息
    41. public List selectAll(){
    42. List images=new ArrayList<>();
    43. //1、获取数据库连接
    44. Connection connection=DBUtil.getConnection();
    45. //2.构造SQL语句
    46. String sql="select * from image_table";
    47. PreparedStatement statement=null;
    48. ResultSet resultSet=null;
    49. try {
    50. //3.执行sql语句
    51. statement=connection.prepareStatement(sql);
    52. resultSet=statement.executeQuery();
    53. //4.处理结果集
    54. while(resultSet.next()){
    55. Image image=new Image();
    56. image.setImageId(resultSet.getInt("imageId"));
    57. image.setImageName(resultSet.getString("imageName"));
    58. image.setSize(resultSet.getInt("size"));
    59. image.setUploadTime(resultSet.getString("uploadTime"));
    60. image.setContentType(resultSet.getString("contentType"));
    61. image.setPath(resultSet.getString("path"));
    62. image.setMd5(resultSet.getString("md5"));
    63. images.add(image);
    64. }
    65. return images;
    66. }catch (SQLException e){
    67. e.printStackTrace();
    68. }finally{
    69. //关闭连接
    70. DBUtil.close(connection,statement,resultSet);
    71. }
    72. return null;
    73. }
    74. //根据imageId查找指定的图片信息
    75. public Image selectOne(int imageId){
    76. //1.获取数据库连接
    77. Connection connection=DBUtil.getConnection();
    78. //2.构造SQL语句
    79. String sql="select * from image_table where imageId = ?";
    80. PreparedStatement statement=null;
    81. ResultSet resultSet=null;
    82. //3.执行SQL语句
    83. try {
    84. statement=connection.prepareStatement(sql);
    85. statement.setInt(1,imageId);
    86. resultSet =statement.executeQuery();
    87. //4.处理结果集
    88. if(resultSet.next()){
    89. Image image=new Image();
    90. image.setImageId(resultSet.getInt("imageId"));
    91. image.setImageName(resultSet.getString("imageName"));
    92. image.setSize(resultSet.getInt("size"));
    93. image.setUploadTime(resultSet.getString("uploadTime"));
    94. image.setContentType(resultSet.getString("contentType"));
    95. image.setPath(resultSet.getString("path"));
    96. image.setMd5(resultSet.getString("md5"));
    97. return image;
    98. }
    99. } catch (SQLException e) {
    100. e.printStackTrace();
    101. }finally{
    102. //5.关闭连接
    103. DBUtil.close(connection,statement,resultSet);
    104. }
    105. return null;
    106. }
    107. //根据imageId删除指定图片
    108. public void delete(int imageId){
    109. //1、获取数据库连接
    110. Connection connection=DBUtil.getConnection();
    111. //2.拼装SQL语句
    112. String sql="delete * from image_table where imageId = ?";
    113. PreparedStatement statement=null;
    114. // ResultSet resultSet=null;
    115. //3.执行SQL语句
    116. try {
    117. statement=connection.prepareStatement(sql);
    118. statement.setInt(1,imageId);
    119. int ret =statement.executeUpdate();
    120. //4.处理结果集
    121. if(ret!=1){
    122. throw new JavaImageServerException("删除数据库操作失败")
    123. }
    124. } catch (SQLException | JavaImageServerException e) {
    125. e.printStackTrace();
    126. }finally{
    127. //4.关闭连接
    128. DBUtil.close(connection,statement,null);
    129. }
    130. }
    131. public static void main(String[] args) {
    132. //用于进行简单的测试
    133. //1.测试插入数据
    134. // Image image=new Image();
    135. // image.setImageName("1.png");
    136. // image.setSize(100);
    137. // image.setUploadTime("2023");
    138. // image.setContentType("image/png");
    139. // image.setPath("./date/1.png");
    140. // image.setMd5("112233");
    141. // ImageDao imageDao=new ImageDao();
    142. // imageDao.insert(image);
    143. //2.测试查找所有图片信息
    144. // ImageDao imageDao=new ImageDao();
    145. // List images=imageDao.selectAll();
    146. // System.out.println(images);
    147. //3.测试查找指定图片信息
    148. ImageDao imageDao=new ImageDao();
    149. Image image=imageDao.selectOne(1);
    150. System.out.println(image);
    151. //4.测试查找指定图片信息
    152. ImageDao imageDao=new ImageDao();
    153. imageDao.delete(1);
    154. }
    155. }

    2.基于Servlet来搭建服务器

    (1)安装Servlet

    (2)创建一个类,继承HttpServlet父类(重写父类中的一些重要方法)

    如果服务器收到的是GET方法,就会自动调用HttpServlet的doGet方法;

    如果服务器收到的是POST方法,就会自动调用HttpServlet的doPost方法;

    如果服务器收到的是DELETE方法,就会自动调用HttpServlet的doDelete方法;

    HttpServletRequest req--->请求(方法、url、各种header、body)
    HttpServletResponse resp--->响应(状态码、各种header、body)
    

    给网页上显示一个hello world,修改请求还是修改响应--->修改响应;当代码写完之后,还需要修改webapp/WEB-INF/web.xml把新创建的Servlet注册进去:

    1. xml version ="1.0" encoding =" UTF -8"?>
    2. app xmlns ="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation ="http://xmlns.jcp.org/xm1/ns/javaee
    5. http://xmIns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    6. version ="3.1"
    7. metadata-complete =" true ">
    8. Hello
    9. HelloServlet
    10. Hello
    11. / hello-servlet

    标签-->>告诉Tomcat当前这个servlet对应到代码中的那个类

    标签-->>告诉Tomcat当前这个servlet对应到的URL的path是什么

    三、基于Servlet搭建好项目的后端部分

    部署:

    (1)使用maven打包(war) maven package

    (2)把war包拷贝到tomcat的webapps目录中

    部署完之后,就可以在浏览器(http客户端)中访问服务器了。

    http://47.98.116.42:8080/java_image_server/image

    java_image_server----->war包的名字;image---->web.xml配置的内容

    • ImageServlet:

    (1)上传图片

    需要用到第三方库

    对于JSON格式的响应,需要把content-type设定成指定格式

    如果有两个图片,内容不同,但是名字相同,此时会出现上传失败的情况;应该让每次上传图片对应的路径都不相同(在路径上加上时间戳)

    (2)查看所有图片信息

    (3)查看所有指定图片信息

    (4)删除指定图片

    代码:

    1. package api;
    2. import dao.Image;
    3. import dao.ImageDao;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import java.io.File;
    9. import java.io.IOException;
    10. import java.text.SimpleDateFormat;
    11. import java.util.Date;
    12. import java.util.List;
    13. public class ImageServlet extends HttpServlet {
    14. //查看图片属性,既能查看所有,也能查看指定
    15. @Override
    16. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws SecurityException, ServletException, IOException {
    17. //考虑到查看所有图片属性和查看指定图片属性
    18. //通过是否URL中带有imageId参数来进行区分
    19. //存在imageId查看指定图片属性,否则就查看所有图片属性
    20. //例如:URL/image?imageId=100
    21. //imageId的值就是"100"
    22. //如果URL中不存在imageId那么返回null
    23. String imageId =req.getParameter("imageId");
    24. if(imageId==null || imageId.equals("")){
    25. //查看所有图片属性
    26. selectAll(req,resp);
    27. }else{
    28. //查看指定图片
    29. selectOne(imageId,resp);
    30. }
    31. // //req对象中包含了请求中的所有信息
    32. // //resp对象要生成的结果就放到里面去
    33. // //当前这个doGet方法就是要根据请求,生成响应
    34. // resp.setStatus(200);
    35. // //这个代码就是把hello这个字符串放到http响应的body中了
    36. // resp.getWriter().write("hello");
    37. }
    38. private void selectAll(HttpServletRequest req,HttpServletResponse resp){
    39. //1.创建一个ImageDao对象,并查找数据库
    40. ImageDao imageDao=new ImageDao();
    41. List images=imageDao.selectAll();
    42. //2.把查找到的结果转成JSON格式的字符串,并且写回到resp对象
    43. Gson gson=new GsonBuilder().create();
    44. //jsonData就是一个json格式的字符串,和之前约定的格式是一样的
    45. String jsonDate=gson.toJson(images);
    46. resp.getWriter().write(jsonDate);
    47. }
    48. private void selectOne(String imageId,HttpServletResponse resp){
    49. resp.setContentType("application/json;charset=utf-8");
    50. //1.创建ImageDao对象
    51. ImageDao imageDao=new ImageDao();
    52. Image image=imageDao.selectOne(Integer.parseInt(imageId));
    53. //2.使用gson把查看到的数据转成json格式,并写回给响应对象
    54. Gson gson=new GsonBuilder().create;
    55. String jsonData=gson.toJson(image);
    56. resp.getWriter().write(jsonData);
    57. }
    58. //上传图片
    59. @Override
    60. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    61. //1.获取图片的属性信息,并且存入数据库
    62. //1>需要创建一个factory对象,和upload对象,为了获取到图片属性做的准备工作
    63. FileItemFactory factory=new DiskFileItemFactory();
    64. ServletFileUpload upload=new ServletFileUpload(factory);
    65. //2>通过upload对象进一步解析请求
    66. List items=null;
    67. try{
    68. items=upload.paresRequest(req);
    69. }catch(FileUploadException e){
    70. //出现异常说明解析出错
    71. e.printStackTrace();
    72. //告诉客户端出现的具体的错误是什么
    73. resp.setContentType("application/json;charset=utf-8");
    74. resp.getWriter().write("{\"ok\":false,\"reason\",\"请求解析失败\"}");
    75. return;
    76. }
    77. //3>把FileItem中的属性提取出来,转换成Image对象,才能存到数据库中
    78. //当前只考虑一张图片的情况
    79. FileItem fileItem=item.get(0);
    80. Image image=new Image();
    81. image.setImageName(fileItem.getName());
    82. image.setSize((int)fileItem.getSize());
    83. //手动获取一下当前日期,并转换成格式化日期
    84. SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
    85. image.setUploadTime(simpleDateFormat.format(new Date()));
    86. image.setContentType(fileItem.getContentType());
    87. //自己构造一个路径来保存,引入时间戳为了让文件能够唯一
    88. image.setPath("./image/"+System.currentTimeMillis()+"_"+image.getImageName());
    89. //TODO MD5(先不管,写死)
    90. image.setMD5("112233");
    91. //存到数据库中
    92. ImageDao imageDao=new ImageDao();
    93. imageDao.insert(image);
    94. //2.获取图片的内容信息,并且写入磁盘文件
    95. File file=new File(image.getPath());
    96. try{
    97. fileItem.write(file);
    98. }catch(Exception e){
    99. e.printStackTrace();
    100. resp.setContentType("application/json;charset=utf-8");
    101. resp.getWriter().write("{\"ok\":false,\"reason\",\"写磁盘失败\"}");
    102. return;
    103. }
    104. //3.给客户端返回一个结果数据
    105. //resp.setContentType("application/json;charset=utf-8");
    106. // resp.getWriter().write("{\"ok\":true}");
    107. resp.sendRedirect("index.html");
    108. }
    109. //删除指定图片
    110. @Override
    111. protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    112. resp.setContentType("application/json;charset=utf-8");
    113. //1.先获取到请求中的imageId
    114. String imageId=req.getParameter("imageId");
    115. if(imageId==null || imageId.equals("")){
    116. resp.setStatus(200);
    117. resp.getWriter().write("{\"ok\":false,\"reason\",\"解析请求失败\"}");
    118. return;
    119. }
    120. //2.传教imageDao对象,查看到该图片对象对应的相关属性(为了知道这个图片对应的文件路径)
    121. ImageDao imageDao=new ImageDao();
    122. Image image=imageDao.selectOne(Integer.parseInt(ImageId));
    123. if(image==null){
    124. //此时请求中传入的id在数据库中不存在
    125. resp.setStatus(200);
    126. resp.getWriter().write("{\"ok\":false,\"reason\",\"image在数据库中不存在\"}");
    127. return;
    128. }
    129. //3.删除数据库中的记录
    130. imageDao.delete(Integer.parseInt(imageId));
    131. //4.删除本地磁盘文件
    132. File fule=new File(image.getPath());
    133. file.delete();
    134. resp.setStatus(200);
    135. resp.getWriter().write("{\"ok\":true}");
    136. }
    137. }
    • ImageShowServlet

    代码:

    1. package api;
    2. import dao.Image;
    3. import dao.ImageDao;
    4. import javax.servlet.ServletException;
    5. import javax.servlet.http.HttpServlet;
    6. import javax.servlet.http.HttpServletRequest;
    7. import javax.servlet.http.HttpServletResponse;
    8. import java.io.File;
    9. import java.io.FileInputStream;
    10. import java.io.IOException;
    11. import java.io.OutputStream;
    12. public class ImageShowServlet extends HttpServlet {
    13. @Override
    14. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    15. //1.解析出imageId
    16. String imageId=req.getParameter("imageId");
    17. if(imageId==null || imageId.equals("")){
    18. resp.setContentType("application/json;charset=utf-8");
    19. resp.getWriter().write("{\"ok\":false,\"reason\",\"imageId解析失败\"}");
    20. return;
    21. }
    22. //2.根据imageId查找数据库,得到对应的图片属性信息(需要知道图片存储的路径
    23. ImageDao imageDao=new ImageDao();
    24. Image image=imageDao.selectOne(Integer.parseInt(ImageId));
    25. //3.根据路径打开文件,读取其中的内容,写入到响应对象中
    26. resp.setContentType(image.getContentType());
    27. File file=new File(image.getPath());
    28. //由于图片是二进制文件,应该使用字节流的方式读取文件
    29. OutputStream outputStream=resp.getOutputStream();
    30. FileInputStream fileInputStream=new FileInputStream(file);
    31. byte[] buffer=new byte[1024];
    32. while(true){
    33. int len=fileInputStream.read(buffer);
    34. if(len==-1){
    35. //文件读取结束
    36. break;
    37. }
    38. //此时语句读到一部分数据,放到buffer里面,把buffer中的内容写到响应对象中
    39. outputStream.write(buffer);
    40. }
    41. fileInputStream.close();
    42. outputStream.close();
    43. }
    44. }

    四、实现前端页面(展示图片,增删操作)、

    • 实现前端页面主要应用的技术:

    (1)HTML-->网页的骨架;

    (2)CSS--->描述网页上组件的样式(位置、大小、颜色等);

    (3)JavaScript:描述前端页面上的一些动作(和用户具体交互的行为)

    (HTML、CSS、JavaScript可以写到一个HTML文件中,也可以分开写)

    把网页上显示的这些预览图片替换成服务器上保存的图片,img标签中scr改成服务器上存在的图片的url就可以了;

    需要获取到服务器上所有图片的url(ImageServlet),需要通过JS先获取到所有图片的属性,再分别加载每一个图片;使用JS来完成。

    • 主流的前端框架

    (1)Vue

    1. var app = new Vue({
    2. el: '#app',
    3. data: {
    4. message: 'Hello Vue!'
    5. }
    6. })

    (2)React(facebook)

    (3)Auglar(google)

    JS中变量类型都是在初始化的时候自动推导的

    var声明这是一个变量;

    Vue所做的最核心的工作,把页面显示的内容和JS中的代码相互关联到一起;

    修改js中的变量就能很方便的影响的页面的显示情况。

    1. var app = new Vue({
    2. el:'#app',
    3. data: {
    4. images: [
    5. {
    6. imageId: 1,
    7. imageName: "1.png",
    8. contentType: "image/png",
    9. md5: "aabbccdd",
    10. },
    11. {
    12. imageId: 2,
    13. imageName: "2.png",
    14. contentType: "image/png",
    15. md5: "aabbccdd",
    16. }
    17. }
    18. },
    19. methods: {
    20. },
    21. });

    Vue对象中构造一组写死的数据,先去借助这组数据来渲染页面

    Vue中的命令:

    1>v-for--->>循环访问一个数据

    2>v-bind-->>把数据绑定到html标签上的某个属性

    1. "am-g am-g-fixed blog-fixed blog-content">
    2. "figure" class="am am-figure am-figure-default " data-am-figure="
    3. { pureview: 'true' }">
    4. "container">
    5. for="image in images">
    6. " 'imageShow?imageId=' + image.imageId "
    7. style="height:200px;width:200px">
    8. {{image.imageName}}

  • 3>v-on-->>绑定某种事件的处理函数(点击鼠标、双击、右键等)

    1. remove(image_id) {
    2. $.ajax({
    3. url:"image?image_id=" + image_id,
    4. type:"delete",
    5. context: this,
    6. success: function(data, status) {
    7. this.getImages();
    8. alert("删除成功");
    9. }
    10. })
    11. }

    如果是在标签内部使用Vue对象中的数据,就需要使用插值表达式;

    如果是在标签属性中使用Vue对象中的数据,步需要使用插值表达式,但要搭配Vue的命令;

    images这个数组里面的内容是写死的,接下里通过浏览器中JS代码请求服务器,获取到服务器上都有那些图片,把这个数据作为Vue渲染的依据(Vue对象中的images数组)

    1. getImages() {
    2. $.ajax({
    3. url: "image",
    4. type: "get",
    5. context: this,
    6. success: function(data, status) {
    7. this.images = data;
    8. // 这个代码用来触发 resize 事件.
    9. $("#app").resize();
    10. }
    11. })
    12. },

    ajax:JSz中构造HTTP请求发送给服务器的一种实现方式

    原来页面的渲染过程:

    1>先加载图片

    2>再根据图片大小设定图片的位置,设定显示图片的空间大小

    使用ajax来渲染:

    1>页面先尝试获取页面的大小,并设定显示图片的空间(当前图片还没有获取到,不知道图片的大小)

    2>通过ajax获取图片内容

    改进上传操作,上传成功之后,自动跳转到主页index.html  HTTP重定向

    实现删除图片,浏览器给服务器发送一个DELETE/image?imageId=xxx这样的请求就可以了(ajax完成)

    拓展:

    (1)简单的防盗链机制(通过一定的机制来限制其他人来使用图片)

    可以判定当前请求的referer爱段(HTTP请求协议中的header部分),是不是在我们代码指定的白名单中,如果是,就可以访问。

    referer-->表示当前请求的上一个页面的地址

    再代码中用一个hashSet存一下允许访问的Referer就可以了,展示图片的时候判断一下是否再hashSet中存在即可。

    (2)优化磁盘空间

    应用到MD5,如果两个图片内容完全一样,就在磁盘上存一份就可以了。通过MD5可以判断两个图片内容是否一样。

    图片文件虽然是二进制数据,但是本质上也是字符串,针对图片内容计算MD5。

    如果两个图片内容相同,得到的MD5一定是相同的,反之,近似认为MD5相同,原图内容一定相同。

    理论上使是有可能两个图片的内容不同,MD5相同,但实际上出现概率极低(MD5自身算法设计上引起的特性)

    实现思路:

    上传图片的时候,先判定新图片的MD5在数据库中是否存在,如果已经存在了,就不用把图片内容写到磁盘上,如果不存在就写到磁盘上。

    1>该上传代码的逻辑,磁盘文件名用md5值来表示

    2>修改ImageDao新增一个接口,能按照MD5查找数据库内容

    3>修改上传图片的逻辑,根据MD5判定当前图片是是否要写磁盘

  • 相关阅读:
    vueDay04——v-if else show
    【Python爬虫】过来人告诉你:为什么找工作抓住这个细节,能少踩很多坑哦~(招聘网站实战)
    MediaBox助力企业一站式获取音视频能力
    gitlab安装配置及应用
    ts学习02-数据类型
    在 Azure ML 上用 .NET 跑机器学习
    QT基础教程(QDebug和QString)
    小猿圈Java讲师分享开发9年Java进阶大全
    数据可视化之交通可视化
    手写vue路由
  • 原文地址:https://blog.csdn.net/m0_58272200/article/details/132800586