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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…