数据库以及其他项目配置

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 该项目配置了数据库连接和MyBatis设置,并解决了配置文件加载问题。启动类使用 `@SpringBootApplication` 注解,可通过 `@ComponentScan` 指定扫描包。Lombok 自动生成 getter/setter 等方法,简化代码。Result 实体类用于统一返回格式。用户模块包括注册与登录功能,使用 MD5 加密密码、Spring Validation 参数校验及 JWT 认证。JWT 工具类处理令牌生成与解析,并通过拦截器验证。Redis 优化登录功能,利用 ThreadLocal 存储用户信息。此外,还包括文章模块的相关功能,如文章分类管理、

数据库以及其他项目配置
server:
port: 9090

spring:
datasource:
url: jdbc:mysql://localhost:3306/lostarknote
username: root
password: guxiang
driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
configuration:
map-underscore-to-camel-case: true
遇到问题:找不到"url"....
可能原因:没有扫描到配置文件(yml),在pom.xml中的build标签中添加以下内容



src/main/java

/*.yml
/ .properties
**/.xml

false


src/main/resources

/*.yml
/ .properties
**/.xml

false

启动类相关
@SpringBootApplication:包扫描时,自动扫描启动类所在包及其子包,若需要扫描其他包,需要使用@ComponentScan进行包名指定

Lombok工具:
自动生成getter/setter/toString方法 ,需要引入lombok依赖,然后在实体类上添加@Data注解


org.projectlombok
lombok
1.18.30

Result实体类
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Result {

private Integer code;
private String message;
private T data;

public static <E> Result<E> 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);
}

}

用户模块

注册功能:

1.密码加密
public class MD5Util {
//生成MD5
public static String getMD5(String message) {
String md5 = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5"); // 创建一个md5算法对象
byte[] messageByte = message.getBytes("UTF-8");
byte[] md5Byte = md.digest(messageByte); // 获得MD5字节数组,16*8=128位
md5 = bytesToHex(md5Byte); // 转换为16进制字符串
} catch (Exception e) {
e.printStackTrace();
}
return md5;
}

// 二进制转十六进制
public static String bytesToHex(byte[] bytes) {
    StringBuffer hexStr = new StringBuffer();
    int num;
    for (int i = 0; i < bytes.length; i++) {
        num = bytes[i];
        if(num < 0) {
            num += 256;
        }
        if(num < 16){
            hexStr.append("0");
        }
        hexStr.append(Integer.toHexString(num));
    }
    return hexStr.toString().toUpperCase();
}

}

2.参数校验——Spring Validation
image.png

3.全局异常处理器
@RestControllerAdvice
public class GobalExceptionHandler {

@ExceptionHandler(Exception.class)
public Result handleException(Exception e)
{
    e.printStackTrace();
    return Result.error(StringUtils.hasLength(e.getMessage())? e.getMessage() : "操作失败!");
}

}

登录功能

登录认证:JWT令牌
image.png
image.png

JWT工具类
public class JWTUtil {
private static final String SECRET = "guxiang";

public static String generateToken(Map<String, Object> claims){
    return JWT.create()
            .withClaim("claims", claims)
            .withExpiresAt(new Date(System.currentTimeMillis()* 1000 * 60 * 60 * 24))
            .sign(Algorithm.HMAC256(SECRET));
}

public static Map<String, Object> parseToken(String token){
    return JWT.require(Algorithm.HMAC256(SECRET))
            .build()
            .verify(token)
            .getClaim("claims")
            .asMap();
}

}

JWT验证:从请求头中获取token
@RestController
@RequestMapping("/dungeon")
public class DungeonController {

@GetMapping("/list")
public Result<String> list(@RequestHeader("Authorization") String token, HttpServletResponse response) {
    //验证token
    //若能正常解析(不报错),则验证通过
    try {
        Map<String, Object> claims = JWTUtil.parseToken(token);
        return Result.success("副本数据获取成功!");
    }catch (Exception e) {
        response.setStatus(401);
        return Result.error("未登录!");
    }

}

}

进阶:注册拦截器进行验证。
注册一个拦截器进行token的验证,就不用单独在每个业务代码里进行token验证

@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//令牌验证
String token = request.getHeader("Authorization");

    //若能正常解析(不报错),则验证通过
    try {
        Map<String, Object> claims = JWTUtil.parseToken(token);
        //放行
        return true;
    }catch (Exception e) {
        response.setStatus(401);
        return false;
    }
}

}
@Configuration
public class WebConfig implements WebMvcConfigurer {

@Autowired
private LoginInterceptor loginInterceptor;

@Override
public void addInterceptors(InterceptorRegistry registry) {
    //登录注册不用拦截
    registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login","/user/register");
}

}
@RestController
@RequestMapping("/dungeon")
public class DungeonController {

@GetMapping("/list")
public Result<String> list() {
    //这里不用再验证token,已经统一在拦截器中做验证
    return Result.success("副本数据获取成功!");
}

}

登录优化——Redis
image.png
image.png

获取用户信息

ThreadLocal
获取用户信息需要通过token中存储的username到数据库中查找,需要解析token。
在其他业务可能也需要username的信息,又要解析token,为了避免代码重复,在之前拦截器中解析出的token统一放到线程中(ThreadLocal)。
image.png

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);
}

public static void remove() {
    THREAD_LOCAL.remove();
}

}
拦截器中将数据存入ThreadLocal中,请求完成后清除ThreadLocal,防止内存泄露

@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//令牌验证
String token = request.getHeader("Authorization");

    //若能正常解析(不报错),则验证通过
    try {
        Map<String, Object> claims = JWTUtil.parseToken(token);
        //将数据存储到ThreadLocal中
        ThreadLocalUtil.set(claims);
        //放行
        return true;
    }catch (Exception e) {
        response.setStatus(401);
        return false;
    }
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    //清空ThreadLocal中的数据,防止内存泄露
    ThreadLocalUtil.remove();
}

}
接口中从ThreadLocal中获取数据

@GetMapping("/userInfo")
public Result userInfo(@RequestHeader("Authorization") String token) {
// Map claims = JWTUtil.parseToken(token);
// String username = (String) claims.get("username");

    Map<String, Object> map = ThreadLocalUtil.get();
    String username = (String) map.get("username");

    User loginUser = userService.findByUsername(username);

    return Result.success(loginUser);
}

//代码效果参考:https://www.h3cw.com/sitemap/post.html
@JsonIgnore
image.png

更新用户信息

实体类中参数验证
image.png

更新用户密码
参数用一个map接收,因为接受的参数名与数据库中不一致
更新用户信息时,参数名与字段名一致,所以用user实体类接收
image.png

文章模块

新增文章分类

文章分类列表

@JsonFormat
image.png

文章分类详情

更新文章分类
image.png

新增文章

自定义校验
image.png

文章分页查询
image.png
image.png
image.png
image.png

文件上传
image.png

相关文章
|
12天前
|
SQL 关系型数据库 分布式数据库
PolarDB Proxy配置与优化:提升数据库访问效率
【9月更文挑战第6天】PolarDB是阿里云推出的高性能分布式关系型数据库,PolarDB Proxy作为其关键组件,位于客户端与PolarDB集群间,负责SQL请求的解析与转发,并支持连接池管理、SQL过滤及路由规则等功能。本文详细介绍了PolarDB Proxy的配置方法,包括连接池、负载均衡和SQL过滤设置,并探讨了监控调优、缓存及网络优化策略,以帮助提升数据库访问效率。
21 1
|
27天前
|
安全 Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+jsp实现的健身房管理系统(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和JSP技术实现的健身房管理系统。随着健康生活观念的普及,健身房成为日常锻炼的重要场所,高效管理会员信息、课程安排等变得尤为重要。该系统旨在通过简洁的操作界面帮助管理者轻松处理日常运营挑战。技术栈包括:JDK 1.8、Maven 3.6、MySQL 8.0、JSP、Shiro、Spring Boot 2.0等。系统功能覆盖登录、会员管理(如会员列表、充值管理)、教练管理、课程管理、器材管理、物品遗失管理、商品管理及信息统计等多方面。
|
26天前
|
关系型数据库 MySQL Linux
在Linux中,如何配置数据库服务器(如MySQL或PostgreSQL)?
在Linux中,如何配置数据库服务器(如MySQL或PostgreSQL)?
|
25天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
在数字化时代背景下,本文详细介绍了如何使用Spring Boot框架结合Vue.js技术栈,实现一个前后端分离的考试管理系统。该系统旨在提升考试管理效率,优化用户体验,确保数据安全及可维护性。技术选型包括:Spring Boot 2.0、Vue.js 2.0、Node.js 12.14.0、MySQL 8.0、Element-UI等。系统功能涵盖登录注册、学员考试(包括查看试卷、答题、成绩查询等)、管理员功能(题库管理、试题管理、试卷管理、系统设置等)。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
|
5天前
|
SQL 关系型数据库 MySQL
MySQL技术安装配置、数据库与表的设计、数据操作解析
MySQL,作为最流行的关系型数据库管理系统之一,在WEB应用领域中占据着举足轻重的地位。本文将从MySQL的基本概念、安装配置、数据库与表的设计、数据操作解析,并通过具体的代码示例展示如何在实际项目中应用MySQL。
21 0
|
30天前
|
JavaScript Java Maven
毕设项目&课程设计&毕设项目:springboot+vue实现的在线求职管理平台(含教程&源码&数据库数据)
本文介绍了一款基于Spring Boot和Vue.js实现的在线求职平台。该平台采用了前后端分离的架构,使用Spring Boot作为后端服务
毕设项目&课程设计&毕设项目:springboot+vue实现的在线求职管理平台(含教程&源码&数据库数据)
|
21天前
|
关系型数据库 MySQL 机器人
Django入门到放弃之数据库配置
Django入门到放弃之数据库配置
|
25天前
|
开发框架 .NET 关系型数据库
【Azure 应用服务】App Service 通过门户配置数据库连接字符串不生效 
【Azure 应用服务】App Service 通过门户配置数据库连接字符串不生效 
|
1月前
|
安全 Nacos 数据库
【技术安全大揭秘】Nacos暴露公网后被非法访问?!6大安全加固秘籍,手把手教你如何保护数据库免遭恶意篡改,打造坚不可摧的微服务注册与配置中心!从限制公网访问到启用访问控制,全方位解析如何构建安全防护体系,让您从此告别数据安全风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其公网暴露可能引发数据库被非法访问甚至篡改的安全隐患。本文剖析此问题并提供解决方案,包括限制公网访问、启用HTTPS、加强数据库安全、配置访问控制及监控等,帮助开发者确保服务安全稳定运行。
76 0