发布时间:2023-04-23 文章分类:WEB开发, 电脑百科 投稿人:王小丽 字号: 默认 | | 超大 打印

       在上次前后端交互,我们使用的是最基本的HTML+Servlet的组合,比较基础,今天我们来讲一讲Html+Springboot框架,前后端交互实现更为简便,大大降低了我们开发人员在代码上面所花费的时间,那今天让我们一探究竟吧。

1.添加路由守卫

      在前端我们在index.js中添加了路由守卫

springboot前后端交互(小白教学)

 springboot前后端交互(小白教学)

 在网址中直接去http://localhost:8081/#/main

由于路由守卫,我们不能直接进入main页面中,自动给我们跳转到登录页面中

springboot前后端交互(小白教学)

 2.验证token

添加token一块有4步:

  1. 登录成功后,后端生成token
  2. 前端接收,并保存
  3. 前端拦截器向后端发送
  4. 后端拦截器验证token

1. 登录成功后,后端生成token

package com.ffyc.common;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Service
public class JWTUtil {
    /**
     * jwt 生成 token
     *
     * @param id
     * @param account * @return
     */
    public static String token(Integer id, String account) {
        String token = "";
        try {
            //过期时间 为 1970.1.1 0:0:0 至 过期时间 当前的毫秒值 + 有效时间
            Date expireDate = new Date(new Date().getTime() + 60 * 60 * 24 * 1000);//过期时间
            //秘钥及加密算法  加盐
            Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
            //设置头部信息
            Map<String, Object> header = new HashMap<>();
            header.put("typ", "JWT");//生成的类型
            header.put("alg", "HS256");//加密算法
            //携带 id,账号信息,生成签名
            token = JWT.create()
                    .withHeader(header)//头部
                    .withClaim("id", id)//用户id
                    .withClaim("account", account)//用户账号
                    .withExpiresAt(expireDate)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return token;
    }
    public static boolean verify(String token) {
        try {
            //验签
            Algorithm algorithm = Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE");
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception e) {//当传过来的 token 如果有问题,抛出异常
            return false;
        }
    }
    /**
     * 获得 token 中 playload 部分数据,按需使用
     *
     * @param token
     * @return
     */
    public static DecodedJWT getTokenInfo(String token) {
        return JWT.require(Algorithm.HMAC256("ZCEQIUBFKSJBFJH2020BQWE")).build().verify(token);
    }
}

将生成Token添加到admin对象中

springboot前后端交互(小白教学)

 2.前端接收,并保存

在main.js中添加验证token字段

springboot前后端交互(小白教学)

3. 前端拦截器向后端发送

在main.js中添加

springboot前后端交互(小白教学)

 4.后端拦截器验证token

后端token拦截器:

package com.ffyc.common;
import com.fasterxml.jackson.databind.json.JsonMapper;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//Token 验证拦截器
public class Token implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("后端Token拦截器");
        String adminToken=request.getHeader("token");
        boolean res=JWTUtil.verify(adminToken);
        if(!res){
            CommonResult commonResult=new CommonResult(202,res,"token失效");
            JsonMapper jsonMapper=new JsonMapper();
            String json=  jsonMapper.writeValueAsString(commonResult);
            response.getWriter().print(json);
        }
        return res;
    }
}

注册拦截器:

package com.ffyc.common;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class WebConfig implements WebMvcConfigurer{
	public void addInterceptors(InterceptorRegistry registry) {
		InterceptorRegistration inter =  registry.addInterceptor(new Token());
		inter.addPathPatterns("/admin/**"); //管理员需要拦截过滤地址
		inter.excludePathPatterns("/admin/loginCtl/login");//放行地址
		//放行行前台首页,文章详细信息等地址
		//inter.excludePathPatterns("/swagger*/**"); //放行swagger
		//inter.excludePathPatterns("/v2/**");//放行swagger
		//inter.excludePathPatterns("/webjars/**");//放行swagger
	}
}

在网址中直接搜索127.0.0.1:8080/admin/loginCtl/test

springboot前后端交互(小白教学)

 拦截器会进行验证,没有Token,返回CommomResult

springboot前后端交互(小白教学)

 3.完成最基本的登录功能

 3.1  dao层

在dao层创建接口

package com.ffyc.dao;
import com.ffyc.model.Admin;
import org.springframework.stereotype.Repository;
@Repository//使spring创建并管理对象
public interface LoginDao {
    public Admin Login(Admin admin);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE
        mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--接口的添加-->
<mapper namespace="com.ffyc.dao.LoginDao">
    <select id="Login" resultType="Admin">
        select * from admin where account=#{account} and password=#{password}
    </select>
</mapper>

  3.2 model层

在model层创建admin类

package com.ffyc.model;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data//lombok 可以自动创建get set方法
@Getter
@Setter
public class Admin {
    private Integer id;
    private String account;
    private int password;
    private String token;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getAccount() {
        return account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public int getPassword() {
        return password;
    }
    public void setPassword(int password) {
        this.password = password;
    }
    public String getToken() {
        return token;
    }
    public void setToken(String token) {
        this.token = token;
    }
}

  3.2 service层

  在service层写逻辑部分

package com.ffyc.service;
import com.ffyc.common.CommonResult;
import com.ffyc.common.JWTUtil;
import com.ffyc.dao.LoginDao;
import com.ffyc.model.Admin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class LoginService {
     @Autowired
     LoginDao loginDao;
     public Admin login(Admin admin){
        Admin a = loginDao.Login(admin);
         return a;
     }
}

3.4 web层

package com.ffyc.web;
import com.ffyc.common.CommonResult;
import com.ffyc.common.JWTUtil;
import com.ffyc.model.Admin;
import com.ffyc.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(path= "/admin/loginCtl")
public class Controller {
    @Autowired
    LoginService loginService;
    @RequestMapping(path= "/login")
    //后端可以接收前端提交的json数据,但是必须是对象接收,必须要在参数前面添加@RequestBody
    public CommonResult login(@RequestBody Admin admin){
     Admin a = loginService.login(admin);
        CommonResult commonResult=null;
        if(a!=null) {
            a.setToken(JWTUtil.token(a.getId(),a.getAccount()));
            commonResult = new CommonResult(200, a, "登录成功");//可以对创建方法进封装
        }else{
            commonResult = new CommonResult(201, a, "账号密码错误");//可以对创建方法进封装
        }
     return commonResult;
    }
}

springboot前后端交互(小白教学)

 加这个标签之后,前端就不需要再添加JsonString的方法

springboot前后端交互(小白教学)

 4.配置application.yml

#配置内置服务器的端口号
server:
 port: 8080
#spring相关的配置
spring:
  #配置数据库的连接信息,生成默认的数据源对象,生成JdbcTemplate,事务管理功能进行初始化
 datasource:
   url: jdbc:mysql://127.0.0.1:3306/map?serverTimezone=Asia/Shanghai
   username: root
   password: root
   driver-class-name: com.mysql.cj.jdbc.Driver
   type: com.alibaba.druid.pool.DruidDataSource #指定数据源类型,还需要创建其对象
   initialSize: 5 #初始化时建立物理连接的个数   数据库连接池相关的配置
   minIdle: 1 #最小连接池数量
   maxActive: 20 #最大连接池数量
#mybatis配置  创建SqlsessionFactory
mybatis:
   type-aliases-package: com.ffyc.model
   mapper-locations: classpath:mappers/*Mappers.xml
   configuration: #mybatis settings配置
     map-underscore-to-camel-case: true
     cache-enabled: true