五分钟写一个VUE结合SpringBoot的单表增删改查带JWT登录功能界面

首先先准备WebStorm与IDEA

 数据库准备一个简单的表

CREATE TABLE `sys_user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` char(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名',
  `password` char(16) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码',
  `nickname` char(30) COLLATE utf8mb4_unicode_ci DEFAULT 'NewUser' COMMENT '昵称',
  `email` char(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '邮箱',
  `phone` char(11) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '手机号',
  `address` char(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地址',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

后端的Mybatis实现一下Mapper

package com.xiejianjun.vueproject.mapper;

import com.xiejianjun.vueproject.dto.Page;
import com.xiejianjun.vueproject.dto.UserDTO;
import com.xiejianjun.vueproject.entities.SysUser;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;

import java.util.List;

@Mapper
@Repository
public interface SysUserMapper {
    @Select("select `id`," +
            "`username`," +
            "`nickname`," +
            "`email`," +
            "`phone`," +
            "`address`" +
            "from sys_user")
    List<SysUser> selectSysUserList();

    @Select("select `id`," +
            "`username`," +
            "`nickname`," +
            "`email`," +
            "`phone`," +
            "`address`" +
            "from sys_user where `id` = #{id}")
    SysUser selectSysUserById(@Param("id") Integer id);

    @Delete("delete from sys_user where `id` = #{id}")
    Integer deleteSysUserById(@Param("id") Integer id);

    Integer updateSysUserById(SysUser user);

    @Insert("insert into sys_user(username,password,nickname,email,phone,address) values(#{username},#{password},#{nickname},#{email},#{phone},#{address})")
    Integer insertSysUser(SysUser user);

    @Select("select `id`,`username`,`nickname`,`email`,`phone`,`address` from sys_user limit #{pageNum},#{pageSize}")
    List<SysUser> getPage(Page page);

    @Select("select count(*) from sys_user")
    Integer SysUserCount();

    @Select("select `id`,`username`,`nickname`,`email`,`phone`,`address` from sys_user where `username`=#{username} and `password`=#{password}")
    SysUser checkUser(UserDTO userDTO);
}

服务层调用一下Mapper,最好都在此处抛出异常

package com.xiejianjun.vueproject.service.impl;

import com.xiejianjun.vueproject.dto.Page;
import com.xiejianjun.vueproject.dto.UserDTO;
import com.xiejianjun.vueproject.exception.MyException;
import com.xiejianjun.vueproject.mapper.SysUserMapper;
import com.xiejianjun.vueproject.service.SysUserService;
import com.xiejianjun.vueproject.util.JWTUtil;
import com.xiejianjun.vueproject.vo.Constants;
import com.xiejianjun.vueproject.entities.SysUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public List<SysUser> queryAllSysUser() {
        return sysUserMapper.selectSysUserList();
    }

    @Override
    public SysUser querySysUserById(Integer id) {
        SysUser user = sysUserMapper.selectSysUserById(id);
        if (user == null) {
            throw new MyException(Constants.Code_401.getCode(), "查无此人!");
        }
        return user;
    }

    @Override
    public Integer deleteUserById(Integer id) {
        return sysUserMapper.deleteSysUserById(id);
    }

    @Override
    public Integer updateUserById(SysUser user) {
        return sysUserMapper.updateSysUserById(user);
    }

    @Override
    public Integer addUser(SysUser user) {
        // 最好加一个判断数据库中是否有相同用户,我懒得加
        return sysUserMapper.insertSysUser(user);
    }

    @Override
    public List<SysUser> querySysUserPage(Page page) {
        page.setPageNum((page.getPageNum() - 1) * page.getPageSize());
        return sysUserMapper.getPage(page);
    }

    @Override
    public Integer querySysUserCount() {
        return sysUserMapper.SysUserCount();
    }

    @Override
    public UserDTO GetValidUser(UserDTO userDTO) {

        SysUser sysUser = sysUserMapper.checkUser(userDTO);
        if(sysUser == null) {
            throw new MyException(Constants.Code_500.getCode(), "用户名或密码错误");
        } else {
            Map<String,String> map = new HashMap<>();
            map.put("id", String.valueOf(sysUser.id));
            map.put("username",sysUser.username);
            map.put("nickname",sysUser.nickname);
            map.put("email",sysUser.email);
            map.put("phone",sysUser.phone);
            map.put("address",sysUser.address);
            String token = JWTUtil.getToken(map);
            BeanUtils.copyProperties(sysUser,userDTO);
            userDTO.setPassword(null);
            userDTO.setToken(token);
        }
        return userDTO;
    }
}

控制器的异常捕获器,利用AOP的思想改变控制层的返回值参数,所以控制层的返回值要与捕获器返回值相同

package com.xiejianjun.vueproject.exception;

import com.xiejianjun.vueproject.vo.Constants;
import com.xiejianjun.vueproject.vo.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;

@ControllerAdvice
public class MyExceptionHandler {
    @ExceptionHandler(value = MyException.class)
    @ResponseBody
    public Result userResult(MyException e) {
        return new Result(e.getCode(), e.getMessage(), null);
    }

    @ExceptionHandler(value = IOException.class)
    @ResponseBody
    public Result fileResult(IOException e) {
        return new Result(Constants.Code_500.getCode(), e.getMessage(), null);
    }
}

控制层提供一下服务前端的接口

package com.xiejianjun.vueproject.controller;

import com.xiejianjun.vueproject.dto.Page;
import com.xiejianjun.vueproject.dto.UserDTO;
import com.xiejianjun.vueproject.service.SysUserService;
import com.xiejianjun.vueproject.vo.Result;
import com.xiejianjun.vueproject.entities.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;

/*    @GetMapping("/")
    public List<SysUser> getUserList() {
        return sysUserService.queryAllSysUser();
    }*/

    @GetMapping("/{id}")
    public Result getUser(@PathVariable("id") Integer id) {
        return Result.success(sysUserService.querySysUserById(id), "查询特定用户成功");
    }

    @PutMapping("/")
    public Result addUser(@RequestBody SysUser user) {
        return Result.success(sysUserService.addUser(user), "增加用户成功");
    }

    @DeleteMapping("/{id}")
    public Result deleteUser(@PathVariable("id") Integer id) {

        return Result.success(sysUserService.deleteUserById(id), "删除用户成功");
    }

    @PostMapping("/")
    public Result updateUser(@RequestBody SysUser user) {

        return Result.success(sysUserService.updateUserById(user), "更新用户成功");
    }

    @GetMapping("/page")
    public Result getUserPage(@RequestParam(
            required = false,
            value = "pageNum",
            defaultValue = "1") Integer pageNum,
                              @RequestParam(
                                      required = false,
                                      name = "pageSize",
                                      defaultValue = "2")
                                      Integer pageSize) {
        Map<String, Object> map = new HashMap<>();
        map.put("pageData", sysUserService.querySysUserPage(new Page(pageNum, pageSize)));
        map.put("total", sysUserService.querySysUserCount());

        return Result.success(map, "请求页数用户成功");
    }

    @PostMapping("/login")
    public Result login(@RequestBody UserDTO userDTO) {
        UserDTO user = sysUserService.GetValidUser(userDTO);
        return Result.success(user, "登录成功");
    }
}

最后把跨域设置一下

package com.xiejianjun.vueproject.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {
    // 当前跨域请求最大有效时长。这里默认1天
    private static final long MAX_AGE = 24 * 60 * 60;

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        corsConfiguration.setMaxAge(MAX_AGE);
        source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }

}

接下来是VUE的部分

首先打开WebStorm,我默认你已经装好Vue-cli了

随便在一个文件夹下运行vue create "你的项目名称"

选择创建vue2

随后在main.js上引入elementui以及路由插件

import ElementUI from 'element-ui';
// 引入elementUI所有的CSS样式
import 'element-ui/lib/theme-chalk/index.css';
// 引入router
import VueRouter from "vue-router"
import router from "./route";
import request from "@/network/request";


//关闭Vue的生产提示
Vue.config.productionTip = false
// 使用elementUI插件
Vue.use(ElementUI)
Vue.use(VueRouter)


new Vue({
  render: h => h(App),
  router,
  beforeCreate() {
    Vue.prototype.$request = request
  }
}).$mount('#app')

全局的网络过滤器,在请求数据时携带token判断身份信息,服务器响应的数据的msg用elementui打印,并在控制台输出完整信息方便调试

import axios from "axios";
import ElementUI from "element-ui";
const instance = axios.create({
    baseURL: 'http://localhost:8910/',
    timeout: 5000
})

instance.interceptors.request.use(config => {

    let token = window.sessionStorage.getItem('token')
    if (typeof token != "undefined" && token != null && token !== 'undefined'){
        config['headers'].token = JSON.parse(token)
    }
    return config;
},
    err => {
    //
    })

instance.interceptors.response.use(res => {
    console.log(res.data)
    if (res.data.code === '200') {
        ElementUI.Message({
            message: res.data.msg,
            type: "success"
        })
    } else {
        ElementUI.Message({
            message: res.data.msg,
            type: "error"
        })
    }
    return res
})

export default instance




配置一下路由器,只用得到manage,home,user,login,person这五个路由

import VueRouter from "vue-router"

import About from "@/page/About";
import Login from "@/page/Login";
import User from "@/page/User";
import Home from "@/page/Home";
import Manage from "@/page/Manage";
import Person from "@/page/Person";
import MyFile from "@/page/MyFile";

export default new VueRouter({
    routes: [
        {
            path:'/',
            redirect: '/home',
            component: Manage,
            children: [
                {
                    path: 'user',
                    component: User
                },
                {
                    path: 'home',
                    component: Home,
                },
                {
                    path: 'person',
                    component: Person
                },
                {
                    path: 'file',
                    component: MyFile
                }
            ]
        },
        {
            path: '/about',
            component: About
        },
        {
            path: '/login',
            name: 'Login',
            component: Login
        }
    ]
})

App.vue只需要套个路由展示器就好了,什么都不用写

<template>
  <router-view/>
</template>

<script>
export default {
  name: 'App'
}
</script>

Manage.vue注入到App.vue的routerview标签内,且负责把最新的user信息传递给子组件Header

<template>
  <div id="app">
    <el-container style="height: 100%; border: 1px solid #eee">
      <Aside/>
      <el-container>
        <el-header style="text-align: right; font-size: 12px">
            <Header :user="user"/>
        </el-header>
        <el-main>
          <router-view @refreshUser="getUser"></router-view>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>


import Aside from "@/components/Aside";
import Header from "@/components/Header";
import User from "@/page/User";

export default {
  name: 'Manage',
  data() {
    return {
      tableData: [],
      total: 0,
      form: {},
      pageSize: 2,
      pageNum: 1,
      dialogFormVisible: false,
      user: window.sessionStorage.getItem('user')?JSON.parse(window.sessionStorage.getItem('user')):{}
    }
  },
  components: {
    Header,
    Aside,
    User
  },
  methods: {
    getUser() {
      this.$request.get(`/user/${JSON.parse(window.sessionStorage.getItem('user')).id}`)
      .then(res => {
        console.log(res.data)
        this.user = res.data.data
      })
    }
  }


}
</script>

<style>


.el-header {
  background-color: #B3C0D1;
  color: #333;
  line-height: 60px;
}

.el-select .el-input {
  width: 130px;
}
</style>

子路由组件Home.vue简单写一下,之后可以替换个echart图展示

<template>
  <div>
    <p>主页</p>
  </div>
</template>

<script>
export default {
  name: "Home"
}
</script>

<style scoped>

</style>

Header.vue 作为manage.vue 的子组件,提供上边栏

<template>
  <div>
    <div v-show="user==null">
      <el-dropdown>
        <i class="el-icon-setting" style="margin-right: 15px"></i>
        <el-dropdown-menu  slot="dropdown">
          <el-dropdown-item @click.native="$router.push('/login')">登录</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
    <div v-if="user!=null">
      <el-dropdown>
        <i class="el-icon-setting" style="margin-right: 15px"></i>
        <el-dropdown-menu  slot="dropdown">
          <el-dropdown-item @click.native="$router.push('/person')">个人信息</el-dropdown-item>
          <el-dropdown-item @click.native="logout">注销</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      <span>{{user.nickname}}</span>
    </div>
  </div>
</template>

<script>
export default {
  name: "Header",
  props:['user']
  ,
  methods: {
    logout() {
      window.sessionStorage.removeItem('user')
      window.sessionStorage.removeItem('token')
      this.$router.push('/login')
    }
  },
  mounted() {

  }
}
</script>

<style scoped>

</style>

Aside.vue 作为Manage.vue的子组件,提供侧边栏

<template>
  <el-aside width="200px" style="background-color: rgb(238, 241, 246);height: 100%">
    <el-menu :default-openeds="['1', '3']"
              router>
      <el-menu-item index="/">主页</el-menu-item>
      <el-submenu index="1">
        <template slot="title"><i class="el-icon-message"></i>管理页面</template>
        <el-menu-item-group>
          <el-menu-item index="/user">用户管理</el-menu-item>
        </el-menu-item-group>
        <el-menu-item-group>
          <el-menu-item index="/file">文件管理</el-menu-item>
        </el-menu-item-group>
        <el-menu-item-group>
          <el-menu-item index="/user">角色管理</el-menu-item>
        </el-menu-item-group>
        <el-menu-item-group>
          <el-menu-item index="/user">菜单管理</el-menu-item>
        </el-menu-item-group>
      </el-submenu>

    </el-menu>
  </el-aside>
</template>

<script>
export default {
  name: "Aside"
}
</script>

<style scoped>
.el-aside {
  color: #333;
}
</style>

User.vue 作为Manage.vue的子路由,提供用户的增删改查的功能

<template>
<div>
  <div style="padding: 10px 0;" class="el-input">
    <el-input placeholder="请输入搜索内容">
      <el-button slot="append" icon="el-icon-search"></el-button>
    </el-input>
  </div>

  <el-row>
    <el-button type="primary" @click="handleAdd">新增 <i class="el-icon-plus"></i></el-button>
  </el-row>

  <el-table :data="tableData">
    <el-table-column prop="id" label="用户ID" width="140">
    </el-table-column>
    <el-table-column prop="username" label="姓名" width="120">
    </el-table-column>
    <el-table-column prop="nickname" label="昵称" width="120">
    </el-table-column>
    <el-table-column prop="phone" label="电话" width="120">
    </el-table-column>
    <el-table-column prop="email" label="邮箱" width="120">
    </el-table-column>
    <el-table-column prop="address" label="地址">
    </el-table-column>
    <el-table-column>
      <template slot-scope="scope">
        <el-button type="success" @click="handleEdit(scope.row)">编辑 <i class="el-icon-circle-plus-outline"></i></el-button>
        <el-button type="danger" @click="handleDelete(scope.row.id)">删除 <i class="el-icon-delete-solid"></i></el-button>
      </template>
    </el-table-column>
  </el-table>

  <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :page-sizes="[2, 4, 6, 8]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total">
  </el-pagination>

  <el-dialog title="用户信息" :visible.sync="dialogFormVisible">
    <el-form :model="form" label-width="80px">
      <el-form-item label="用户名" >
        <el-input v-model="form.username" autocomplete="off" disabled></el-input>
      </el-form-item>
      <el-form-item label="用户昵称" >
        <el-input v-model="form.nickname" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="用户密码" >
        <el-input v-model="form.password" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="用户地址">
        <el-input v-model="form.address"></el-input>
      </el-form-item>
      <el-form-item label="用户邮箱">
        <el-input v-model="form.email" autocomplete="off"></el-input>
      </el-form-item>
      <el-form-item label="用户电话" >
        <el-input v-model="form.phone" autocomplete="off"></el-input>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogFormVisible = false">取 消</el-button>
      <el-button type="primary" @click="putBankEnd">确 定</el-button>
    </div>
  </el-dialog>

</div>
</template>

<script>


export default {
  name: "User",
  data() {
    return {
      tableData: [],
      total: 0,
      form: {},
      pageSize: 2,
      pageNum: 1,
      dialogFormVisible: false
    }
  },
  methods:
      {
        handleSizeChange(pageSize) {
          this.pageSize = pageSize
          this.load()
        },
        handleCurrentChange(pageNum) {
          this.pageNum = pageNum
          this.load()
        },
        handleAdd() {
          this.dialogFormVisible = true
          this.form = {}
        },
        // 弹窗按钮的抉择,用是否存在id来判断是更新还是增加
        putBankEnd() {
          this.dialogFormVisible = false
          if(this.form.id){
            this.update()
          }else {
            this.add()
          }


        },
        handleDelete(id) {
          if(confirm("你确定要删除此项吗?")) {
            this.delete(id)
          }else {
            //
          }

        },
        handleEdit(data) {
          this.form = data
          this.dialogFormVisible = true
        },
        load() {
          this.$request.get("user/page",{
            params: {
              pageNum: this.pageNum,
              pageSize: this.pageSize
            }
          }).then(res => {
            if (res.data.code === '200'){
              this.tableData = res.data.data.pageData
              this.total = res.data.data.total
              if (!this.tableData.length) {
                this.$message.error("此页已无数据,加载上一页")
                if (this.pageNum > 1) {
                  this.pageNum--
                  this.load()
                }
              }
            }
          })

        },
        add() {
          this.$request.put("user/", this.form).then(res => {
            if(res.data.code === '200') {
              //
            } else {
              //
            }
            this.load()
          })
        },
        update() {
          this.$request.post("user/", this.form).then(res => {
            if(res.data.code === '200') {
              //
            } else {
              //
            }
            this.load()
          })
        },
        delete(id) {
          this.$request.delete(`user/${id}`).then(res => {
            if(res.data.code === '200') {
              //
            } else {
              //
            }
            this.load()
          })
        }
      },
  mounted() {
    this.load()
  }
}
</script>

<style scoped>

</style>

Person.vue 作为Manage.vue的子路由,提供修改用户个人信息的功能

<template>
  <div>
    <el-radio-group v-model="labelPosition" size="small">
      <el-radio-button label="left">左对齐</el-radio-button>
      <el-radio-button label="right">右对齐</el-radio-button>
      <el-radio-button label="top">顶部对齐</el-radio-button>
    </el-radio-group>
    <div style="margin: 20px;"></div>
    <el-form :label-position="labelPosition" label-width="80px" :model="user">
      <el-form-item label="我的昵称">
        <el-input v-model="user.nickname"></el-input>
      </el-form-item>
      <el-form-item label="我的电话">
        <el-input v-model="user.phone"></el-input>
      </el-form-item>
      <el-form-item label="我的地址">
        <el-input v-model="user.address"></el-input>
      </el-form-item>
      <el-form-item label="我的邮箱">
        <el-input v-model="user.email"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click.native="handleUpdate" >修改</el-button>
      </el-form-item>
    </el-form>
  </div>

</template>

<script>
export default {
  name: "Person",
  data() {
    return {
      labelPosition: 'right',
      user: JSON.parse(window.sessionStorage.getItem('user'))
    }
  },
  methods: {
    handleUpdate() {
      this.$request.post('/user/',this.user).then(res => {
        console.log(res)
        window.sessionStorage.setItem('user',JSON.stringify(this.user))
        this.$emit("refreshUser")
      })
    }
  }
}
</script>

<style scoped>

</style>

Login.vue 登录的时候向后端发请求就好了,登陆成功就把用户信息和token放在浏览器的sessionStorage里面,让路由跳回首页,后端的拦截器如果没收到带有token信息的请求头的请求,则会返回无权限访问的Result类型的Json对象

<template>
  <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
    <el-form-item label="用户名" prop="username">
      <el-input v-model="ruleForm.username"></el-input>
    </el-form-item>
    <el-form-item label="密码" prop="password">
      <el-input v-model="ruleForm.password" show-password></el-input>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm('ruleForm')">登录</el-button>
      <el-button @click="resetForm('ruleForm')">重置</el-button>
    </el-form-item>
  </el-form>
</template>

<script>

export default {
  name: "Login",
  data() {
    return {
      ruleForm: {},
      rules: {
        username: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
          //{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '请输入活动名称', trigger: 'blur' },
          //{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.$request.post('user/login',this.ruleForm).then(res => {
            if (res.data.code === '200') {
              //console.log(res.data.data)
              sessionStorage.setItem('user',JSON.stringify(res.data.data))
              sessionStorage.setItem('token',JSON.stringify(res.data.data.token))
              //this.$message.success(res.data.msg)
              this.$router.push('/')
            }else {
              //this.$message.error(res.data.msg)
            }
          })
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    }
  }
}
</script>

<style scoped>

</style>

验证token的后端代码,利用拦截器实现

package com.xiejianjun.vueproject.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.xiejianjun.vueproject.service.SysUserService;
import com.xiejianjun.vueproject.util.JWTUtil;
import com.xiejianjun.vueproject.vo.Constants;
import com.xiejianjun.vueproject.vo.Result;
import jdk.nashorn.internal.ir.debug.JSONWriter;
import org.apache.tomcat.util.json.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class MyInterceptor implements HandlerInterceptor {
    @Autowired
    private SysUserService sysUserService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        String token = request.getHeader("token");
        String json;
        if (token != null) {
            try{
                Integer validate = Integer.parseInt(JWTUtil.validate(token));
                if (sysUserService.querySysUserById(validate) == null) {
                    json = JSONObject.toJSON(new Result(Constants.Code_401.getCode(), "查无此人", null)).toString();
                    response.setHeader("Content-type", "text/html;charset=UTF-8");
                    response.setCharacterEncoding("utf-8");
                    response.setContentType("text/html;charset=UTF-8");
                    response.getWriter().println(json);
                    return false;
                }
                return true;
            } catch (TokenExpiredException e) {
                json = JSONObject.toJSON(new Result(Constants.Code_401.getCode(), "登录状态过期", null)).toString();
                response.setHeader("Content-type", "text/html;charset=UTF-8");
                response.setCharacterEncoding("utf-8");
                response.setContentType("text/html;charset=UTF-8");
                response.getWriter().println(json);
                return false;
            } catch (SignatureVerificationException e) {
                json = JSONObject.toJSON(new Result(Constants.Code_401.getCode(), "签名不一致", null)).toString();
                response.setHeader("Content-type", "text/html;charset=UTF-8");
                response.setCharacterEncoding("utf-8");
                response.setContentType("text/html;charset=UTF-8");
                response.getWriter().println(json);
                return false;
            } catch (Exception e) {
                json = JSONObject.toJSON(new Result(Constants.Code_401.getCode(), "绷不住了", null)).toString();
                response.setHeader("Content-type", "text/html;charset=UTF-8");
                response.setCharacterEncoding("utf-8");
                response.setContentType("text/html;charset=UTF-8");
                response.getWriter().println(json);
                return false;
            }
        }
        System.out.println("拦截器拦截成功");
        json = JSONObject.toJSON(new Result(Constants.Code_401.getCode(), "无权限访问", null)).toString();
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}

页面展示