项目随笔-【大事件(文章类)】

cnblogs 2024-07-01 15:39:00 阅读 61

项目随笔-【大事件(文章类)】

自定义参数校验注解

需要写一个自定义注解Xxx+校验规则的类XxxValidation【需要继承ConstraintValidator】

自定义注解

@Documented

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

@Constraint(validatedBy = {StateValidation.class})//使用 `StateValidation` 类来验证该字段的值是否满足特定的约束条件

public @interface State {

String message() default "state参数的值只能是已发布或者草稿";//验证失败的错误提示信息

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}

注解校验规则

public class StateValidation implements ConstraintValidator<State,String> {

@Override

public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {

//校验规则

if (value == null){

return false;

}

if (value.equals("已发布") || value.equals("草稿")){

return true;

}

return false;

}

}

  • <State>ConstraintValidator 接口的第一个泛型参数,它指定了验证器将要验证的约束注解的类型。在这个例子中,State 可能是一个自定义的注解,用于标记需要验证的字段。
  • <String>ConstraintValidator 接口的第二个泛型参数,它指定了验证器将要验证的属性值的类型。在这个例子中,String 表示 StateValidation 类将验证 String 类型的属性值。

阿里云Oss存储

工具类

public class AliOssUtil {

// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。

private static final String ENDPOINT = "https://oss-cn-hangzhou.aliyuncs.com";

// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。【这里没使用】

// EnvironmentVariableCredentialsProvider credentialsProvider =

// CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

private static final String ACCESS_KEY_ID = "LTAI5tJKk5H98ZmQQ9CgeG8y";

private static final String ACCESS_KEY_SECRET = "90xHhXxKig6LNnbb4ubpRBeIdw7RAT";

// 填写Bucket名称,例如examplebucket。

private static final String BUCKET_NAME = "zy-bigevent";

public static String uploadFile(String objectName, InputStream in) throws Exception {

// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。

// 创建OSSClient实例。

OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

String url = "";

try {

// 填写字符串。

String content = "Hello OSS,你好世界";

// 创建PutObjectRequest对象。

PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, objectName, in);

// 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。

// ObjectMetadata metadata = new ObjectMetadata();

// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());

// metadata.setObjectAcl(CannedAccessControlList.Private);

// putObjectRequest.setMetadata(metadata);

// 上传字符串。

PutObjectResult result = ossClient.putObject(putObjectRequest);

url = "https://" + BUCKET_NAME + "." + ENDPOINT.substring(ENDPOINT.lastIndexOf("/") + 1) + "/" + objectName;

} catch (OSSException oe) {

System.out.println("Caught an OSSException, which means your request made it to OSS, "

+ "but was rejected with an error response for some reason.");

System.out.println("Error Message:" + oe.getErrorMessage());

System.out.println("Error Code:" + oe.getErrorCode());

System.out.println("Request ID:" + oe.getRequestId());

System.out.println("Host ID:" + oe.getHostId());

} catch (ClientException ce) {

System.out.println("Caught an ClientException, which means the client encountered "

+ "a serious internal problem while trying to communicate with OSS, "

+ "such as not being able to access the network.");

System.out.println("Error Message:" + ce.getMessage());

} finally {

if (ossClient != null) {

ossClient.shutdown();

}

}

return url;

}

}

Controller

@RestController

public class FileUploadController {

@PostMapping("/upload")

public Result<String> upload(MultipartFile file) throws Exception {

//把文件的内容存储到本地磁盘

String originalFilename = file.getOriginalFilename();

String fileName = UUID.randomUUID().toString()+originalFilename.substring(originalFilename.lastIndexOf("."));

// file.transferTo(new File("C:\\Users\\23117\\Desktop\\files\\"+originalFilename));

String url = AliOssUtil.uploadFile(fileName, file.getInputStream());

return Result.success(url);

}

}

Redis主动失效令牌

令牌主动失效机制

● 登录成功后,给浏览器响应令牌的同时,把该令牌存储到redis中。

● LoginInterceptor拦截器中,需要验证浏览器携带的令牌,并同时需要获取到redis中存储的与之相同的令牌。

● 当用户修改密码成功后,删除redis中存储的旧令牌。

登录

@PostMapping("/login")

public Result<String> login(String username,String password) {

//业务逻辑...

String token = JwtUtil.genToken(claims);

//把 token 存储到 redis 中

ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();

//redis存储令牌 key 和 value 都是 token

operations.set(token,token,1, TimeUnit.HOURS);//TimeUnit.HOURS 是 redis key 的过期时间单位

return Result.success(token);

//业务逻辑...

}

更换密码【此时需要主动删除redis中的token】

@PatchMapping("/updatePwd")

public Result updatePwd(@RequestBody Map<String, String> parms,@RequestHeader("Authorization") String token) {

//业务逻辑...

userService.updatePwd(newPwd);//更新新密码

//删除redis对应的token

ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();

operations.getOperations().delete(token);

return Result.success();

}

拦截器

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//令牌验证

String token = request.getHeader("Authorization");

try {

//获取redid key

ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();

String redisToken = operations.get(token);

if (redisToken == null){

//token 已经失效

throw new RuntimeException();

}

Map<String, Object> claims = JwtUtil.parseToken(token);

ThreadLocalUtil.set(claims);

//放行

return true;

} catch (Exception e) {

response.setStatus(401);

//不放行

return false;

}

}

SpringBoot项目部署

需要pom.xml文件加入打包插件

<build>

<plugins>

<!-- 打包插件-->

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

<version>3.3.0</version>

</plugin>

</plugins>

</build>

在maven生命周期中点击 package生成jar

在对应环境部署 java -jar 【 jar的名字 】

SpringBoot配置方式

SpringBoot多环境开发

  • SpringBoot多环境开发需要分开发环境、测试环境、生产环境

SpringBoot多环境开发单文件配置

#通用信息,指定生效的环境

spring:

profiles:

active: dev

server:

servlet:

context-path: /aaa

---

#开发环境

spring:

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://localhost:3306/big_event

username: root

password: zy

servlet:

multipart:

max-file-size: 5MB

data:

redis:

host: localhost

port: 6379

config:

activate:

on-profile: dev

mybatis:

configuration:

map-underscore-to-camel-case: true #开启驼峰命名/下划线命名转换

server:

port: 8081

---

#测试环境

spring:

config:

activate:

on-profile: test

server:

port: 8082

---

#生产环境

spring:

config:

activate:

on-profile: pro

server:

port: 8084

SpringBoot多环境开发多文件配置

application.yml

#通用信息,指定生效的环境

spring:

profiles:

active: test

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://localhost:3306/big_event

username: root

password: zy

server:

servlet:

context-path: /aaa

application-dev.yml

#开发环境

config:

activate:

on-profile: dev

server:

port: 8081

application-pro.yml

#生产环境

spring:

config:

activate:

on-profile: pro

server:

port: 8084

application-test.yml

#测试环境

spring:

config:

activate:

on-profile: test

server:

port: 8082

SpringBoot多环境开发多文件配置-分组

application.yml

#通用信息,指定生效的环境

spring:

profiles:

group:

"dev": devService,devDB,devSelf

active: dev

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://localhost:3306/big_event

username: root

password: zy

server:

servlet:

context-path: /aaa

application-devService

#开发环境

server:

port: 8085

application-devDb

#数据库相关配置

application-devSelf

#自定义相关配置

项目参考:

B站:BV14z4y1N7pg



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。