spring -MVC-02

SpringMVC-11 - 響應

在 SpringMVC 中,響應是服務器對客戶端請求的反饋,它可以以多種形式呈現,包括視圖名稱、ModelAndView 對象、JSON 數據以及重定向等。以下是對 SpringMVC 中不同響應類型的詳細介紹:

1. 視圖名稱

通過返回視圖名稱,SpringMVC 會將請求轉發到對應的視圖資源進行渲染。視圖資源可以是 JSP、Thymeleaf 模板、FreeMarker 模板等。

@RequestMapping("/home")

public String home(Model model) {

????model.addAttribute("message", "Welcome to Spring MVC");

? ?return "home"; // 返回視圖名稱

}

在上述示例中,home方法返回一個字符串home,SpringMVC 會根據配置的視圖解析器,將該字符串解析為實際的視圖資源(例如/WEB-INF/views/home.jsp),并將模型數據(message)傳遞給視圖進行渲染。最終,渲染后的視圖將作為響應返回給客戶端。

視圖解析器配置

視圖解析器負責將邏輯視圖名稱解析為實際的視圖資源。常見的視圖解析器有InternalResourceViewResolver、ThymeleafViewResolver等。

InternalResourceViewResolver

@Bean

public ViewResolver viewResolver() {

????InternalResourceViewResolver resolver = new InternalResourceViewResolver();

????resolver.setPrefix("/WEB-INF/views/");

????resolver.setSuffix(".jsp");

return resolver;

}

ThymeleafViewResolver

@Bean

public ViewResolver thymeleafViewResolver(SpringTemplateEngine templateEngine) {

????ThymeleafViewResolver resolver = new ThymeleafViewResolver();

????resolver.setTemplateEngine(templateEngine);

????resolver.setCharacterEncoding("UTF-8");

return resolver;

}

@Bean

public SpringTemplateEngine templateEngine(TemplateResolver templateResolver) {

????SpringTemplateEngine engine = new SpringTemplateEngine();

????engine.setTemplateResolver(templateResolver);

return engine;

}

@Bean

public TemplateResolver templateResolver() {

????ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();

????resolver.setPrefix("/WEB-INF/templates/");

????resolver.setSuffix(".html");

????resolver.setTemplateMode("HTML5");

????resolver.setCharacterEncoding("UTF-8");

return resolver;

}

2. ModelAndView

ModelAndView對象包含了模型數據和視圖信息,通過返回ModelAndView,可以在一個對象中同時指定模型數據和要渲染的視圖。

@RequestMapping("/products")

public ModelAndView listProducts() {

????ModelAndView mav = new ModelAndView("products/list");

????mav.addObject("products", productService.getAllProducts());

return mav;

}

在上述示例中,listProducts方法創建了一個ModelAndView對象,指定了視圖名稱為products/list,并添加了一個名為products的模型數據,該數據包含了所有產品的列表。SpringMVC 會根據視圖名稱解析視圖資源,并將模型數據傳遞給視圖進行渲染。

使用 ModelAndView 的優勢

靈活性高:可以在一個對象中同時處理模型數據和視圖邏輯。

方便傳遞復雜數據結構:適合傳遞多個模型數據或復雜的對象。

3. JSON 響應

在現代 Web 應用中,JSON 是一種常用的數據交換格式。

SpringMVC 提供了對 JSON 響應的支持,通過使用@RestController注解或@ResponseBody注解,可以將方法的返回值直接轉換為 JSON 格式并返回給客戶端。

@RestController

@RequestMapping("/api/products")

public class ProductRestController {

????@GetMapping

????public List<Product> getAllProducts() {

????????return productService.getAllProducts();

}

}

在上述示例中,ProductRestController類使用了@RestController注解,該注解等價于@Controller和@ResponseBody的組合。因此,getAllProducts方法的返回值會被自動轉換為 JSON 格式并返回給客戶端。

JSON 序列化與反序列化

SpringMVC 使用 Jackson 庫來進行 JSON 的序列化和反序列化。Jackson 會自動將 ?對象轉換為 JSON 字符串,并在需要時將 JSON 字符串轉換回 ?對象。

配置 JSON 序列化選項

可以通過配置 Jackson 的ObjectMapper來定制 JSON 的序列化行為,例如:

@Configuration

public class WebConfig implements WebMvcConfigurer {

????@Override

????public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

????????MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

????????ObjectMapper mapper = new ObjectMapper();

????????// 配置序列化選項

????????mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 不序列化null值

????????mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 忽略未知屬性

????????converter.setObjectMapper(mapper);

????????converters.add(converter);

}

}

4. 重定向

重定向是指服務器返回一個 HTTP 狀態碼 302(或其他重定向狀態碼),并在響應頭中指定一個新的 URL,客戶端會根據這個新的 URL 再次發送請求。

@RequestMapping("/save")

public String saveProduct(@ModelAttribute Product product) {

????productService.save(product);

? ? return "redirect:/products";

}

在上述示例中,saveProduct方法在保存產品后,返回一個redirect:/products的字符串,SpringMVC 會將其解析為重定向指令,客戶端會被重定向到/products路徑。

重定向的作用

防止表單重復提交:用戶刷新頁面時不會再次提交表單。

引導用戶到新的頁面:例如注冊成功后重定向到登錄頁面。

重定向傳遞參數

可以使用RedirectAttributes來在重定向過程中傳遞參數:

@RequestMapping("/save")

public String saveProduct(@ModelAttribute Product product, RedirectAttributes attrs) {

????productService.save(product);

????attrs.addFlashAttribute("message", "產品保存成功");

return "redirect:/products";

}

在上述示例中,addFlashAttribute方法添加了一個臨時屬性message,這個屬性只會在重定向后的下一次請求中有效。

總結

SpringMVC 提供了多種響應類型,包括視圖名稱、ModelAndView、JSON 響應和重定向。開發者可以根據具體需求選擇合適的響應方式,以實現靈活、高效的 Web 應用開發。

視圖名稱:適用于傳統的頁面渲染場景,通過視圖解析器將邏輯視圖名映射到實際視圖資源

ModelAndView:提供了更靈活的方式來處理模型數據和視圖邏輯,適合傳遞多個模型數據或復雜對象。

JSON 響應:用于返回 JSON 格式的數據,適用于前后端分離的架構,通過 Jackson 庫進行 JSON 的序列化和反序列化。

重定向:用于引導用戶到新的頁面,防止表單重復提交,可通過RedirectAttributes傳遞臨時參數。

SpringMVC-12-REST 風格簡介

REST (Representational State Transfer) 是一種軟件架構風格,它使用 HTTP 協議的標準方法 (GET、POST、PUT、DELETE) 來操作資源。

REST 的主要特點:

資源導向:每個 URL 代表一種資源

使用標準 HTTP 方法:GET (獲取)、POST (創建)、PUT (更新)、DELETE (刪除)

無狀態:每個請求都是獨立的,不依賴于之前的請求

統一接口:所有資源都通過統一的接口進行操作

SpringMVC-13-RESTful 入門案例

下面是一個簡單的 RESTful API 示例:

@RestController

@RequestMapping("/api/products")

public class ProductRestController {

????@Autowired

????private ProductService productService;

????// 獲取所有產品

????@GetMapping

????public List<Product> getAll() {

????????return productService.getAll();

????}

????// 獲取單個產品

????@GetMapping("/{id}")

????public Product getById(@PathVariable Long id) {

????????return productService.getById(id);

????}

????// 創建產品

????@PostMapping

????public Product create(@RequestBody Product product) {

????????return productService.save(product);

????}

????// 更新產品

????@PutMapping("/{id}")

????public Product update(@PathVariable Long id, @RequestBody Product product) {

????????return productService.update(id, product);

????}

????// 刪除產品

????@DeleteMapping("/{id}")

????public void delete(@PathVariable Long id) {

????????productService.delete(id);

}

}

SpringMVC-14-RESTful 快速開發

可以使用 Spring Data JPA 和 Spring HATEOAS 來加速 RESTful API 的開發。

添加依賴:

xml

<dependency>

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

????<artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency>

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

<artifactId>spring-boot-starter-hateoas</artifactId>

</dependency>

創建實體和 Repository:

@Entity

public class Product {

????@Id

????@GeneratedValue(strategy = GenerationType.IDENTITY)

????private Long id;

????private String name;

????private double price;

// getters and setters....

}

public interface ProductRepository extends JpaRepository<Product, Long> {}

創建資源控制器:

@RestController

@RequestMapping("/api/products")

public class ProductController {

????private final ProductRepository repository;

????private final EntityLinks entityLinks;

????@Autowired

????public ProductController(ProductRepository repository, EntityLinks entityLinks) {

????????this.repository = repository;

????????this.entityLinks = entityLinks;

????}

????@GetMapping

????public Resources<Resource<Product>> getAll() {

????????List<Resource<Product>> products = repository.findAll().stream()

????????????.map(product -> new Resource<>(product,

????????????????linkTo(methodOn(ProductController.class).getOne(product.getId())).withSelfRel(),

????????????????linkTo(methodOn(ProductController.class).getAll()).withRel("products")))

????????????.collect(Collectors.toList());

????????return new Resources<>(products,

????????????linkTo(methodOn(ProductController.class).getAll()).withSelfRel());

????}

????@GetMapping("/{id}")

????public Resource<Product> getOne(@PathVariable Long id) {

????????Product product = repository.findById(id)

????????????.orElseThrow(() -> new ResourceNotFoundException("Product not found with id: " + id));

????????return new Resource<>(product,

????????????linkTo(methodOn(ProductController.class).getOne(id)).withSelfRel(),

????????????linkTo(methodOn(ProductController.class).getAll()).withRel("products"));

}

}

SpringMVC-15 - 案例:基于 RESTful 頁面數據交互 (后臺接口開發)

假設我們要開發一個簡單的產品管理系統,下面是后臺接口的實現:

@RestController

@RequestMapping("/api/products")

public class ProductApiController {

????@Autowired

????private ProductService productService;

????@GetMapping

????public Page<ProductDTO> listProducts(

????????????@RequestParam(name = "page", defaultValue = "0") int page,

????????????@RequestParam(name = "size", defaultValue = "10") int size) {

????????return productService.getProducts(page, size);

????}

????@PostMapping

public ResponseEntity<ProductDTO> createProduct

(@RequestBody ProductDTO productDTO) {

????????ProductDTO createdProduct = productService.createProduct(productDTO);

????????URI location = ServletUriComponentsBuilder

????????????????.fromCurrentRequest()

????????????????.path("/{id}")

????????????????.buildAndExpand(createdProduct.getId())

????????????????.toUri();

????????return ResponseEntity.created(location).body(createdProduct);

????}

????@GetMapping("/{id}")

????public ResponseEntity<ProductDTO> getProduct(@PathVariable Long id) {

????????ProductDTO productDTO = productService.getProduct(id);

????????return ResponseEntity.ok(productDTO);

????}

????@PutMapping("/{id}")

????public ResponseEntity<ProductDTO> updateProduct(@PathVariable Long id, @RequestBody ProductDTO productDTO) {

????????ProductDTO updatedProduct = productService.updateProduct(id, productDTO);

????????return ResponseEntity.ok(updatedProduct);

????}

????@DeleteMapping("/{id}")

????public ResponseEntity<?> deleteProduct(@PathVariable Long id) {

????????productService.deleteProduct(id);

????????return ResponseEntity.noContent().build();

}

}

SpringMVC-16 - 案例:基于 RESTful 頁面數據交互 (頁面訪問處理)

下面是一個使用 Thymeleaf 模板引擎的前端頁面示例:

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<head>

????<title>Product Management</title>

????<script src="https://cdn.tailwindcss.com">

</script>

????<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">

</head>

<body class="bg-gray-100">

????<div class="container mx-auto px-4 py-8">

????????<h1 class="text-3xl font-bold mb-6">Product Management</h1>

????????

????????<div class="mb-6">

????????????<button id="addProductBtn" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">

????????????????<i class="fa fa-plus"></i> Add Product

????????????</button>

????????</div>

????????

????????<div class="bg-white rounded-lg shadow-md p-6 mb-6">

????????????<table class="min-w-full">

????????????????<thead>

????????????????????<tr class="bg-gray-200 text-gray-600 uppercase text-sm leading-normal">

????????????????????????<th class="py-3 px-6 text-left">ID</th>

????????????????????????<th class="py-3 px-6 text-left">Name</th>

????????????????????????<th class="py-3 px-6 text-left">Price</th>

????????????????????????<th class="py-3 px-6 text-left">Actions</th>

????????????????????</tr>

????????????????</thead>

????????????????<tbody id="productsTableBody" class="text-gray-600 text-sm font-light">

????????????????????<!-- Products will be loaded here via Script -->

????????????????</tbody>

????????????</table>

????????</div>

????????

????????<!-- Pagination -->

????????<div id="pagination" class="flex items-center justify-between bg-white rounded-lg shadow-md p-6">

????????????<!-- Pagination controls will be loaded here via Script -->

????????</div>

????????

????????<!-- Add/Edit Modal -->

????????<div id="productModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">

????????????<div class="bg-white rounded-lg shadow-xl w-full max-w-md p-6">

????????????????<h2 id="modalTitle" class="text-2xl font-bold mb-4">Add Product</h2>

????????????????<form id="productForm">

????????????????????<input type="hidden" id="productId">

????????????????????<div class="mb-4">

????????????????????????<label for="productName" class="block text-gray-700 font-bold mb-2">Name:</label>

????????????????????????<input type="text" id="productName" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" required>

????????????????????</div>

????????????????????<div class="mb-4">

????????????????????????<label for="productPrice" class="block text-gray-700 font-bold mb-2">Price:</label>

????????????????????????<input type="number" id="productPrice" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" step="0.01" required>

????????????????????</div>

????????????????????<div class="flex justify-end">

????????????????????????<button type="button" id="cancelBtn" class="mr-2 px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded">Cancel</button>

????????????????????????<button type="submit" class="px-4 py-2 bg-blue-500 hover:bg-blue-700 text-white rounded">Save</button>

????????????????????</div>

????????????????</form>

????????????</div>

????????</div>

????</div>

????

????<script>

????????// Script code for handling API calls and UI interactions

????????document.addEventListener('DOMContentLoaded', function() {

????????????// Load products on page load

????????????loadProducts(0);

????????????

????????????// Add product button click

????????????document.getElementById('addProductBtn').addEventListener('click', function() {

????????????????document.getElementById('modalTitle').textContent = 'Add Product';

????????????????document.getElementById('productId').value = '';

????????????????document.getElementById('productName').value = '';

????????????????document.getElementById('productPrice').value = '';

????????????????document.getElementById('productModal').classList.remove('hidden');

????????????});

????????????

????????????// Cancel button click

????????????document.getElementById('cancelBtn').addEventListener('click', function() {

????????????????document.getElementById('productModal').classList.add('hidden');

????????????});

????????????

????????????// Product form submission

????????????document.getElementById('productForm').addEventListener('submit', function(e) {

????????????????e.preventDefault();

????????????????

????????????????const productId = document.getElementById('productId').value;

????????????????const productName = document.getElementById('productName').value;

????????????????const productPrice = document.getElementById('productPrice').value;

????????????????

????????????????const productData = {

????????????????????name: productName,

????????????????????price: parseFloat(productPrice)

????????????????};

????????????????

????????????????if (productId) {

????????????????????// Update existing product

????????????????????fetch(`/api/products/${productId}`, {

????????????????????????method: 'PUT',

????????????????????????headers: {

????????????????????????????'Content-Type': 'application/json'

????????????????????????},

????????????????????????body: JSON.stringify(productData)

????????????????????})

????????????????????.then(response => response.json())

????????????????????.then(() => {

????????????????????????document.getElementById('productModal').classList.add('hidden');

????????????????????????loadProducts(currentPage);

????????????????????})

????????????????????.catch(error => console.error('Error:', error));

????????????????} else {

????????????????????// Create new product

????????????????????fetch('/api/products', {

????????????????????????method: 'POST',

????????????????????????headers: {

????????????????????????????'Content-Type': 'application/json'

????????????????????????},

????????????????????????body: JSON.stringify(productData)

????????????????????})

????????????????????.then(response => response.json())

????????????????????.then(() => {

????????????????????????document.getElementById('productModal').classList.add('hidden');

????????????????????????loadProducts(0);

????????????????????})

????????????????????.catch(error => console.error('Error:', error));

????????????????}

????????????});

????????});

????????

????????let currentPage = 0;

????????

????????function loadProducts(page) {

????????????currentPage = page;

????????????

????????????fetch(`/api/products?page=${page}`)

????????????????.then(response => response.json())

????????????????.then(data => {

????????????????????const productsTableBody = document.getElementById('productsTableBody');

????????????????????productsTableBody.innerHTML = '';

????????????????????

????????????????????data.content.forEach(product => {

????????????????????????const row = document.createElement('tr');

????????????????????????row.className = 'border-b border-gray-200 hover:bg-gray-100';

????????????????????????

????????????????????????row.innerHTML = `

????????????????????????????<td class="py-3 px-6">${product.id}</td>

????????????????????????????<td class="py-3 px-6">${product.name}</td>

????????????????????????????<td class="py-3 px-6">$${product.price.toFixed(2)}</td>

????????????????????????????<td class="py-3 px-6">

????????????????????????????????<button οnclick="editProduct(${product.id})" class="text-blue-500 hover:text-blue-700 mr-2">

????????????????????????????????????<i class="fa fa-pencil"></i>

????????????????????????????????</button>

????????????????????????????????<button οnclick="deleteProduct(${product.id})" class="text-red-500 hover:text-red-700">

????????????????????????????????????<i class="fa fa-trash"></i>

????????????????????????????????</button>

????????????????????????????</td>

????????????????????????`;

????????????????????????

????????????????????????productsTableBody.appendChild(row);

????????????????????});

????????????????????

????????????????????// Update pagination

????????????????????updatePagination(data);

????????????????})

????????????????.catch(error => console.error('Error:', error));

????????}

????????

????????function editProduct(id) {

????????????fetch(`/api/products/${id}`)

????????????????.then(response => response.json())

????????????????.then(product => {

????????????????????document.getElementById('modalTitle').textContent = 'Edit Product';

????????????????????document.getElementById('productId').value = product.id;

????????????????????document.getElementById('productName').value = product.name;

????????????????????document.getElementById('productPrice').value = product.price;

????????????????????document.getElementById('productModal').classList.remove('hidden');

????????????????})

????????????????.catch(error => console.error('Error:', error));

????????}

????????

????????function deleteProduct(id) {

????????????if (confirm('Are you sure you want to delete this product?')) {

????????????????fetch(`/api/products/${id}`, {

????????????????????method: 'DELETE'

????????????????})

????????????????.then(() => {

????????????????????loadProducts(currentPage);

????????????????})

????????????????.catch(error => console.error('Error:', error));

????????????}

????????}

????????

????????function updatePagination(data) {

????????????const pagination = document.getElementById('pagination');

????????????pagination.innerHTML = '';

????????????

????????????const prevButton = document.createElement('button');

????????????prevButton.className = 'px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded';

????????????prevButton.disabled = !data.first;

????????????prevButton.innerHTML = '<i class="fa fa-chevron-left"></i> Previous';

????????????prevButton.onclick = () => loadProducts(currentPage - 1);

????????????pagination.appendChild(prevButton);

????????????

????????????const pageInfo = document.createElement('span');

????????????pageInfo.className = 'px-4';

????????????pageInfo.textContent = `Page ${data.number + 1} of ${data.totalPages}`;

????????????pagination.appendChild(pageInfo);

????????????

????????????const nextButton = document.createElement('button');

????????????nextButton.className = 'px-4 py-2 bg-gray-200 hover:bg-gray-300 rounded';

????????????nextButton.disabled = !data.last;

????????????nextButton.innerHTML = 'Next <i class="fa fa-chevron-right"></i>';

????????????nextButton.onclick = () => loadProducts(currentPage + 1);

????????????pagination.appendChild(nextButton);

????????}

</script>

</body>

</html>

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

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

相關文章

老舊設備升級利器:Modbus TCP轉 Profinet讓能效監控更智能

在工業自動化領域&#xff0c;ModbusTCP和Profinet是兩種常見的通訊協議。Profinet是西門子公司推出的基于以太網的實時工業以太網標準&#xff0c;而Modbus則是由施耐德電氣提出的全球首個真正開放的、應用于電子控制器上的現場總線協議。這兩種協議各有各的優點&#xff0c;但…

ubuntu下docker安裝mongodb-支持單副本集

1.mogodb支持事務的前提 1) MongoDB 版本&#xff1a;確保 MongoDB 版本大于或等于 4.0&#xff0c;因為事務支持是在 4.0 版本中引入的。 2) 副本集配置&#xff1a;MongoDB 必須以副本集&#xff08;Replica Set&#xff09;模式運行&#xff0c;即使是單節點副本集&#x…

【前端開發】Uniapp日期時間選擇器:實現分鐘動態步長設置

技術棧 Uniapp + Vue3 + uView年份顯示前后一年,分鐘動態設置間隔效果圖 主體顯示<view class="uni-row-between selector"><view class="uni-flex-1 left" @click="!props.disabled && openPicker()"><uni-iconscolor=…

iOS 藍牙開發中的 BT 與 BLE

在 iOS 開發者的語境里&#xff0c;大家把 BT 和 BLE 當成兩種不同的藍牙技術在談——它們來自同一個 Bluetooth 規范&#xff0c;但面向的場景、協議棧乃至 Apple 提供的 API 都截然不同。 縮寫全稱 / 技術名稱規范層叫法iOS 支持現狀典型用途BTBluetooth Classic&#xff08…

Flink CEP是什么?

Apache Flink 的 CEP&#xff08;Complex Event Processing&#xff0c;復雜事件處理&#xff09; 是 Flink 提供的一個庫&#xff0c;用于在無界數據流中檢測符合特定模式的事件組合。 &#x1f3af; 一、什么是 CEP&#xff1f; ? 定義&#xff1a; CEP 是一種從連續的數據…

ARM (Attention Refinement Module)

ARM模塊【來源于BiSeNet】&#xff1a;細化特征圖的注意力&#xff0c;增強重要特征并抑制不重要的特征。 Attention Refinement Module (ARM) 詳解 ARM (Attention Refinement Module) 是 BiSeNet 中用于增強特征表示的關鍵模塊&#xff0c;它通過注意力機制來細化特征圖&…

AR0144CSSC20SUKA0-CRBR——1/4英寸 1.0 MP 高性能CMOS圖像傳感器解析

產品概述&#xff1a; AR0144CSSC20SUKA0-CRBR 是一款1/4 英寸&#xff0c;1.0 Mp CMOS 數字圖像傳感器&#xff0c;帶有 1280H x 800V 有效像素陣列 全局快門CMOS數字圖像傳感器&#xff0c;它結合了新型的創新全局快門像素設計&#xff0c;適用于準確快速的移動場景捕捉。該…

深入理解遞歸算法:Go語言實現指南

深入理解遞歸算法&#xff1a;Go語言實現指南 引言 遞歸是編程中一種優雅而強大的算法思想&#xff0c;通過函數自我調用的方式解決復雜問題。本文將使用Go語言演示遞歸的核心原理&#xff0c;并通過典型示例幫助開發者掌握這一重要技術。 一、遞歸基礎概念 1.1 遞歸定義 遞歸…

vue2實現【瀑布流布局】

瀑布流 1. 解釋2. 形成結構和樣式3. 自定義指令 1. 解釋 瀑布流特征&#xff1a; 等寬不等高&#xff1a;元素寬度固定&#xff0c;高度根據內容自適應。錯落排列&#xff1a;元素像瀑布一樣從上到下依次填充&#xff0c;自動尋找最短列插入 體現&#xff1a;圖中第一排1&…

CSS display有幾種屬性值

在 CSS 中&#xff0c;display 屬性是控制元素布局和渲染方式的核心屬性之一。它有多種屬性值&#xff0c;每個值都決定了元素在文檔流中的表現形式。以下是 display 的主要屬性值分類及說明&#xff1a; 1. 塊級和行內布局 塊級元素 (block) 特性&#xff1a;獨占一行&…

基于Java實現可靠傳輸

實現可靠傳輸 1. 結合代碼和 LOG 文件分析針對每個項目舉例說明解決效果。 RDT1.0 對應 Log 日志&#xff1a;Log 1.0.txt&#xff0c;接收文件 recvData 1.0.txt RDT1.0 版本是在可靠信道上進行可靠的數據傳輸&#xff0c;因此沒有過多的內容需要說明&#xff0c;發送方 L…

機器學習10-隨機森林

隨機森林學習筆記 一、隨機森林簡介 隨機森林&#xff08;Random Forest&#xff09;是一種集成學習算法&#xff0c;基于決策樹構建模型。它通過組合多個決策樹的結果來提高模型的準確性和穩定性。隨機森林的核心思想是利用“集成”的方式&#xff0c;將多個弱學習器組合成一…

LeetCode 438. 找到字符串中所有字母異位詞 | 滑動窗口與字符計數數組解法

文章目錄 問題描述核心思路&#xff1a;滑動窗口 字符計數數組1. 字符計數數組2. 滑動窗口 算法步驟完整代碼實現復雜度分析關鍵點總結類似問題 問題描述 給定兩個字符串 s 和 p&#xff0c;要求找到 s 中所有是 p 的**字母異位詞&#xff08;Anagram&#xff09;**的子串的起…

idea中,git的cherry-pick怎么用

背景: A同學在A分支進行開發, B同學在B分支進行開發,B同學開發過程中發現,A同學在A分支上面的某次提交,例如某次提交了一個工具類,B同學也用的到這個工具類,但是B又不想mergeA分支的代碼,此時就可以用到git的chery pick能力.

深入解析:如何基于開源OpENer開發EtherNet/IP從站服務

一、EtherNet/IP協議概述 EtherNet/IP(Industrial Protocol)是一種基于以太網的工業自動化通信協議,它將CIP(Common Industrial Protocol)封裝在標準以太網幀中,通過TCP/IP和UDP/IP實現工業設備間的通信。作為ODVA(Open DeviceNet Vendors Association)組織的核心協議…

當 PyIceberg 和 DuckDB 遇見 AWS S3 Tables:打造 Serverless 數據湖“開源夢幻組合”

引言 在一些大數據分析場景比如電商大數據營銷中&#xff0c;我們需要快速分析存儲海量用戶行為數據&#xff08;如瀏覽、加購、下單&#xff09;&#xff0c;以進行用戶行為分析&#xff0c;優化營銷策略。傳統方法依賴 Spark/Presto 集群或 Redshift 查詢 S3 上的 Parquet/O…

流復備機斷檔處理

文章目錄 環境癥狀問題原因解決方案 環境 系統平臺&#xff1a;UOS&#xff08;海光&#xff09;,UOS &#xff08;飛騰&#xff09;,UOS&#xff08;鯤鵬&#xff09;,UOS&#xff08;龍芯&#xff09;,UOS &#xff08;申威&#xff09;,銀河麒麟svs&#xff08;X86_64&…

【藍橋杯真題精講】第 16 屆 Python A 組(省賽)

文章目錄 T1 偏藍 (5/5)T2 IPv6 (0/5)T3 2025 圖形 (10/10)T4 最大數字 (10/10)T5 倒水 (15/15)T6 拼好數 (0/15)T7 登山 (20/20)T8 原料采購 (20/20) 更好的閱讀體驗 高速訪問&#xff1a;https://wiki.dwj601.cn/ds-and-algo/lan-qiao-cup/16th-python-a/永久鏈接&#xff1…

SpringBoot+Dubbo+Zookeeper實現分布式系統步驟

SpringBootDubboZookeeper實現分布式系統 一、分布式系統通俗解釋二、環境準備&#xff08;詳細版&#xff09;1. 軟件版本2. 安裝Zookeeper&#xff08;單機模式&#xff09; 三、完整項目結構&#xff08;帶詳細注釋&#xff09;四、手把手代碼實現步驟1&#xff1a;創建父工…

Spring的業務層,持久層,控制層的關系

在 Spring 框架中&#xff0c;控制層&#xff08;Controller&#xff09;、業務層&#xff08;Service&#xff09; 和 持久層&#xff08;Repository/Mapper&#xff09; 是分層架構的核心組成部分&#xff0c;職責分離明確&#xff0c;通過依賴注入&#xff08;DI&#xff09…