首页 > 其他分享 >项目随笔-【大事件(文章类)】

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

时间:2024-07-01 15:01:15浏览次数:1  
标签:return String spring server token 事件 文章 随笔 public

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

自定义参数校验注解

需要写一个自定义注解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

标签:return,String,spring,server,token,事件,文章,随笔,public
From: https://www.cnblogs.com/zydevelop/p/18278015/zy_event

相关文章

  • 文字游侠:AI模型一键生成爆款文章,让你效率提高20倍!附渠道和小白教程!
    自去年起,人工智能(AI)的话题热度急剧上升,各种AI工具如雨后春笋般涌现,为我们的日常生活和工作带来了极大的便利。近期,小编发现了一款名为“文字游侠”的AI文章生成工具,它极大地提高了自媒体文章创作的效率,甚至可达20倍之多。【工具模型简介】:“文字游侠”头条神器,是一款集全自......
  • 如何刻画复杂事件
    前言复杂事件的刻画✍️[网摘整理]设\(A\),\(B\)是试验\(E\)的随机事件,深入体会用基本事件的和或积的运算来刻画复杂事件,并熟练掌握:①\(A\)发生:\(A=AB+A\bar{B}\);②只有\(A\)发生:\(A\bar{B}\);③\(A\),\(B\)恰有一个发生:\(A\bar{B}\)+\(\bar{A}B\);④\(A\),\(B\)同时发......
  • 随笔杂谈 | HW到底什么时候开始
    前言关于国护时间网上是众说纷纭,有人说自己认识xxx国护7月份,有人说自己见过xxx文件国护6月份。有人说小道消息国护8月份。反正说啥的都有。那么今天笔者就来简单聊聊,国护究竟什么时候开始。1、没有人会知道国护的准确时间。2、红头文件下发!=明确HW时间。3、红头文件不......
  • 如何避免 `click` 和 `mousedown` 事件之间的冲突
    Genie你好!为了避免click和mousedown事件之间的冲突,可以通过检查拖拽的状态来决定是否应触发click事件。我们可以设置一个简单的延迟,并使用一个标志位来确定是否应该忽略click事件。下面是修改后的代码:<script>const{remote,ipcRenderer}=require('electron'......
  • 2024/06/24笔记随笔
    网格布局创建简易计算器publicclassCalculatorDemoextendsApplication{privatedoublenumber1=0;privateStringoperator="";privatebooleanstart=true;@Overridepublicvoidstart(Stagestage)throwsException{stage.......
  • 2024/06/23笔记随笔
    创建文本输入框:````plaintextTextFieldtextField=newTextField();textField.setPromptText("请输入文字");//提示信息textField.setMaxWidth(100);*设置按钮的点击事件处理器:````plaintext//创建按钮的点击事件处理器Buttonbutton=newButton("Clickme");......
  • 【测试文章搬运】创建泛型和测试套件
    创建泛型和测试套件泛型根据字面概念,通用词可以作为整个组或类的描述。在自动化应用程序时,我们会遇到各种端到端场景。端到端场景可能由几个简单的功能组成。因此,这些功能中的许多功能只需稍加修改或几乎无需修改即可作为多个测试脚本的通用功能。因此,建议创建一个通用类,其中......
  • 【测试文章搬运】测试计划包含哪些要素?
    ComponentsOfAPlanDocumentItemsinaTestPlanTemplateWhatdotheycontain?Scope=>TestScenarios/Testobjectivesthatwillbevalidated.  Outofscope=>Enhancedclarityonwhatwearenotgoingtocover  Assumptions=&g......
  • 【测试文章搬运】用selenium并从excel里面读取测试数据——采用数据驱动测试自动化框
    SeleniumFrameworkCreationAndAccessingTestDataFromExcel–SeleniumTutorial在本系列的当前教程中,我们将为您提供一个示例框架,用于存储测试数据及其Excel操作的Excel。同样,我们将继续前进并引入新的策略和资源来完善我们的框架。让我们学习一下:使用示例项目的......
  • 【测试文章搬运】如何建立一个测试卓越中心(TCOE)
    HowToSetUpATestingCenterOfExcellence(TCoE)本综合指南详细介绍了什么是测试卓越中心以及如何设置TCoE。它包括优点和缺点、KPI和发展阶段:随着公司转向软件开发的新方式,测试作为一种集中式服务变得越来越普遍。组织正在寻找在多个团队中成功部署测试人员的方法,同时......