SpringMVC學習(二)——RESTful API、攔截器、異常處理、數據類型轉換

一、RESTful?

(一)RESTful概述

????????RESTful是一種軟件架構風格,用于設計網絡應用程序。REST是“Representational State Transfer”的縮寫,中文意思是“表現層狀態轉移”。它基于客戶端-服務器模型和無狀態操作,以及使用HTTP請求來處理數據。RESTful架構風格強調利用HTTP協議的四個主要方法(GET、POST、PUT、DELETE)來實現資源的訪問和操作。以下是RESTful架構的一些核心原則:

  1. 客戶端-服務器分離:客戶端和服務器之間的交互應該是簡單的,服務器端負責存儲數據和業務邏輯,客戶端負責展示。

  2. 無狀態:每個請求從客戶端到服務器必須包含所有必要的信息,以便服務器能夠理解請求并獨立地處理它,不依賴于之前的任何請求。

  3. 可緩存:數據被標記為可緩存或不可緩存。如果數據被標記為可緩存,那么客戶端可以緩存數據以提高效率。

  4. 統一接口:系統組件之間的交互通過統一的接口進行,這簡化了整體系統架構,使得系統更容易理解、開發和使用。

  5. 分層系統:客戶端不能直接了解它所消費的服務之外的任何服務器信息,也不應該知道它的數據是來自一個服務器還是多個服務器。

  6. 按需代碼(可選):服務器可以按需向客戶端發送代碼,比如JavaScript,以便在客戶端執行。

????????在RESTful架構中,資源(Resources)是核心概念,每個資源都有一個唯一的標識符,通常是一個URI。客戶端通過HTTP方法對這些資源進行操作:

  • GET:請求從服務器檢索特定資源。GET請求應該是安全的,不會產生副作用。

  • POST:向服務器提交新的資源,通常會導致創建新的資源。

  • PUT:更新服務器上的現有資源。

  • DELETE:從服務器上刪除資源。

????????RESTful API設計簡潔、直觀,易于理解和使用,因此在現代網絡應用中非常流行

代碼示例:?

@CrossOrigin  // 允許跨域請求
@RestController
@RequestMapping("/emp")
public class EmpController {@Autowiredprivate EmpService empService;/*** 查詢員工*/@GetMapping("/{empno}")public R queryEmpById(@PathVariable("empno") Integer empno) {Emp emp = empService.queryById(empno);return R.ok(emp);}/*** 新增員工*/@PostMappingpublic R addEmp(@RequestBody Emp emp) {empService.save(emp);return R.ok();}/*** 修改員工*/@PutMappingpublic R editEmp(@RequestBody Emp emp) {empService.update(emp);return R.ok();}/*** 刪除員工*/@DeleteMapping("/{empno}")public R deleteEmpById(@PathVariable("empno") Integer empno) {empService.deleteById(empno);return R.ok();}/*** 查詢所有員工*/@GetMapping("/getAll")public R queryEmpList() {List<Emp> empList = empService.getList();return R.ok(empList);}
}

(二)@PathVariable:從URL中提取路徑變量

????????@PathVariable是Spring MVC中用于從URL中提取路徑變量的注解。它允許將URL模板中的占位符映射到方法參數,從而實現動態路由和數據傳遞。
使用場景:

  • RESTful API:在設計RESTful API時,通常會使用@PathVariable來獲取資源的唯一標識符(如 ID)。
  • 動態內容:根據 URL 中的變量來動態生成頁面或響應內容。

二、攔截器

(一)HandlerInterceptor

????????HandlerInterceptor是SpringMVC內置攔截器機制,用于在請求處理的不同階段插入自定義邏輯。它允許在請求到達控制器之前、控制器處理請求之后以及請求完成之后執行特定的操作。比如:權限驗證、日志記錄、數據共享等......

使用步驟:

  • 實現HandlerInterceptor接口的組件即可成為攔截器
  • 創建WebMvcConfigurer組件,并配置攔截器的攔截路徑
  • 執行順序:順序preHandle→目標方法→倒序postHandle→渲染→倒序afterCompletion
  • 只有執行成功的preHandle會倒序執行afterCompletion
  • postHandle、afterCompletion從哪里跑出異常,倒序鏈路從哪里結束
  • postHandle失敗不會影響afterCompletion執行
@Component  // 攔截器還需要配置(告訴SpringMVC,這個攔截器主要攔截什么請求)
public class MyHandlerInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("MyHandlerInterceptor...preHandle...");return false; // true表示放行,false表示攔截}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("MyHandlerInterceptor...postHandle...");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("MyHandlerInterceptor...afterCompletion...");}
}
@Configuration  // 專門對SpringMVC底層進行配置
public class MySpringMVCConfig implements WebMvcConfigurer {@AutowiredMyHandlerInterceptor myHandlerInterceptor;/*** 添加攔截器*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myHandlerInterceptor).addPathPatterns("/**"); // 攔截所有請求}
}
@CrossOrigin  // 允許跨域請求
@RestController
@RequestMapping("/emp")
public class EmpController {@Autowiredprivate EmpService empService;/*** 查詢員工*/@GetMapping("/{empno}")public R queryEmpById(@PathVariable("empno") Integer empno) {System.out.println("查詢用戶。目標方法執行......");Emp emp = empService.queryById(empno);return R.ok(emp);}
}

(二)攔截器與過濾器的區別(面試題)?

三、異常處理

1.編程式異常處理

編程式異常處理:如果大量業務都需要加異常處理代碼會很麻煩

@GetMapping("/hello")
public R hello(@RequestParam(value = "i", defaultValue = "0") Integer i) {try {int j = 10 / i;return R.ok(j);} catch (Exception e) {return R.error(100, "除數不能為0", e.getMessage());}
}

2.聲明式異常處理

  1. 如果Controller本類出現異常,會自動在本類中找到有沒有@ExceptionHandler標注的方法,如果有,執行這個方法,它的返回值,就是客戶端收到的結果;如果發生異常,多個都能處理,就精確的優先。
  2. 異常處理的優先級:本類 > 全局;精確 > 模糊
  3. 如果出現了異常:本類和全局都不能處理,SpringBoot底層對SpringMVC有兜底處理機制:自適應處理(瀏覽器響應頁面、移動端響應JSON)
  4. 最佳實踐:編寫全局異常處理器,處理所有異常
@RestController
public class HelloController {@GetMapping("/hello")public R hello(@RequestParam(value = "i", defaultValue = "0") Integer i) throws FileNotFoundException {int j = 10 / i;
//        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\lxm\\Desktop\\test.txt");String str = null;str.length();return R.ok(j);}@ExceptionHandler(ArithmeticException.class)public R handlerArithmeticException(ArithmeticException e) {System.out.println("ArithmeticException異常處理");return R.error(100, "除數不能為0", e.getMessage());}@ExceptionHandler(FileNotFoundException.class)public R FileNotFoundException(FileNotFoundException e) {System.out.println("FileNotFoundException異常處理");return R.error(300, "文件找不到", e.getMessage());}@ExceptionHandler(Throwable.class)public R handlerException(Throwable e) {System.out.println("Throwable異常處理");return R.error(500, "其他異常", e.getMessage());}
}
// @ResponseBody
// @ControllerAdvice   // 告訴SpringMVC,這個類是處理全局異常的
@RestControllerAdvice  // 全局異常處理器:相當于@ControllerAdvice + @ResponseBody
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public R handleException(Throwable e) {System.out.println("全局異常處理");return R.error(500, e.getMessage());}@ExceptionHandler(ArithmeticException.class)public R handlerArithmeticException(ArithmeticException e) {System.out.println("算數異常處理");return R.error(100, e.getMessage());}
}

3.異常處理的最終方式

  1. 必須有業務異常類:BusinessException
  2. 必須有異常枚舉類:BusinessExceptionEnum列舉項目中每個模塊將會出現的所有異常情況
  3. 編寫業務代碼的時候,只需編寫正確邏輯,如果出現預期的問題,需要以拋異常的方式中斷邏輯并通知上層
  4. 全局異常處理器:GlobalExceptionHandler 處理所有異常,返回給前端約定的JSON數據與錯誤碼

異常枚舉類:?

public enum BusinessExceptionEnum {ORDER_NOT_EXIST(10001, "訂單不存在"),ORDER_STATUS_ERROR(10002, "訂單狀態錯誤"),ORDER_UPDATE_ERROR(10003, "訂單更新失敗"),ORDER_DELETE_ERROR(10004, "訂單刪除失敗"),ORDER_CREATE_ERROR(10005, "訂單創建失敗"),ORDER_QUERY_ERROR(10006, "訂單查詢失敗"),ORDER_PAY_ERROR(10007, "訂單支付失敗"),ORDER_CANCEL_ERROR(10008, "訂單取消失敗");@Getterprivate Integer code;@Getterprivate String msg;BusinessExceptionEnum(Integer code, String msg) {this.code = code;this.msg = msg;}
}

全局業務異常類:?

@Data
public class BusinessException extends RuntimeException {private Integer code;private String msg;public BusinessException(Integer code, String msg) {super(msg);this.code = code;this.msg = msg;}public BusinessException(BusinessExceptionEnum businessExceptionEnum) {super(businessExceptionEnum.getMsg());this.code = businessExceptionEnum.getCode();this.msg = businessExceptionEnum.getMsg();}
}

業務代碼?

@Override
public void update(Emp emp) {// 去數據庫查詢原來的值Integer empno = emp.getEmpno();if (empno == null) {throw new BusinessException(BusinessExceptionEnum.ORDER_NOT_EXIST);}Emp empById = empDao.getEmpById(empno);if (StringUtils.hasText(empById.getEname())) {empById.setEname(emp.getEname());}empDao.updateEmp(emp);
}

四、SpringMVC原理

五、數據類型轉換

1.String轉Date類型

@Controller
@RequestMapping("/book")
public class BookController {@GetMapping("/jump")public String jump(){// int i = 1/0;return "book/add";}@PostMapping("/doAdd")@ResponseBodypublic BookModel doAdd(BookModel book){return book;/*** {*   "id": null,*   "name": "紅樓夢",*   "ctime": 1735228800000* }*/}@PostMapping("/doAdd2")@ResponseBodypublic Date doAdd2(String name,@DateTimeFormat(pattern = "yyyy-MM-dd") Date ctime){return ctime; // 1735142400000}
}
@Data
public class BookModel {private Integer id;private String name;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date ctime;
}

2.String轉LocalDateTime類型

自定義參數類型轉換器:

public class StringToDate implements Converter<String, Date> {@Overridepublic Date convert(String s) {//傳入的參數,等待被轉換的2024-12-27 字符串System.out.println(s);SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");Date date = null;try {date = simpleDateFormat.parse(s);} catch (ParseException e) {throw new RuntimeException(e);}return date;}
}public class StringToDateTime implements Converter<String, LocalDateTime> {@Overridepublic LocalDateTime convert(String s) {return LocalDateTime.parse(s, DateTimeFormatter.ISO_LOCAL_DATE_TIME);}
}
@Data
public class BookModel {private Integer id;private String name;
//    @DateTimeFormat(pattern = "yyyy-MM-dd")private Date ctime;
//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime utime;
}

3.接收JSON字符串

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.2</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>2.11.2</version>
</dependency>
/*** 接收JSON轉換日期時間*/
@PostMapping("/doAdd3")
@ResponseBody
public BookModel doAdd3(@RequestBody BookModel book){return book;
}
@Data
public class BookModel {private Integer id;private String name;// @DateTimeFormat(pattern = "yyyy-MM-dd")private Date ctime;@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime utime;
}

注意:

JSON時間,可以寫2024-01-27 09:09:09
不能寫 2024-1-27 9:9:9

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64352.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64352.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64352.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Windows中安裝Python3

Windows中安裝Python3 1. 下載Python安裝包 首先&#xff0c;訪問Python的官方網站 Python.org&#xff0c;選擇適合你Windows版本的Python安裝包。 2. 運行安裝包 下載完成.exe文件后&#xff0c;雙擊運行安裝包。在安裝過程中&#xff0c;有一些關鍵的選項需要特別注意&a…

JS數值類型中特殊數值NaN(Not-a-Number)理解和應用場景

NaN 的含義 在 JavaScript 中&#xff0c;NaN 是一種特殊的數值類型&#xff0c;表示 “Not-a-Number”。它通常用于標識數學運算或類型轉換的結果無法產生有效數值的情況。 特性 類型為數值&#xff1a; console.log(typeof NaN); // "number"盡管 NaN 表示 “不是…

虛幻引擎結構之UWorld

Uworld -> Ulevel ->Actors -> AActor 在虛幻引擎中&#xff0c;UWorld 類扮演著至關重要的角色&#xff0c;它就像是游戲世界的總指揮。作為游戲世界的核心容器&#xff0c;UWorld 包含了構成游戲體驗的眾多元素&#xff0c;從游戲實體到關卡設計&#xff0c;再到物…

java中logback怎么開啟異步功能

在Java中使用Logback時&#xff0c;開啟異步日志記錄功能可以通過配置AsyncAppender來實現。異步日志記錄可以顯著提高應用程序的性能&#xff0c;因為它將日志記錄操作從主線程移到了后臺線程執行&#xff0c;從而減少了主線程的阻塞時間。 步驟 1: 添加 Logback 配置文件 確…

2024第一屆Solar杯應急響應挑戰賽

日志流量 日志流量-1 直接放到D盾分析 解碼 flag{A7b4_X9zK_2v8N_wL5q4} 日志流量-2 哥斯拉流量 工具解一下 flag{sA4hP_89dFh_x09tY_lL4SI4} 日志流量-3 tcp流6復制data流 解碼 改pdf flag{dD7g_jk90_jnVm_aPkcs} 內存取證 內存取證-1 vol.py -f 123.raw --profileWin…

HarmonyOS Next 實現登錄注冊頁面(ARKTS) 并使用Springboot作為后端提供接口

1. HarmonyOS next ArkTS ArkTS圍繞應用開發在 TypeScript &#xff08;簡稱TS&#xff09;生態基礎上做了進一步擴展&#xff0c;繼承了TS的所有特性&#xff0c;是TS的超集 ArkTS在TS的基礎上擴展了struct和很多的裝飾器以達到描述UI和狀態管理的目的 以下代碼是一個基于…

Spring Boot教程之四十:使用 Jasypt 加密 Spring Boot 項目中的密碼

如何使用 Jasypt 加密 Spring Boot 項目中的密碼 在本文中&#xff0c;我們將學習如何加密 Spring Boot 應用程序配置文件&#xff08;如 application.properties 或 application.yml&#xff09;中的數據。在這些文件中&#xff0c;我們可以加密用戶名、密碼等。 您經常會遇到…

【Vue】如何在 Vue 3 中使用組合式 API 與 Vuex 進行狀態管理的詳細教程

如何在 Vue 3 中使用組合式 API 與 Vuex 進行狀態管理的詳細教程。 安裝 Vuex 首先&#xff0c;在你的 Vue 3 項目中安裝 Vuex。可以使用 npm 或 yarn&#xff1a; npm install vuexnext --save # or yarn add vuexnext創建 Store 在 Vue 3 中&#xff0c;你可以使用 creat…

七、隊列————相關概念詳解

隊列————相關概念詳解 前言一、隊列1.1 隊列是什么?1.2 隊列的類比 二、隊列的常用操作三、隊列的實現3.1 基于數組實現隊列3.1.1 基于環形數組實現的隊列3.1.2 基于動態數組實現的隊列 3.2 基于鏈表實現隊列 四、隊列的典型應用總結 前言 本篇文章&#xff0c;我們一起來…

基于 Ragflow 搭建知識庫-初步實踐

基于 Ragflow 搭建知識庫-初步實踐 一、簡介 Ragflow 是一個強大的工具&#xff0c;可用于構建知識庫&#xff0c;實現高效的知識檢索和查詢功能。本文介紹如何利用 Ragflow 搭建知識庫&#xff0c;包括環境準備、安裝步驟、配置過程以及基本使用方法。 二、環境準備 硬件要…

Pandas03

Pandas01 Pandas02 文章目錄 內容回顧1 排序和統計函數2 缺失值處理2.1 認識缺失值2.2 缺失值處理- 刪除2.3 缺失值處理- 填充非時序數據時序數據 3 Pandas數據類型3.1 數值類型和字符串類型之間的轉換3.2 日期時間類型3.3 日期時間索引 4 分組聚合4.1 分組聚合的API使用4.2 分…

springboot整合log4j2日志框架1

一 log4j基本知識 1.1 log4j的日志級別 Log4j定義了8個級別的log&#xff08;除去OFF和ALL&#xff0c;可以說分為6個級別&#xff09;&#xff0c;優先級從低到高依次為&#xff1a;All&#xff0c;trace&#xff0c;debug&#xff0c;info&#xff0c;warn&#xff0c;err…

Spring源碼_05_IOC容器啟動細節

前面幾章&#xff0c;大致講了Spring的IOC容器的大致過程和原理&#xff0c;以及重要的容器和beanFactory的繼承關系&#xff0c;為后續這些細節挖掘提供一點理解基礎。掌握總體脈絡是必要的&#xff0c;接下來的每一章都是從總體脈絡中&#xff0c; 去研究之前沒看的一些重要…

WPF使用OpenCvSharp4

WPF使用OpenCvSharp4 創建項目安裝OpenCvSharp4 創建項目 安裝OpenCvSharp4 在解決方案資源管理器中&#xff0c;右鍵單擊項目名稱&#xff0c;選擇“管理 NuGet 包”。搜索并安裝以下包&#xff1a; OpenCvSharp4OpenCvSharp4.ExtensionsOpenCvSharp4.runtime.winSystem.Man…

leetcode 3083. 字符串及其反轉中是否存在同一子字符串 簡單

給你一個字符串 s &#xff0c;請你判斷字符串 s 是否存在一個長度為 2 的子字符串&#xff0c;在其反轉后的字符串中也出現。 如果存在這樣的子字符串&#xff0c;返回 true&#xff1b;如果不存在&#xff0c;返回 false 。 示例 1&#xff1a; 輸入&#xff1a;s "…

TCP-UDP調試工具推薦:Socket通信測試教程(附詳細圖解)

前言 在網絡編程與應用開發中&#xff0c;調試始終是一項不可忽視的重要環節。尤其是在涉及TCP/IP、UDP等底層網絡通信協議時&#xff0c;如何確保數據能夠準確無誤地在不同節點間傳輸&#xff0c;是許多開發者關注的核心問題。 調試的難點不僅在于定位連接建立、數據流控制及…

Vue.js框架:在線教育系統的安全性與穩定性

2.1系統開發使用的關鍵技術 本系統在開發中選擇B/S框架進行設計&#xff0c;語言采用Java&#xff0c;數據庫采用Mysql&#xff0c;并在設計中加入VUE.js技術&#xff0c;本系統的運行環境為Idea。 2.2 VUE.js技術介紹 VUE.js是一個用來開發前臺界面的JavaScript框架&#xff0…

【新方法】通過清華鏡像源加速 PyTorch GPU 2.5安裝及 CUDA 版本選擇指南

下面詳細介紹所提到的兩條命令&#xff0c;它們的作用及如何在你的 Python 環境中加速 PyTorch 等庫的安裝。 1. 設置清華鏡像源 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple這條命令的作用是將 pip &#xff08;Python 的包管理工具&#xf…

【數據結構】單鏈表的使用

單鏈表的使用 1、基本概念2、鏈表的分類3、鏈表的基本操作a、單鏈表節點設計b、單鏈表初始化c、單鏈表增刪節點**節點頭插&#xff1a;****節點尾插&#xff1a;****新節點插入指定節點后&#xff1a;**節點刪除&#xff1a; d、單鏈表修改節點e、單鏈表遍歷&#xff0c;并打印…

虛幻引擎是什么?

Unreal Engine&#xff0c;是一款由Epic Games開發的游戲引擎。該引擎主要是為了開發第一人稱射擊游戲而設計&#xff0c;但現在已經被成功地應用于開發模擬游戲、恐怖游戲、角色扮演游戲等多種不同類型的游戲。虛幻引擎除了被用于開發游戲&#xff0c;現在也用于電影的虛擬制片…