数据库和SpringBoot基础02

实例一:实现注册和登录功能

首页:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>工程首页</h1>
<a href="/reg.html">注册</a>
<a href="/login.html">登录</a>
</body>
</html>

注册页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>注册页面</h1>
<div>
  <input type="text" v-model="user.username" placeholder="请输入用户名">
  <input type="text" v-model="user.password" placeholder="请输入密码">
  <input type="text" v-model="user.nick" placeholder="请输入昵称">
  <input type="button" value="注册" @click="reg()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    let v = new Vue({
        el:"div",
        data:{
            user:{
                username:"",
                password:"",
                nick:""
            }
        },
        methods:{
            reg(){
                //发出post 把装着用户信息的user对象提交
                axios.post("/reg",v.user).then(function (response){
                    //判断如果注册成功 返回首页
                    if(response.data==1){
                        alert("注册成功!")
                        //让浏览器显示到首页
                        location.href="/";
                    }else{
                        alert("用户名已存在!");
                    }
                })
            }
        }
    })
</script>
</body>
</html>

登录页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录页面</h1>
<div>
  <input type="text" v-model="user.username" placeholder="用户名">
  <input type="text" v-model="user.password" placeholder="密码">
  <input type="button" value="登录" @click="login()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
  let v = new Vue({
    el:"div",
    data:{
      user:{
        username:"", password:""
      }
    },
      methods:{
        login(){
          //发出异步post请求
            axios.post("/login",v.user).then(function (response){
                //判断如果登录成功 返回首页
                if(response.data==1){
                    alert("登录成功!")
                    //让浏览器显示到首页
                    location.href="/";
                }else if(response.data==2){
                    alert("用户名不存在!");
                }else{
                    alert("密码错误!")
                }
            })
        }
      }

  })
</script>
</body>
</html>

功能实现类;


@RestController
public class UserController {
    @Autowired
    UserMapper mapper;

    @RequestMapping("/reg")
    public int reg(@RequestBody User user){
        User u = mapper.selectByUsername(user.getUsername());
        if(u!=null){
            return 2;//"用户名已存在!"
        }
        //执行注册
        mapper.insert(user);
        return 1;//"注册成功!"
    }

    @RequestMapping("/login")
    public int login(@RequestBody User user){
        //拿用户输入的用户名查询数据库里面的用户信息
        User u = mapper.selectByUsername(user.getUsername());
        if(u!=null){ //代表查询到了用户信息
            //判断用户输入的密码和查询到的密码是否一致
            if(user.getPassword().equals(u.getPassword())){
                return 1;//登录成功!
            }
            return 3;//密码错误!
        }
        return 2;//代表用户名不存在
    }

}

mapper类:

@Mapper
public interface UserMapper {
    //如果返回值为一个对象而非List集合 要求查询回来的结果必须是0条或者1条
    //如果出现了大于1条的情况会报错
    @Select("select *from user where username=#{username}")
    User selectByUsername(String username);

    @Insert("insert into user values(null,#{username},#{password},#{nick})")
    void insert(User user);

}

User类:

后端的MVC设计模式

  • 把实现一个业务的代码划分为三部分,分别是: 页面相关(V),业务逻辑相关(C),数据相关(M)
  • M:Model 数据模型, 对应的代码是数据库相关的Mapper部分
  • V:View 视图, 对应所有页面相关内容
  • C:Controller 控制器,对应的是Controller相关代码
  • 实现一个业务的顺序: V页面相关代码->C Controller相关代码->M 数据库Mapper相关代码
  • 排错时也是从这三部分代码中找问题
  • 后端MVC涉及模式中的V页面相关,前端工程师将页面又划分为了MVC三部分

前后端分离 

 如果前后端不分离, 后端服务器需要两套代码来应对 手机客户端和浏览器客户端, 因为不同的客户端的需求内容是不一样的,这样后端的开发效率就会受影响.

 前后端分离:指在Controller中不再处理页面相关内容, 浏览器客户端需要先请求页面,页面加载完之后从页面中再次发出请求获取数据, 得到数据后把数据展示在页面中,这个过程属于页面的局部刷新, 同步请求只能实现页面的整体刷新无法实现局部刷新, 所以以后不再使用同步请求, 全部使用异步请求,因为以后工作基本全是前后端分离思想.

JSON

  • JSON是一种轻量级的数据交换格式(数据封装格式)
  • 客户端和服务器之间需要互相传递数据,当需要传递复杂数据时需要按照特定的格式将数据进行封装,JSON就是这样一个通用格式.

登录成功

用户名已存在

密码错误

1

2

3

"id=1, title=手机 , price=1000, saleCount=500"

[{"id":1,"title":"阿迪袜子","price":10.0,"saleCount":1000},{"id":3,"title":"裤子","price":50.0,"saleCount":400},{"id":4,"title":"袜子","price":5.0,"saleCount":100}]

服务器和客户端之间如何传递复杂数据 

商品管理添加商品步骤:

1、创建工程 3个打钩 修改application.properties配置文件, 启动工程测试是否成功

2、创建index.html首页 和 insert.html页面

3、在insert.html页面中添加三个文本框和一个添加按钮, 通过Vue对页面内容进行管理,此时需要把之前工程中的js文件夹复制到新工程, 当点击添加按钮时向/insert地址发出异步post请求把用户输入的商品信息提交

4、创建controller.ProductController 添加insert方法处理/insert请求 创建Product实体类 在insert方法中声明用来接收传递过来的参数(此参数需要通过@RequestBody注解进行修饰

5、创建ProductMapper 在里面添加insert方法通过@Insert注解修饰

6、在Controller中将ProductMapper装配进来, 在insert方法中调用mapper的insert方法把接收到的Product对象传递过去

商品管理商品列表步骤:

1、在index.html页面中添加商品列表超链接 请求地址为/list.html页面

2、创建list.html页面, 在页面中添加表格,并且通过Vue进行管理,在Vue的created方法中发出异步的get请求,把请求回来的数据交给一个数组变量, 然后让页面中表格的内容和数据变量进行绑定, 当数组有值时页面会自动显示数据

3、在ProductController中添加select方法 处理/select请求,方法中调用mapper的select方法 把得到的List集合直接返回给客户端

4、实现 mapper里面的select方法

商品管理删除商品步骤:

1、在商品列表页面中添加删除的超链接 ,废掉超链接的跳转功能添加点击事件,调用del方法, 在方法中向/delete发出异步get请求并且把商品的id传递过去

2、在ProductController中 添加delete方法处理/delete请求在方法中调用mapper的deleteById方法把接收到的id传递进去

3、实现mapper里面的deleteById方法

商品管理修改商品步骤:

1、给列表页面添加 修改超链接 往/update.html页面跳转 并且传递过去商品id

2、创建update.html页面 在Vue的created方法中得到传递过来的id 然后向/selectById 发出异步的get请求 把id传递过去 把服务返回的数据用一个product对象接收, 并且页面内容和此对象进行绑定 这样对象有值页面就能跟着显示

3、在ProductController里面添加selectById方法 处理/selectById请求, 在方法中调用Mapper的selectById方法

4、实现mapper里面的selectById方法

5、给update.html页面中的修改按钮添加点击事件, 点击时向/update地址发出异步的post请求把商品的信息一起提交

6、在ProductController里面添加update方法处理/update请求,在方法中掉用mapper的update方法

7、实现mapper里面的update方法 .

实例二:商品管理实例

首页:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>商品管理首页</h1>
<a href="/insert.html">添加商品</a>
<a href="/list.html">商品列表</a>
</body>
</html>

添加商品页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>添加商品</h1>
<div>
  <input type="text" v-model="p.title" placeholder="商品标题">
  <input type="text" v-model="p.price" placeholder="商品价格">
  <input type="text" v-model="p.saleCount" placeholder="商品销量">
  <input type="button" value="添加" @click="insert()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    let v = new Vue({
        el:"div",
        data:{
            p:{
                title:"",
                price:"",
                saleCount:""
            }
        },
        methods:{
            insert(){
                //发出异步请求
                axios.post("/insert",v.p).then(function (response){
                    alert("添加完成!")
                    location.href="/";
                })
            }
        }
    })
</script>
</body>
</html>

商品列表页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1> 商品列表</h1>
<table border="1">
  <tr>
    <th>商品id</th>
    <th>商品标题</th>
    <th>商品价格</th>
    <th>商品销量</th>
      <th>操作</th>
  </tr>
    <tr v-for="p in arr">
        <td>{{p.id}}</td>
        <td>{{p.title}}</td>
        <td>{{p.price}}</td>
        <td>{{p.saleCount}}</td>
        <!--javascript:void(0):废掉超连接自身的跳转功能-->
        <td><a href="javascript:void(0)" @click="del(p.id)">删除</a>
            <!--点击修改需要跳转页面 所以不能和删除一样废掉跳转功能-->
            <!--元素的属性里面出现变量 需要进行属性绑定-->
            <a :href="'/update.html?id='+p.id">修改</a>
        </td>
    </tr>
</table>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    let v = new Vue({
        el:"table",
        data:{
            arr:[]
        },
        created:function (){//此方法是Vue对象创建时执行的方法
            //一般会把加载完页面请求数据的代码 写在此方法中
            //发出异步请求获取数据
            axios.get("/select").then(function (response){
                //服务器返回的数据直接给到arr数组 由于页面和数组进行了绑定
                //数组值发生改变时页面会自动发生改变

                //服务器传递过来的是二进制的数据Axios框架会先将二进制的数据转回JSON格式的字符串
                //转完字符串之后会再将JSON格式的字符串转成数组或对象
                v.arr = response.data;
            })
        },
        methods:{
            del(id){
                //发出删除的异步请求
                axios.get("/delete?id="+id).then(function (response){
                    alert("删除完成!");
                    location.reload();//刷新页面
                })
            }
        }
    })
</script>
</body>
</html>

修改商品页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>修改商品页面</h1>
<div>
  <input type="text" v-model="product.id" placeholder="id" readonly>
  <input type="text" v-model="product.title" placeholder="标题">
  <input type="text" v-model="product.price" placeholder="价格">
  <input type="text" v-model="product.saleCount" placeholder="销量">
  <input type="button" value="修改" @click="update()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
  let v = new Vue({
    el:"div",
    data:{
        /*可以动态的添加属性*/
        product:{}
    },
    created:function (){
        //页面加载完之后 得到商品的id 通过id查询商品信息 并显示到页面中
        //从地址栏中得到id参数
      let id = location.search.split("=")[1];
        //发出异步请求通过id查询对应的商品信息
        axios.get("/selectById?id="+id).then(function (response){
            //把服务器查询回来的商品信息赋值给Vue里面的product变量
            //让页面和product对象进行绑定 当product得到值页面就会显示出来
            v.product = response.data;
        })
    },
      methods:{
          update(){
              //发出异步post请求
              axios.post("/update",v.product).then(function (response) {
                  alert("修改完成!");
                  location.href="/list.html";
              })
          }
      }
  })
</script>
</body>
</html>

 ProductController功能实现类:

import java.util.List;

@RestController
public class ProductController {
    @Autowired
    ProductMapper mapper;
    @RequestMapping("/insert")
    public void insert(@RequestBody Product product){
        System.out.println(product.toString());
        mapper.insert(product);
    }

    @RequestMapping("/select")
    public List<Product> select(){
        // SpringMVC框架当发现返回值类型为集合或自定义的对象类型时,
        //会将集合或对象转成JSON格式的字符串,然后再将JSON格式字符串转成二进制数据进行网络传输
        //[{"id":1,"title":"阿迪袜子","price":10.0,"saleCount":1000},{"id":3,"title":"裤子","price":50.0,"saleCount":400},{"id":4,"title":"袜子","price":5.0,"saleCount":100}]
        List<Product> list = mapper.select();

        return list;
    }

    @RequestMapping("/delete")
    public void delete(int id){
        System.out.println("id = "+id);
        mapper.deleteById(id);
    }

    @RequestMapping("/selectById")
    public Product selectById(int id){
        System.out.println("id = "+id);
        //当SpringMVC框架发现返回的是一个自定义对象会自动转成JSDN格式的字符串
        return mapper.selectById(id);
    }

    @RequestMapping("/update")
    public void update(@RequestBody Product product){
        mapper.update(product);
    }

}

Product类:

 mapper类:

import java.util.List;

@Mapper
public interface ProductMapper {
    @Insert("insert into product values(null,#{title},#{price},#{saleCount})")
    void insert(Product product);

    @Select("select *from product")
    @Result(property = "saleCount",column = "sale_count")
    List<Product> select();

    @Delete("delete from product where id=#{id}")
    void deleteById(int id);

    @Select("select *from product where id=#{id}")
    @Result(property = "saleCount",column = "sale_count")
    Product selectById(int id);

    @Update("update product set title=#{title},price=#{price},sale_count=#{saleCount} where id=#{id}")
    void update(Product product);
}

实例三:实现文件上传功能

首页:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <!-- import CSS -->
  <link rel="stylesheet" href="css/eui.css">
</head>
<body>
<div id="app">
  <!--name代表上传文件时 文件的参数名-->
  <el-upload
          action="/upload"
          name="picFile"
          list-type="picture-card"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove">
    <i class="el-icon-plus"></i>
  </el-upload>
  <el-dialog :visible.sync="dialogVisible">
    <img width="100%" :src="dialogImageUrl" alt="">
  </el-dialog>
</div>
</body>
<!-- import Vue before Element -->
<script src="js/vue.js"></script>
<!-- import JavaScript -->
<script src="js/eui.js"></script>
<script src="js/axios.min.js"></script>
<script>
  let v = new Vue({
    el: '#app',
    data: function() {
      return {
        dialogImageUrl: '',
        dialogVisible: false
      }
    },
    methods: {
      handleRemove(file, fileList) {
        console.log(file, fileList);
        //当点击删除图片时方法会执行
        //file代表要删除的文件
        //file.response代表文件上传成功时 服务器响应的数据(文件名)
        console.log("文件名="+file.response);
        axios.get("/remove?name="+file.response).then(function (response) {
          console.log("服务器图片已经删除")
        })
      },
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      }
    }
  })
</script>
</html>
@RestController
public class UploadController {
    @RequestMapping("/upload")
    public String upload(MultipartFile picFile) throws IOException {
        System.out.println("picFile = " + picFile);
        //得到文件原始文件名  a.jpg
        String fileName = picFile.getOriginalFilename();
        //得到后缀名  从最后一个.出现的位置截取到最后
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        //得到唯一文件名  UUID.randomUUID()得到一个唯一标识符
        fileName = UUID.randomUUID()+suffix;
        System.out.println("文件名:"+fileName);
        //准备保存图片的文件夹路径
        String dirPath = "F:/files";
        File dirFile = new File(dirPath);
        //如果该文件夹不存在 则创建此文件夹
        if (!dirFile.exists()){
            dirFile.mkdirs();//创建文件夹
        }
        //得到文件的完整路径
        String filePath = dirPath+"/"+fileName;
        //把文件保存到此路径   异常抛出
        picFile.transferTo(new File(filePath));
        System.out.println("文件保存完成! 请去此路径检查文件是否存在 "+filePath);

        return fileName;
    }

    @RequestMapping("/remove")
    public void remove(String name){
        String dirPath = "F:/files";
        String filePath = dirPath+"/"+name;
        new File(filePath).delete();//删除文件
    }

}

微博练习步骤

1、创建boot5-1工程 3个打钩

2、配置文件中添加以下内容(empdb改成weibo) ,并启动工程检查是否能够成功运行

spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/weibo?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false

spring.servlet.multipart.max-file-size=10MB

3、创建数据库和表

create database weibo charset=utf8;

use weibo;

create table user(id int primary key auto_increment,username varchar(50),password varchar(50),nick varchar(50))charset=utf8;

4、在工程中添加首页index.html 在工程中添加js和css文件夹(从4-2工程中复制),添加完之后 Buil->ReBuild

5、创建微博表

use weibo;

create table weibo(id int primary key auto_increment,content varchar(100),url varchar(255),nick varchar(50),created timestamp,user_id int)charset=utf8;

会话管理

1、客户端和服务器之间进行数据传输遵循的是HTTP协议,此协议属于无状态协议(一次请求对应一次响应,响应完之后链接就会断开) 服务器是无法跟踪客户端的请求.通过Cookie服务器可以给客户端添加一个标识,当客户端再次发出请求时会带着这个Cookie这样服务器就能识别此客户端了, 但是由于Cookie是保存在客户端的存在被篡改的风险,Session的出现解决了此问题

2、Cookie: 打孔式会员卡, 数据保存在客户端

  • 只能保存字符串数据
  • 默认数据是保存在浏览器内存中,当会话结束(浏览器关闭)数据会删除, 也可以设置自定义的保存时长,设置完之后数据会保存在磁盘中时间到了之后清除.
  • 应用场景: 需要长时间保存的数据,比如:记住用户名和密码

3、Session:相当于银行卡, 数据保存在服务器内存中(工程重新启动会清空所有Session)

  • 可以保存任意对象类型的数据
  • 默认数据只能保存半小时左右,而且不建议修改保存时长,因为数据是保存在服务器的内存中的, 服务器只有一个所以不能占用太多的内存.
  • 应用场景: 保存登录状态,涉及敏感数据,因为数据保存在服务器会更安全

 如何通过Session对象记住登录状态

1、在登录成功时把当前客户端登录的user用户对象保存到当前客户端所对应的Session对象里面,

2、每个客户端进入到首页index.html时会立即发请求获取当前客户端登录的用户对象, 服务器接收到请求后会从当前客户端所对应的Session对象里面获取曾经保存过的用户对象(前提是登陆过),如果没有登录直接获取得到的是null返回给客户端,此时客户端得到的是""空字符串, 客户端判断是否是空字符来表示是否登录过, 通过给isLogin赋值true或false来控制页面显示的内容

 实例:微博练习:

微博首页:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>微博首页</h1>
<div>
    <div v-if="isLogin">
        <p>欢迎{{user.nick}}回来!</p>
        <a href="insert.html">发布微博</a>
        <a href="javascript:void (0)" @click="logout()">登出</a>
    </div>
    <div v-else>
        <a href="/reg.html">注册</a>
        <a href="/login.html">登录</a>
    </div>
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    let v = new Vue({
        el:"body>div",
        data:{
            isLogin:false,
            user:{nick:"刘德华"}
        },
        created:function (){
            //发请求获取当前登录的用户对象 currentUser当前的用户
            axios.get("/currentUser").then(function (response){
                v.user = response.data;
                //如果当前客户端没有登陆的话得到的是空字符串""
                //如果是空字符串代表还没有登录isLogin为false 如果不是空字符串代表登陆过
                v.isLogin = v.user==""?false:true;
            })
        },
        methods:{
            logout(){
                //发出退出登录的请求
                axios.get("/logout").then(function (response){
                    location.reload();//刷新页面
                })
            }
        }
    })
</script>
</body>
</html>

注册页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>注册页面</h1>
<div>
  <input type="text" v-model="user.username" placeholder="用户名">
  <input type="text" v-model="user.password" placeholder="密码">
  <input type="text" v-model="user.nick" placeholder="昵称">
  <input type="button" value="注册" @click="reg()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    let v = new Vue({
        el:"div",
        data:{
            user:{
                username:"",
                password:"",
                nick:""
            }
        },
        methods:{
            reg(){
                axios.post("/reg",v.user).then(function (response){
                    if(response.data==1){
                        alert("注册成功!")
                        location.href="/";
                    }else{
                        alert("用户名已存在")
                    }
                })
            }
        }
    })
</script>
</body>
</html>

登录页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录</h1>
<div>
  <input type="text" v-model="p.username" placeholder="用户名">
  <input type="password" v-model="p.password" placeholder="密码">
  <input type="button" value="登录" @click="login()">
</div>
<script src="js/vue.js"></script>
<script src="js/axios.min.js"></script>
<script>
    let v = new Vue({
        el:"div",
        data:{
            p:{
              username:"",
              password:""
            }
        },
        methods:{
            login(){
                axios.post("/login",v.p).then(function (response){
                    if(response.data==1){
                        alert("登录成功!")
                        location.href="/";
                    }else if(response.data==2){
                        alert("密码错误!")
                    }else {
                        alert("用户名不存在!")
                    }
                })
            }
        }
    })
</script>
</body>
</html>

实现注册登录功能的功能类:

@RestController
public class UserController {
    @Autowired
    UserMapper mapper;

    @RequestMapping("/reg")
    public int reg(@RequestBody User user){
        System.out.println("user="+user.toString());
        User u = mapper.selectByUsername(user.getUsername());
        if(u!=null){
            return 2;
        }
        mapper.insert(user);
        return 1;
    }
    //在参数列表里面声明session 即可得到当前客户端所对应的Session
    @RequestMapping("/login")
    public int login(@RequestBody User user, HttpSession session){
        User u = mapper.selectByUsername(user.getUsername());
        if(u!=null){
            if(u.getPassword().equals(user.getPassword())){
                //把当前登录的用户对象保存到会话对象中
                //user代表用户输入的信息包括:用户名和密码
                //u代表从数据库中查询到的信息 包括:id 用户名 密码 昵称
                session.setAttribute("user",u);

                return 1;
            }
            return 2;
        }
        return 3;
    }

    @RequestMapping("/currentUser")
    public User currentUser(HttpSession session){
        //从会话对象中得到登陆成功是保存的用户对象
        User u = (User) session.getAttribute("user");
        return u;
    }

    @RequestMapping("/logout")
    public void logout(HttpSession session){
        //把登陆成功是保存的user对象删除
        session.removeAttribute("user");
    }

}

 UserMapper类:

@Mapper
public interface UserMapper {

    @Insert("insert into user values(null,#{username},#{password},#{nick})")
    void insert(User user);

    @Select("select *from user where username=#{username}")
    User selectByUsername(String username);
}

发布微博页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <!-- import CSS -->
    <link rel="stylesheet" href="css/eui.css">
</head>
<body>
<h1>发布微博页面</h1>
<div id="app">
    <input type="text" v-model="weibo.content" placeholder="说点儿什么....">
    <!--name代表上传文件时 文件的参数名
        limit="1" 设置只能选择一张图片
    -->
    <el-upload
            action="/upload"
            name="picFile"
            :limit="1"
            list-type="picture-card"
            :on-preview="handlePictureCardPreview"
            :on-success="handleSuccess"
            :on-remove="handleRemove">
        <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
        <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
    <input type="button" value="发布微博" @click="insert()">
</div>
</body>
<!-- import Vue before Element -->
<script src="js/vue.js"></script>
<!-- import JavaScript -->
<script src="js/eui.js"></script>
<script src="js/axios.min.js"></script>
<script>
    let v = new Vue({
        el: '#app',
        data: function() {
            return {
                dialogImageUrl: '',
                dialogVisible: false,
                weibo:{
                    content:"",
                    url:""
                }
            }
        },
        methods: {
            handleRemove(file, fileList) {
                console.log(file, fileList);
                //当点击删除图片时方法会执行
                //file代表要删除的文件
                //file.response代表文件上传成功时 服务器响应的数据(文件名)
                console.log("文件名="+file.response);
                //http://localhost:8080/remove?name=xxx.jpg
                axios.get("/remove?name="+file.response).then(function (response) {
                    console.log("服务器图片已经删除")
                })
            },
            handlePictureCardPreview(file) {
                this.dialogImageUrl = file.url;
                this.dialogVisible = true;
            },
            insert(){
                //得到用户输入的微博文本内容和图片名 一起提交给服务器
                if (v.weibo.content.trim()==""||v.weibo.url==""){
                    alert("微博内容或图片不能为空!")
                    return;
                }
                axios.post("/insert",v.weibo).then(function (response) {
                    if(response.data==1){
                        alert("添加完成!");
                        location.href="/"; //回到首页
                    }else{
                        alert("请先登录")
                        location.href="/login.html";//显示登录页面
                    }

                })
            },
            handleSuccess(response,file,fileList){
                //response=file.response
                console.log("文件上传完成, 图片名="+response);
                v.weibo.url = response;
            }
        }
    })
</script>
</html>

实现文件上传及删除的功能类:

@RestController
public class UploadController {
    @RequestMapping("/upload")
    public String upload(MultipartFile picFile) throws IOException {
        System.out.println("picFile = " + picFile);
        //得到文件原始文件名  a.jpg
        String fileName = picFile.getOriginalFilename();
        //得到后缀名  从最后一个.出现的位置截取到最后
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        //得到唯一文件名  UUID.randomUUID()得到一个唯一标识符
        fileName = UUID.randomUUID()+suffix;
        System.out.println("文件名:"+fileName);
        //准备保存图片的文件夹路径
        String dirPath = "F:/files";
        File dirFile = new File(dirPath);
        //如果该文件夹不存在 则创建此文件夹
        if (!dirFile.exists()){
            dirFile.mkdirs();//创建文件夹
        }
        //得到文件的完整路径
        String filePath = dirPath+"/"+fileName;
        //把文件保存到此路径   异常抛出
        picFile.transferTo(new File(filePath));
        System.out.println("文件保存完成! 请去此路径检查文件是否存在 "+filePath);

        return fileName;
    }

    @RequestMapping("/remove")
    public void remove(String name){
        String dirPath = "F:/files";
        String filePath = dirPath+"/"+name;
        new File(filePath).delete();//删除文件
    }

}

实现发布微博功能类:

@RestController
public class WeiboController {

    @Autowired
    WeiboMapper mapper;

    @RequestMapping("/insert")
    public int insert(@RequestBody Weibo weibo, HttpSession session){
        //得到当前登录的的用户对象
        User u = (User)session.getAttribute("user");
        if(u==null){
            return 2;//代表未登录
        }
        //new Date()得到当前的系统时间
        weibo.setCreated(new Date());
        //把当前登录的用户信息 添加到weibo对象中
        weibo.setUserId(u.getId());
        weibo.setNick(u.getNick());

        System.out.println("weibo="+weibo);
        mapper.insert(weibo);
        return 1;//代表微博发布成功
    }
}

WeiboMapper类:

@Mapper
public interface WeiboMapper {
    @Insert("insert into weibo values(null,#{content},#{url},#{nick},#{created},#{userId})")
    void insert(Weibo weibo);
}

 

 

SpringBoot常见错误列表:

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值