項目隨筆-【大事件(文章類)】

来源:https://www.cnblogs.com/zydevelop/p/18278015/zy_event
-Advertisement-
Play Games

項目隨筆-【大事件(文章類)】 自定義參數校驗註解 需要寫一個自定義註解Xxx+校驗規則的類XxxValidation【需要繼承ConstraintValidator】 自定義註解 @Documented @Target(ElementType.FIELD) @Retention(Retention ...


項目隨筆-【大事件(文章類)】

自定義參數校驗註解

需要寫一個自定義註解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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要介紹了,當使用Python創建自定義類時,如何為其添加屬性,包括為類和實例添加屬性兩種,以及如何獲取自定義的屬性等內容。 ...
  • 本文主要介紹了串口通信協議的基本概念、串口通信的基本流程、如何使用 Python 語言創建一個類和類內成員中屬性和方法的定義。 ...
  • 本文主要介紹了面向對象編程的基本概念:類和對象、三大特性-繼承封裝多態、UML類圖和對象圖的基本概念以及教程所需要的開發環境。 ...
  • 大家好,我是曉凡。 寫在前面 在上一篇文章,我們詳細介紹了SpringBoot3 怎麼整合SpringDoc實現線上介面文檔。但是,有不少小伙伴 都覺得介面界面太醜了。有沒有什麼更美觀一點的UI界面呢? 當然是有的了,畢竟這是一個看臉的時代,Knife4j 這不來了麽。 一、界面比較 這兒我們將上一 ...
  • 本文以springboot+vue技術開發的低代碼平臺為案例,介紹應用系統如何集成企業微信,包括同步企業微信組織用戶、單點登錄、消息發送等。 ...
  • Tex類繼承自MathTex,具體功能和MathTex差不多,有一些細節的差別。在實際的使用中,我感覺Tex在結合一般文本和公式時更方便一些,所以我用的比較多的是Tex。Tex在manim各個模塊中的位置大致如上圖中所示。 1. Tex與MathTex區別 Tex的主要參數和方法和MathTex是一 ...
  • 應用場景:需要創建純色圖像,作為背景圖, 在此基礎上添加文字、形狀、新的圖片等等 原理: cv2的讀取圖片操作本質上是將圖片轉換為uint8的numpy.ndarray類型, 後續的其他圖像操作,本質上也是對於這個ndarray對象的操作 首先用numpy創建一個形狀為(224,224,3)、元素值 ...
  • Markdown 憑藉其簡潔易用的特性,成為創建和編輯純文本文檔的常用選擇。但某些時候我們需要更加精緻的展示效果,例如在專業分享文檔或列印成離線使用的紙質版時,就需要將Markdown文件以其他固定的文檔格式呈現。通過將 Markdown 轉換為 Word 和 PDF 格式,可以得到更多的格式設置, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...