上海著名的网站制作公司,莱芜信息港网页,公司网站下二级站点如何做,详情页设计思路文章目录 前言一、redis安装二、后端代码1.修改application.yml文件2.增加utils文件3.增加Result类4.修改UserController类5.修改UserMapper类6.修改UserService和UserServiceImpl类7.增加LoginInterceptor类8.增加WebConfig类9.修改pom.xml文件 前言
前两篇我们用vuespringbo… 文章目录 前言一、redis安装二、后端代码1.修改application.yml文件2.增加utils文件3.增加Result类4.修改UserController类5.修改UserMapper类6.修改UserService和UserServiceImpl类7.增加LoginInterceptor类8.增加WebConfig类9.修改pom.xml文件 前言
前两篇我们用vuespringboot框架实现了一个很简单的查询数据的demo通过这个demo主要是熟悉IDEAU和VSCode等工具的使用以及熟悉vuespringboot前后端分离开发的基本流程。接下来两篇我们将在前面的基础上实现登录这个B/S典型应用场景进一步深入的理解B/S架构、vue的一些基础插件、前后端交互过程。 一、redis安装
1首先下载redis压缩包Redis-x64-3.0.504.zip地址如下 https://github.com/MicrosoftArchive/redis/releases 2解压到本地路径C:\Program Files进入解压后Redis-x64-3.0.504目录执行以下命令 redis-server.exe redis.windows.conf 如下图所示表示redis启动成功。 先把数据库中password改成md5加密如下图admin密码为12345678数据库中改成它的md5码25d55ad283aa400af464c76d713c07ad
二、后端代码
1.修改application.yml文件
spring配置字段下增加以下内容连接redis服务器。
data:redis:host: localhostport: 63792.增加utils文件
增加utils包里面增加JwtUtil、Md5Util、ThreadLocalUtil类增加JWT、MD5和线程局部变量方法。 JwtUtil类代码
package com.example.demo.utils;import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;import java.util.Date;
import java.util.Map;public class JwtUtil {private static final String KEY itheima;//接收业务数据,生成token并返回public static String genToken(MapString, Object claims) {return JWT.create().withClaim(claims, claims).withExpiresAt(new Date(System.currentTimeMillis() 1000 * 60 * 60 )).sign(Algorithm.HMAC256(KEY));}//接收token,验证token,并返回业务数据public static MapString, Object parseToken(String token) {return JWT.require(Algorithm.HMAC256(KEY)).build().verify(token).getClaim(claims).asMap();}}Md5Util类代码
package com.example.demo.utils;import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class Md5Util {/*** 默认的密码字符串组合用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合*/protected static char hexDigits[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f};protected static MessageDigest messagedigest null;static {try {messagedigest MessageDigest.getInstance(MD5);} catch (NoSuchAlgorithmException nsaex) {System.err.println(Md5Util.class.getName() 初始化失败MessageDigest不支持MD5Util。);nsaex.printStackTrace();}}/*** 生成字符串的md5校验值** param s* return*/public static String getMD5String(String s) {return getMD5String(s.getBytes());}/*** 判断字符串的md5校验码是否与一个已知的md5码相匹配** param password 要校验的字符串* param md5PwdStr 已知的md5校验码* return*/public static boolean checkPassword(String password, String md5PwdStr) {String s getMD5String(password);return s.equals(md5PwdStr);}public static String getMD5String(byte[] bytes) {messagedigest.update(bytes);return bufferToHex(messagedigest.digest());}private static String bufferToHex(byte bytes[]) {return bufferToHex(bytes, 0, bytes.length);}private static String bufferToHex(byte bytes[], int m, int n) {StringBuffer stringbuffer new StringBuffer(2 * n);int k m n;for (int l m; l k; l) {appendHexPair(bytes[l], stringbuffer);}return stringbuffer.toString();}private static void appendHexPair(byte bt, StringBuffer stringbuffer) {char c0 hexDigits[(bt 0xf0) 4];// 取字节中高 4 位的数字转换, // 为逻辑右移将符号位一起右移,此处未发现两种符号有何不同char c1 hexDigits[bt 0xf];// 取字节中低 4 位的数字转换stringbuffer.append(c0);stringbuffer.append(c1);}
}ThreadLocalUtil类代码
package com.example.demo.utils;import java.util.HashMap;
import java.util.Map;/*** ThreadLocal 工具类*/
SuppressWarnings(all)
public class ThreadLocalUtil {//提供ThreadLocal对象,private static final ThreadLocal THREAD_LOCAL new ThreadLocal();//根据键获取值public static T T get(){return (T) THREAD_LOCAL.get();}//存储键值对public static void set(Object value){THREAD_LOCAL.set(value);}//清除ThreadLocal 防止内存泄漏public static void remove(){THREAD_LOCAL.remove();}
}3.增加Result类
bean增加Result类定义HTTP返回结果格式。
package com.example.demo.bean;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;//统一响应结果
NoArgsConstructor
AllArgsConstructor
Data
public class ResultT {private Integer code;//业务状态码 0-成功 1-失败private String message;//提示信息private T data;//响应数据//快速返回操作成功响应结果(带响应数据)public static E ResultE success(E data) {return new Result(0, 操作成功, data);}//快速返回操作成功响应结果public static Result success() {return new Result(0, 操作成功, null);}public static Result error(String message) {return new Result(1, message, null);}
}4.修改UserController类
selectAll方法的返回值需要使用Result定义格式参照下面代码改一下然后增加login方法处理/user/login请求校验用户名、密码后生成JWT令牌并保存在redis中当其它请求过来时需要验证JWT令牌同时令牌中还保存了用户名和密码等信息当需要这些信息时就不用再查询mysql数据库。 Autowiredprivate StringRedisTemplate stringRedisTemplate;PostMapping(/login)public ResultString login(Pattern(regexp ^\\S{5,16}$) String username, Pattern(regexp ^\\S{5,16}$) String password) {//根据用户名查询用户User loginUser userService.findByUserName(username);//判断该用户是否存在if (loginUser null) {return Result.error(用户名错误);}//判断密码是否正确 loginUser对象中的password是密文if (Md5Util.getMD5String(password).equals(loginUser.getPassword())) {//登录成功MapString, Object claims new HashMap();claims.put(id, loginUser.getId());claims.put(username, loginUser.getUserName());String token JwtUtil.genToken(claims);//把token存储到redis中ValueOperationsString, String operations stringRedisTemplate.opsForValue();operations.set(token,token,1, TimeUnit.HOURS);return Result.success(token);}return Result.error(密码错误);}增加后有些字段会是红色工具支持自动导入相关的类鼠标放在字段上会出现下图提示选择“Import class”即可。 注意Pattern字段工具自动导入的类是 import org.intellij.lang.annotations.Pattern; 这里regexp可能识别不到那就换成下面的类但需要增加spring-boot-starter-validation依赖 import jakarta.validation.constraints.Pattern;
5.修改UserMapper类
增加findByUserName方法。 //根据用户名查询用户Select(select * from users where userName#{username})User findByUserName(String username);6.修改UserService和UserServiceImpl类
UserService类增加 //根据用户名查询用户User findByUserName(String username);UserServiceImpl类增加 Overridepublic User findByUserName(String username) {User u userMapper.findByUserName(username);return u;}7.增加LoginInterceptor类
增加interceptors包里面增加LoginInterceptor类这里主要通过拦截器处理校验令牌的过程。
Component
public class LoginInterceptor implements HandlerInterceptor {Autowiredprivate StringRedisTemplate stringRedisTemplate;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//处理OPTIONS请求时返回正确的CORS头部信息if (request.getMethod().equals(OPTIONS)) {response.setHeader(Access-Control-Allow-Origin, *);//*表示放行所有的源response.setHeader(Access-Control-Allow-Methods, GET, POST, PUT, DELETE, HEAD, OPTIONS);response.setHeader(Access-Control-Allow-Headers, *);response.setHeader(Access-Control-Allow-Credentials, true);response.setStatus(HttpServletResponse.SC_OK);return false;}else {//令牌验证String token request.getHeader(Authorization);//验证tokentry {//从redis中获取相同的tokenValueOperationsString, String operations stringRedisTemplate.opsForValue();String redisToken operations.get(token);if (redisToken null) {//token已经失效了throw new RuntimeException();}MapString, Object claims JwtUtil.parseToken(token);//把业务数据存储到ThreadLocal中ThreadLocalUtil.set(claims);//放行return true;} catch (Exception e) {//http响应状态码为401response.setStatus(401);//不放行return false;}}}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//清空ThreadLocal中的数据ThreadLocalUtil.remove();}
}这里调试的时候出现跨域访问不了后端/user/selectAll的情况所以需要加上OPTIONS这段代码。
8.增加WebConfig类
增加config包里面增加WebConfig类如果不需要拦截可以在这里设置。
Configuration
public class WebConfig implements WebMvcConfigurer {Autowiredprivate LoginInterceptor loginInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {//登录接口不拦截registry.addInterceptor(loginInterceptor).excludePathPatterns(/user/login);}//解决跨域问题Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**).allowedOriginPatterns(*).allowedMethods(GET, HEAD, POST,PUT, DELETE, OPTIONS).allowCredentials(true).maxAge(3600);}
}解决跨域问题可以直接在这里增加addCorsMappings方法这样就不需要在每个controller类中增加CrossOrigin。
9.修改pom.xml文件
增加上面代码需要的依赖。
!--redis坐标--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency
!--lombok依赖--dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependency
!--java-jwt坐标--dependencygroupIdcom.auth0/groupIdartifactIdjava-jwt/artifactIdversion4.4.0/version/dependency
!--validation依赖--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency下一篇我们继续实现前端代码