下 SpringBoot-常见场景-三更补充版

接上文(准备开始前后端分离的模式) 准备工作: 基本测试(数据库查询–可跳过,与整合步骤基本一致)
因为是前后端分离的项目,所以最终方法的返回值都会放到请求体当中—>@
所有文件与之前测试的相同
实体类
import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@AllArgsConstructor@NoArgsConstructorpublic class User {private Integer id;private String username;private Integer age;private String address;}
记得加注解,才会知道这个是个接口
接口相应格式统一(另一项目的)
前端发送请求代码编写
出现了跨域问题
4.5 跨域请求 4.5.1 什么是跨域
? 浏览器出于安全的考虑,使用 对象发起 HTTP请求时必须遵守同源策略,否则就是跨域的HTTP请求,默认情况下是被禁止的 。同源策略要求源相同才能正常进行通信,即协议、域名、端口号都完全一致 。
4.5.2 CORS解决跨域
? CORS是一个W3C标准,全称是”跨域资源共享”(Cross-),允许浏览器向跨源服务器 , 发出请求 , 从而克服了AJAX只能同源使用的限制 。
? 它通过服务器增加一个特殊的[--Allow-]来告诉客户端跨域的限制 , 如果浏览器支持CORS、并且判断通过的话,就会允许发起跨域请求 。
?
4.5.3 使用CORS解决跨域 1.使用@
可以在支持跨域的方法上或者是上加上@注解
@RestController@RequestMapping("/user")@CrossOriginpublic class UserController {@Autowiredprivate UserServcie userServcie;@RequestMapping("/findAll")public ResponseResult findAll(){//调用service查询数据 ,进行返回List users = userServcie.findAll();return new ResponseResult(200,users);}}
2.使用的方法配置(更好的方式)
@Configuration//表所示为配置类public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {// 设置允许跨域的路径registry.addMapping("/**")// 设置允许跨域请求的域名.allowedOriginPatterns("*")// 是否允许cookie.allowCredentials(true)// 设置允许的请求方式.allowedMethods("GET", "POST", "DELETE", "PUT")// 设置允许的header属性.allowedHeaders("*")// 跨域允许时间.maxAge(3600);}}
比如:
继续实现功能 前端
运用debug
最终结果
为什么要统一响应格式
data属性当中就是把我们后端响应的json字符串解析出来 。
这样对前端来说判断方便很多
4.6 拦截器 4.6.0 登录案例
4.6.0.1 思路分析
? 在前后端分离的场景中 , 很多时候会采用token的方案进行登录校验 。
? 登录成功时 , 后端会根据一些用户信息生成一个token字符串返回给前端 。
? 前端会存储这个token 。以后前端发起请求时如果有token就会把token放在请求头中发送给后端 。
? 后端接口就可以获取请求头中的token信息进行解析 , 如果解析不成功说明token超时了或者不是正确的token,相当于是未登录状态 。
? 如果解析成功,说明前端是已经登录过的 。
4.6.0.2 Token生成方案-JWT
? 本案例采用目前企业中运用比较多的JWT来生成token 。
? 使用时先引入相关依赖
io.jsonwebtokenjjwt0.9.0
? 然后可以使用下面的工具类来生成和解析token
import io.jsonwebtoken.Claims;import io.jsonwebtoken.JwtBuilder;import io.jsonwebtoken.Jwts;import io.jsonwebtoken.SignatureAlgorithm;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import java.util.Base64;import java.util.Date;import java.util.UUID;/*** JWT工具类*/public class JwtUtil {//有效期为public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 *1000一个小时//设置秘钥明文public static final String JWT_KEY = "sangeng";/*** 创建token* @param id* @param subject* @param ttlMillis* @return*/public static String createJWT(String id, String subject, Long ttlMillis) {SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;long nowMillis = System.currentTimeMillis();Date now = new Date(nowMillis);if(ttlMillis==null){ttlMillis=JwtUtil.JWT_TTL;}long expMillis = nowMillis + ttlMillis;Date expDate = new Date(expMillis);SecretKey secretKey = generalKey();JwtBuilder builder = Jwts.builder().setId(id)//唯一的ID.setSubject(subject)// 主题可以是JSON数据.setIssuer("sg")// 签发者.setIssuedAt(now)// 签发时间.signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥.setExpiration(expDate);// 设置过期时间return builder.compact();}/*** 生成加密后的秘钥 secretKey* @return*/public static SecretKey generalKey() {byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");return key;}/*** 解析** @param jwt* @return* @throws Exception*/public static Claims parseJWT(String jwt) throws Exception {SecretKey secretKey = generalKey();return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();}}
乱写就会抛出异常
4.6.0.3 登录接口实现
数据准备
DROP TABLE IF EXISTS `sys_user`;CREATE TABLE `sys_user` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(50) DEFAULT NULL,`password` varchar(50) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;/*Data for the table `sys_user` */insertinto `sys_user`(`id`,`username`,`password`) values (1,'root','root'),(2,'sangeng','caotang');
实体类
@Data@NoArgsConstructor@AllArgsConstructorpublic class SystemUser {private Integer id;private String username;private String password;}
import com.sangeng.domain.ResponseResult;import com.sangeng.domain.SystemUser;import com.sangeng.service.SystemUserService;import com.sangeng.utils.JwtUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.HashMap;import java.util.Map;import java.util.UUID;@RestController@RequestMapping("/sys_user")public class SystemUserController {@Autowiredprivate SystemUserService userService;@PostMapping("/login")public ResponseResult login(@RequestBody SystemUser user) {//校验用户名密码是否正确SystemUser loginUser = userService.login(user);Map map;if (loginUser != null) {//如果正确 生成token返回map = new HashMap<>();String token = JwtUtil.createJWT(UUID.randomUUID().toString(), String.valueOf(loginUser.getId()), null);map.put("token", token);} else {//如果不正确 给出相应的提示return new ResponseResult(300, "用户名或密码错误,请重新登录");}return new ResponseResult(200, "登录成功", map);}}
public interface SystemUserService {public SystemUser login(SystemUser user);}@Servicepublic class SystemUserServcieImpl implements SystemUserService {@Autowiredprivate SystemUserMapper systemUserMapper;@Overridepublic SystemUser login(SystemUser user) {SystemUser loginUser = systemUserMapper.login(user);return loginUser;}}
dao
@Mapper@Repositorypublic interface UserMapper {List findAll();}
id="login" resultType="com.sangeng.domain.SystemUser">select * from sys_user where username = #{username} and password = #{password}

下  SpringBoot-常见场景-三更补充版

文章插图
>SIGN IN TO CONTINUE.