数据库以及其他项目配置

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 该项目配置了数据库连接和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

相关文章
|
20天前
|
存储 监控 安全
数据库多实例的部署与配置方法
【10月更文挑战第23天】数据库多实例的部署和配置需要综合考虑多个因素,包括硬件资源、软件设置、性能优化、安全保障等。通过合理的部署和配置,可以充分发挥多实例的优势,提高数据库系统的运行效率和可靠性。在实际操作中,要不断总结经验,根据实际情况进行调整和优化,以适应不断变化的业务需求。
|
13天前
|
消息中间件 资源调度 关系型数据库
如何在Flink on YARN环境中配置Debezium CDC 3.0,以实现实时捕获数据库变更事件并将其传输到Flink进行处理
本文介绍了如何在Flink on YARN环境中配置Debezium CDC 3.0,以实现实时捕获数据库变更事件并将其传输到Flink进行处理。主要内容包括安装Debezium、配置Kafka Connect、创建Flink任务以及启动任务的具体步骤,为构建实时数据管道提供了详细指导。
36 9
|
13天前
|
安全 Nacos 数据库
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改。本文详细探讨了这一问题的原因及解决方案,包括限制公网访问、使用HTTPS、强化数据库安全、启用访问控制、监控和审计等步骤,帮助开发者确保服务的安全运行。
27 3
|
16天前
|
PHP 数据库 数据安全/隐私保护
布谷直播源码部署服务器关于数据库配置的详细说明
布谷直播系统源码搭建部署时数据库配置明细!
|
18天前
|
Java 数据库连接 数据库
如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面
本文介绍了如何构建高效稳定的Java数据库连接池,涵盖连接池配置、并发控制和异常处理等方面。通过合理配置初始连接数、最大连接数和空闲连接超时时间,确保系统性能和稳定性。文章还探讨了同步阻塞、异步回调和信号量等并发控制策略,并提供了异常处理的最佳实践。最后,给出了一个简单的连接池示例代码,并推荐使用成熟的连接池框架(如HikariCP、C3P0)以简化开发。
39 2
|
20天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
61 2
|
27天前
|
SQL JavaScript 关系型数据库
node博客小项目:接口开发、连接mysql数据库
【10月更文挑战第14天】node博客小项目:接口开发、连接mysql数据库
|
1月前
|
前端开发 Java 数据库连接
javamvc配置,增删改查,文件上传下载。
【10月更文挑战第4天】javamvc配置,增删改查,文件上传下载。
37 1
|
1月前
|
关系型数据库 MySQL Java
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
这篇文章是关于如何使用Django框架配置MySQL数据库,创建模型实例,并自动或手动创建数据库表,以及对这些表进行操作的详细教程。
62 0
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
|
21天前
|
SQL 关系型数据库 数据库连接
"Nacos 2.1.0版本数据库配置写入难题破解攻略:一步步教你排查连接、权限和配置问题,重启服务轻松解决!"
【10月更文挑战第23天】在使用Nacos 2.1.0版本时,可能会遇到无法将配置信息写入数据库的问题。本文将引导你逐步解决这一问题,包括检查数据库连接、用户权限、Nacos配置文件,并提供示例代码和详细步骤。通过这些方法,你可以有效解决配置写入失败的问题。
46 0