springboot實戰專案-寰宇外賣重難點總結

crazybuddha發表於2024-10-02

思考

前端和後端的請求地址不同,前端傳送的請求,是如何請求到後端服務的?

可以透過nginx反向代理將前端傳送的動態請求由nginx轉發到後端服務。nginx其他優點:1.提高訪問速度。2.進行負載均衡。3.安全性高,保護後端服務安全。

nginx負載均衡策略:

1.輪詢(預設):按時間順序依次將請求分發到不同的後端伺服器。
2.weight:權重,預設為1,權重越高,分配的請求越多。
3.ip_hash:每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器。
4.fair:按後端伺服器的響應時間來分配請求,響應時間短的優先分配。
5.url_hash:按訪問url的hash結果來分配請求,使相同的url定向到同一個後端伺服器。
6.least_conn:最少連線數,哪個機器連線數少就分發到哪個機器。
7.自定義:自定義負載均衡策略。

Swagger介面文件生成工具

Knife4j是為了java MVC框架整合Swagger生成API文件的工具,前身是swagger-bootstrap-ui。

使用方式:1.匯入Knife4j的maven座標。2.在配置類中加入knife4j的相關配置。3.設定靜態資源對映,為了介面文件頁面的正常訪問。
設定靜態資源對映的原因:Swagger的頁面是透過靜態資源訪問的,而SpringBoot預設的靜態資源路徑是“classpath:/static/”和“classpath:/public/”,所以需要設定靜態資源對映。如果不設定靜態資源對映,那麼就會被當作動態請求,就會報404錯誤。

Swagger介面文件生成工具和YApi的區別

1.Swagger是後端生成介面文件的工具,而YApi是前後端都可以生成介面文件的工具。
2.Swagger是開發階段使用的框架,幫助後端開發人員做介面測試。而YApi是設計階段使用的工具,目的是管理和維護介面。

Knife4j的常見註解

1.@Api:用在類上,表示對類的說明。value:表示說明的內容,name:介面名稱。
2.@ApiOperation:用在方法上,表示對方法的說明。value:表示說明的內容,notes:備註。
3.@ApiModelProperty:用在屬性上,表述屬性資訊
4.@ApiModel:用在類上,表示對類的說明。value:表示說明的內容,description:描述。

作用是讓介面文件的生成更加直觀,方便前後端開發人員理解介面的用途和引數。

具體開發

1.新增員工:

1.1. 根據新增員工介面設計DTO,因為當前端提交的資料和實體類對應的屬性差別過大時,建議使用DTO封裝資料。

2.分頁查詢:

2.1. 使用PageHelper外掛實現分頁查詢。
PageHelper.startPage是一個常用的MyBatis分頁外掛,用於在執行查詢時自動處理分頁邏輯。其基本實現原理如下:
2.1.1. 攔截器機制:PageHelper透過MyBatis的攔截器機制,在查詢方法被呼叫前進行攔截。它會在執行查詢之前,讀取傳入的分頁引數(如頁碼和每頁大小)。
2.1.2. 儲存分頁引數:在攔截器中,PageHelper會將分頁引數儲存到一個執行緒區域性變數中,這樣每個執行緒可以獨立地儲存自己的分頁資訊。
2.1.3. 修改SQL語句:在攔截查詢語句時,PageHelper會對SQL進行修改,新增LIMIT和OFFSET子句,從而實現分頁效果。具體來說,它會根據當前頁碼和每頁大小計算出要跳過的記錄數(OFFSET)和要獲取的記錄數(LIMIT)。
2.1.4. 執行查詢:修改後的SQL被傳遞到資料庫執行,返回相應的分頁結果。
2.1.5. 返回結果:最終,PageHelper將結果封裝成分頁物件(如PageInfo),提供分頁相關的資訊(如總記錄數、總頁數等),方便呼叫者使用。

2.2. 分頁查詢的資料中時間格式化,讓前端顯示正確的日期格式:
2.2.1. 使用@JsonFormat註解,指定日期格式。(只能單次生效,下次碰到同型別的還要加上該註解)
2.2.2. 在WebMvcConfig配置類中,新增日期格式化的配置。(一勞永逸,所有日期格式化都生效)

具體實現程式碼:

/**
 * 物件對映器:基於jackson將Java物件轉為json,或者將json轉為Java物件
 * 將JSON解析為Java物件的過程稱為 [從JSON反序列化Java物件]
 * 從Java物件生成JSON的過程稱為 [序列化Java物件到JSON]
 */
public class JacksonObjectMapper extends ObjectMapper {

    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    //public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";

    public JacksonObjectMapper() {
        super();
        //收到未知屬性時不報異常
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);

        //反序列化時,屬性不存在的相容處理
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        SimpleModule simpleModule = new SimpleModule()
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));

        //註冊功能模組 例如,可以新增自定義序列化器和反序列化器
        this.registerModule(simpleModule);
    }
}
    /**
     * 擴充套件spring mvc框架的訊息轉換器
     * @param converters
     */
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("開始擴充套件訊息轉換器...");
        //建立訊息轉換器列表
        //建立一個訊息轉換器物件
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要為訊息轉換器設定一個物件轉換器,物件轉換器可以將java物件序列化為json資料
        converter.setObjectMapper(new JacksonObjectMapper());
        //將訊息轉換器物件新增到訊息轉換器列表中
        converters.add(0, converter);
    }

3.實現公共欄位自動填充(技術點:列舉、註解、AOP、反射)

3.1.自定義註解Autofill,用於標識需要進行公共欄位自動填充的方法。
3.2.自定義切面類AutoFillAspect,用於統一攔截標有@Autofill註解的方法,透過反射為公共欄位賦值。
3.3.Mapper的方法加入AutoFill註解。

相關文章