SpringMVC控制器定义:@Controller注解详解

在这里插入图片描述

文章目录

    • 引言
    • 一、@Controller注解基础
    • 二、@RequestMapping与请求映射
    • 三、参数绑定与数据校验
    • 四、@RestController与RESTful API
    • 五、控制器建议与全局处理
    • 六、控制器测试策略
    • 总结

引言

在SpringMVC框架中,控制器(Controller)是整个Web应用的核心组件,负责处理用户请求并返回相应的响应。@Controller注解是Spring框架提供的一种声明式方式,用于定义控制器类,它不仅简化了开发流程,还提供了丰富的功能特性。深入理解@Controller注解的工作原理及其衍生注解,对于开发高质量的Web应用至关重要。本文将全面剖析@Controller注解的用法、特性及其在SpringMVC中的核心地位,通过详细的代码示例展示其实际应用,帮助开发者掌握这一核心注解的精髓,从而更高效地构建Web应用。

一、@Controller注解基础

@Controller注解是SpringMVC框架中最基础的注解之一,用于标识一个类作为控制器。被@Controller标注的类将被Spring容器识别并注册为Bean,同时具备处理HTTP请求的能力。@Controller本质上是@Component注解的特化,继承了@Component的所有功能,但更具有语义价值,明确表示该类在MVC架构中扮演控制器角色。在SpringMVC框架中,@Controller与@RequestMapping等注解配合使用,实现请求URL到处理方法的映射,构成了Web请求处理的核心机制。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.ui.Model;/*** 基本控制器示例* 使用@Controller注解标识该类为控制器*/
@Controller
@RequestMapping("/users")
public class UserController {/*** 处理GET请求,显示用户列表页面* @param model 视图模型* @return 视图名称*/@RequestMapping(method = RequestMethod.GET)public String listUsers(Model model) {// 添加数据到模型model.addAttribute("title", "用户列表");// 返回视图名称,视图解析器会将其解析为实际的视图return "user/list";}/*** 处理GET请求,显示用户详情页面* @param userId 用户ID* @param model 视图模型* @return 视图名称*/@RequestMapping(value = "/{userId}", method = RequestMethod.GET)public String getUserDetails(@RequestParam("userId") Long userId, Model model) {// 获取用户详情并添加到模型User user = userService.getUserById(userId);model.addAttribute("user", user);return "user/details";}
}

二、@RequestMapping与请求映射

@RequestMapping注解是@Controller注解的重要搭配,用于将HTTP请求映射到控制器的具体处理方法。@RequestMapping可以标注在类级别和方法级别,前者定义基础URL路径,后者定义具体的URL模式。@RequestMapping支持多种属性配置,包括value/path(指定URL路径)、method(限定HTTP方法类型)、params(限定请求参数)、headers(限定请求头)、consumes(限定请求内容类型)和produces(指定响应内容类型)。从Spring 4.3开始,框架还提供了更具语义化的派生注解,如@GetMapping、@PostMapping等,使代码更加清晰易读。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.ui.Model;/*** 演示各种请求映射方式的控制器*/
@Controller
@RequestMapping("/products")
public class ProductController {/*** 使用@GetMapping处理GET请求(Spring 4.3+)* 等同于@RequestMapping(method = RequestMethod.GET)*/@GetMappingpublic String listProducts(Model model) {return "product/list";}/*** 处理带路径变量的GET请求* @param productId 产品ID(从URL路径中提取)*/@GetMapping("/{productId}")public String getProductDetails(@PathVariable Long productId, Model model) {return "product/details";}/*** 处理POST请求,限定Content-Type为application/json*/@PostMapping(consumes = "application/json")public String createProduct(@RequestBody Product product, Model model) {return "redirect:/products";}/*** 处理PUT请求,同时指定请求和响应的Content-Type*/@PutMapping(value = "/{productId}", consumes = "application/json",produces = "application/json")@ResponseBodypublic Product updateProduct(@PathVariable Long productId, @RequestBody Product product) {// 更新产品并返回更新后的对象return updatedProduct;}/*** 根据请求参数匹配的处理方法* 仅当请求包含category参数且不包含type参数时才会匹配*/@GetMapping(params = {"category", "!type"})public String getProductsByCategory(@RequestParam String category, Model model) {return "product/category";}/*** 根据请求头匹配的处理方法* 仅当请求包含指定Accept头时才会匹配*/@GetMapping(headers = "Accept=text/html")public String getProductsForBrowser() {return "product/browser-view";}
}

三、参数绑定与数据校验

SpringMVC提供了强大的参数绑定机制,使控制器方法能够接收各种类型的请求数据。参数绑定包括多种形式,如简单类型参数(@RequestParam)、路径变量(@PathVariable)、请求体(@RequestBody)、表单对象(@ModelAttribute)等。除了参数绑定,SpringMVC还集成了Bean Validation规范,支持通过注解进行数据校验。通过@Valid或@Validated注解,可以触发绑定对象的验证,验证结果会存储在BindingResult中。这种声明式的数据验证方式,大大减少了样板代码,提高了开发效率和代码质量。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.BindingResult;
import org.springframework.ui.Model;import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Min;
import javax.validation.constraints.Email;
import org.hibernate.validator.constraints.Length;/*** 演示参数绑定和数据校验的控制器*/
@Controller
@RequestMapping("/customers")
public class CustomerController {/*** 显示客户注册表单*/@GetMapping("/register")public String showRegistrationForm(Model model) {model.addAttribute("customer", new Customer());return "customer/register";}/*** 处理客户注册请求* 使用@Valid触发数据校验,BindingResult接收校验结果*/@PostMapping("/register")public String registerCustomer(@Valid @ModelAttribute("customer") Customer customer,BindingResult bindingResult,Model model) {// 检查是否有验证错误if (bindingResult.hasErrors()) {return "customer/register"; // 返回表单页面,显示错误信息}// 处理注册逻辑customerService.register(customer);model.addAttribute("message", "注册成功!");return "redirect:/customers/login";}/*** 使用@RequestParam接收查询参数*/@GetMapping("/search")public String searchCustomers(@RequestParam(required = false) String name,@RequestParam(defaultValue = "1") int page,Model model) {// 执行搜索List<Customer> customers = customerService.searchByName(name, page);model.addAttribute("customers", customers);return "customer/search-results";}/*** 使用@PathVariable接收路径变量*/@GetMapping("/{id}")public String getCustomerDetails(@PathVariable("id") Long customerId, Model model) {Customer customer = customerService.getById(customerId);model.addAttribute("customer", customer);return "customer/details";}/*** 处理RESTful API请求* 使用@RequestBody接收JSON请求体*/@PostMapping(value = "/api", consumes = "application/json")@ResponseBodypublic CustomerResponse createCustomerApi(@Valid @RequestBody Customer customer) {// 处理创建逻辑Customer created = customerService.create(customer);// 返回响应对象return new CustomerResponse(created.getId(), "Customer created successfully");}
}/*** 包含验证注解的客户实体类*/
public class Customer {private Long id;@NotBlank(message = "姓名不能为空")@Length(max = 50, message = "姓名长度不能超过50个字符")private String name;@NotBlank(message = "邮箱不能为空")@Email(message = "邮箱格式不正确")private String email;@Min(value = 18, message = "年龄必须大于或等于18岁")private int age;// Getters and Setters// ...
}/*** API响应对象*/
public class CustomerResponse {private Long id;private String message;public CustomerResponse(Long id, String message) {this.id = id;this.message = message;}// Getters and Setters// ...
}

四、@RestController与RESTful API

随着RESTful API的普及,Spring框架引入了@RestController注解,它是@Controller和@ResponseBody的组合注解。@RestController标注的控制器中,所有方法的返回值会自动序列化为HTTP响应体,无需再添加@ResponseBody注解。这种方式特别适合构建RESTful Web服务,既简化了代码,又明确了控制器的用途。@RestController与@RequestMapping及其派生注解(@GetMapping, @PostMapping等)配合使用,可以轻松构建符合REST架构风格的API,支持JSON/XML等多种数据格式,满足现代Web应用的需求。

import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;import java.util.List;/*** RESTful API控制器示例* 使用@RestController注解,所有方法返回值都会自动序列化为响应体*/
@RestController
@RequestMapping("/api/v1/orders")
public class OrderApiController {private final OrderService orderService;/*** 构造器注入服务*/public OrderApiController(OrderService orderService) {this.orderService = orderService;}/*** 获取所有订单* @return 订单列表*/@GetMappingpublic List<Order> getAllOrders() {return orderService.findAll();}/*** 根据ID获取订单* @param id 订单ID* @return 订单详情*/@GetMapping("/{id}")public ResponseEntity<Order> getOrderById(@PathVariable Long id) {return orderService.findById(id).map(order -> ResponseEntity.ok(order)).orElse(ResponseEntity.notFound().build());}/*** 创建新订单* @param order 订单数据* @return 创建的订单*/@PostMapping@ResponseStatus(HttpStatus.CREATED)public Order createOrder(@Valid @RequestBody Order order) {return orderService.create(order);}/*** 更新订单* @param id 订单ID* @param order 订单数据* @return 更新后的订单*/@PutMapping("/{id}")public ResponseEntity<Order> updateOrder(@PathVariable Long id, @Valid @RequestBody Order order) {return orderService.update(id, order).map(updated -> ResponseEntity.ok(updated)).orElse(ResponseEntity.notFound().build());}/*** 部分更新订单* @param id 订单ID* @param updates 部分更新数据* @return 更新后的订单*/@PatchMapping("/{id}")public ResponseEntity<Order> partialUpdateOrder(@PathVariable Long id,@RequestBody Map<String, Object> updates) {return orderService.partialUpdate(id, updates).map(updated -> ResponseEntity.ok(updated)).orElse(ResponseEntity.notFound().build());}/*** 删除订单* @param id 订单ID* @return 无内容响应*/@DeleteMapping("/{id}")public ResponseEntity<Void> deleteOrder(@PathVariable Long id) {boolean deleted = orderService.delete(id);if (deleted) {return ResponseEntity.noContent().build();} else {return ResponseEntity.notFound().build();}}/*** 处理订单状态变更* @param id 订单ID* @param status 新状态* @return 更新后的订单*/@PutMapping("/{id}/status")public ResponseEntity<Order> updateOrderStatus(@PathVariable Long id,@RequestParam OrderStatus status) {return orderService.updateStatus(id, status).map(updated -> ResponseEntity.ok(updated)).orElse(ResponseEntity.notFound().build());}/*** 处理订单异常情况*/@ExceptionHandler(OrderProcessingException.class)@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)public ApiError handleOrderProcessingException(OrderProcessingException ex) {return new ApiError(HttpStatus.UNPROCESSABLE_ENTITY.value(), ex.getMessage());}
}/*** API错误响应对象*/
class ApiError {private int status;private String message;private LocalDateTime timestamp = LocalDateTime.now();public ApiError(int status, String message) {this.status = status;this.message = message;}// Getters and Setters// ...
}

五、控制器建议与全局处理

在实际开发中,往往需要在多个控制器之间共享数据或行为,Spring提供了@ControllerAdvice和@RestControllerAdvice注解来实现这一需求。这两个注解用于定义控制器建议类,可以包含@ExceptionHandler(处理异常)、@InitBinder(初始化数据绑定器)和@ModelAttribute(添加全局数据)方法。控制器建议类提供了一种集中管理跨控制器关注点的机制,如统一异常处理、全局数据预处理等。通过合理使用这些注解,可以使代码更加模块化,减少重复,提高维护性。在大型应用中,良好的控制器建议设计对于保持代码质量和一致性至关重要。

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.ui.Model;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.ModelAndView;import java.beans.PropertyEditorSupport;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;/*** 控制器建议类* 适用于所有控制器*/
@ControllerAdvice
public class GlobalControllerAdvice {/*** 全局异常处理* 处理所有控制器中抛出的ResourceNotFoundException*/@ExceptionHandler(ResourceNotFoundException.class)public ModelAndView handleResourceNotFoundException(ResourceNotFoundException ex) {ModelAndView modelAndView = new ModelAndView("error/not-found");modelAndView.addObject("message", ex.getMessage());modelAndView.setStatus(HttpStatus.NOT_FOUND);return modelAndView;}/*** 全局数据绑定器初始化* 为所有控制器添加日期格式化支持*/@InitBinderpublic void initBinder(WebDataBinder binder) {// 注册自定义属性编辑器,处理LocalDate类型binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");@Overridepublic void setAsText(String text) throws IllegalArgumentException {if (text == null || text.trim().isEmpty()) {setValue(null);} else {setValue(LocalDate.parse(text.trim(), formatter));}}@Overridepublic String getAsText() {LocalDate value = (LocalDate) getValue();return (value != null ? value.format(formatter) : "");}});// 忽略指定字段,防止安全敏感信息被修改binder.setDisallowedFields("id", "createdAt", "createdBy");}/*** 全局模型属性* 为所有控制器的视图添加通用数据*/@ModelAttributepublic void addCommonAttributes(Model model) {model.addAttribute("appName", "My Spring Application");model.addAttribute("copyrightYear", LocalDate.now().getYear());// 添加全局用户信息UserDetails currentUser = SecurityUtils.getCurrentUser();if (currentUser != null) {model.addAttribute("currentUser", currentUser);}}
}/*** REST API专用的控制器建议* 仅适用于@RestController标注的控制器*/
@RestControllerAdvice
public class GlobalRestControllerAdvice {/*** 处理REST API中的异常* 返回JSON格式的错误信息*/@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public ApiError handleException(Exception ex) {return new ApiError(HttpStatus.INTERNAL_SERVER_ERROR.value(),"An unexpected error occurred: " + ex.getMessage());}/*** 处理数据校验异常*/@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public ApiError handleValidationExceptions(MethodArgumentNotValidException ex) {Map<String, String> errors = new HashMap<>();ex.getBindingResult().getFieldErrors().forEach(error -> errors.put(error.getField(), error.getDefaultMessage()));return new ApiError(HttpStatus.BAD_REQUEST.value(),"Validation failed",errors);}/*** 处理认证和授权异常*/@ExceptionHandler({AccessDeniedException.class, AuthenticationException.class})@ResponseStatus(HttpStatus.FORBIDDEN)public ApiError handleSecurityExceptions(Exception ex) {return new ApiError(HttpStatus.FORBIDDEN.value(),"Access denied: " + ex.getMessage());}/*** 处理业务逻辑异常*/@ExceptionHandler(BusinessException.class)@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)public ApiError handleBusinessExceptions(BusinessException ex) {return new ApiError(HttpStatus.UNPROCESSABLE_ENTITY.value(),ex.getMessage());}
}/*** 扩展版API错误响应,支持字段错误*/
class ApiError {private int status;private String message;private Map<String, String> fieldErrors;private LocalDateTime timestamp = LocalDateTime.now();public ApiError(int status, String message) {this.status = status;this.message = message;}public ApiError(int status, String message, Map<String, String> fieldErrors) {this.status = status;this.message = message;this.fieldErrors = fieldErrors;}// Getters and Setters// ...
}

六、控制器测试策略

测试是确保控制器质量的关键环节。Spring提供了强大的测试框架,支持控制器的单元测试和集成测试。对于单元测试,可以使用MockMvc模拟HTTP请求和响应,验证控制器行为,无需启动完整的应用服务器。对于集成测试,Spring Boot提供了@SpringBootTest注解,支持启动实际的应用上下文,进行端到端测试。良好的测试策略应该覆盖正常流程和异常场景,验证请求映射、参数绑定、业务逻辑处理和响应生成等各个环节。通过自动化测试,可以提前发现潜在问题,保障应用质量,减少生产环境故障。

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import com.fasterxml.jackson.databind.ObjectMapper;import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;/*** 控制器单元测试示例* 使用@WebMvcTest只加载Web层组件*/
@ExtendWith(SpringExtension.class)
@WebMvcTest(ProductController.class)
public class ProductControllerTest {@Autowiredprivate MockMvc mockMvc;@Autowiredprivate ObjectMapper objectMapper;@MockBeanprivate ProductService productService;/*** 测试获取产品列表*/@Testpublic void testGetAllProducts() throws Exception {// 准备测试数据List<Product> products = Arrays.asList(new Product(1L, "Product 1", 100.0),new Product(2L, "Product 2", 200.0));// 配置Mock行为when(productService.findAll()).thenReturn(products);// 执行测试并验证结果mockMvc.perform(get("/api/products").accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andExpect(jsonPath("$", hasSize(2))).andExpect(jsonPath("$[0].id").value(1)).andExpect(jsonPath("$[0].name").value("Product 1")).andExpect(jsonPath("$[1].id").value(2)).andExpect(jsonPath("$[1].name").value("Product 2"));// 验证服务方法被调用verify(productService, times(1)).findAll();}/*** 测试创建产品*/@Testpublic void testCreateProduct() throws Exception {// 准备测试数据Product newProduct = new Product(null, "New Product", 150.0);Product savedProduct = new Product(3L, "New Product", 150.0);// 配置Mock行为when(productService.create(any(Product.class))).thenReturn(savedProduct);// 执行测试并验证结果mockMvc.perform(post("/api/products").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(newProduct))).andExpect(status().isCreated()).andExpect(jsonPath("$.id").value(3)).andExpect(jsonPath("$.name").value("New Product")).andExpect(jsonPath("$.price").value(150.0));// 验证服务方法被调用verify(productService, times(1)).create(any(Product.class));}/*** 测试参数验证失败的情况*/@Testpublic void testCreateProductValidationFailure() throws Exception {// 准备无效的测试数据(空名称)Product invalidProduct = new Product(null, "", -10.0);// 执行测试并验证结果mockMvc.perform(post("/api/products").contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(invalidProduct))).andExpect(status().isBadRequest()).andExpect(jsonPath("$.fieldErrors.name").exists()).andExpect(jsonPath("$.fieldErrors.price").exists());// 验证服务方法未被调用verify(productService, never()).create(any(Product.class));}/*** 测试处理异常的情况*/@Testpublic void testHandleNotFoundException() throws Exception {// 配置Mock行为抛出异常when(productService.findById(99L)).thenThrow(new ResourceNotFoundException("Product not found"));// 执行测试并验证结果mockMvc.perform(get("/api/products/99").accept(MediaType.APPLICATION_JSON)).andExpect(status().isNotFound()).andExpect(jsonPath("$.status").value(404)).andExpect(jsonPath("$.message").value("Product not found"));}
}/*** 使用Spring Boot的集成测试示例*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ProductApiIntegrationTest {@Autowiredprivate TestRestTemplate restTemplate;@Autowiredprivate ProductRepository productRepository;@BeforeEachpublic void setup() {// 清空数据库并插入测试数据productRepository.deleteAll();productRepository.save(new Product(null, "Test Product", 99.99));}/*** 端到端测试产品API*/@Testpublic void testProductApiEndToEnd() {// 获取所有产品ResponseEntity<Product[]> getResponse = restTemplate.getForEntity("/api/products", Product[].class);assertThat(getResponse.getStatusCode()).isEqualTo(HttpStatus.OK);assertThat(getResponse.getBody().length).isEqualTo(1);// 创建新产品Product newProduct = new Product(null, "New Product", 123.45);ResponseEntity<Product> createResponse = restTemplate.postForEntity("/api/products", newProduct, Product.class);assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.CREATED);assertThat(createResponse.getBody().getId()).isNotNull();// 获取特定产品Long newId = createResponse.getBody().getId();ResponseEntity<Product> getOneResponse = restTemplate.getForEntity("/api/products/" + newId, Product.class);assertThat(getOneResponse.getStatusCode()).isEqualTo(HttpStatus.OK);assertThat(getOneResponse.getBody().getName()).isEqualTo("New Product");// 删除产品restTemplate.delete("/api/products/" + newId);// 验证删除成功ResponseEntity<Product> getDeletedResponse = restTemplate.getForEntity("/api/products/" + newId, Product.class);assertThat(getDeletedResponse.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);}
}

总结

@Controller注解是SpringMVC框架的核心组件之一,它为Java Web开发提供了强大而灵活的控制器定义机制。本文全面剖析了@Controller及其相关注解的使用方法与工作原理,从基础的请求映射到高级的RESTful API开发,从参数绑定与数据校验到全局控制器建议,系统性地展示了SpringMVC控制器的丰富功能。通过合理使用这些注解,开发者可以构建出结构清晰、功能完善的Web应用,有效处理各种复杂的HTTP请求与响应。值得注意的是,良好的控制器设计应遵循单一职责原则,保持代码的简洁性和可测试性,同时结合SpringMVC提供的测试工具,确保控制器的质量和稳定性。随着微服务架构的流行,@RestController在API开发中的重要性日益凸显,掌握这些注解的精髓对于现代Java开发者而言至关重要。通过深入理解SpringMVC控制器的定义方式,开发者能够更加高效地构建企业级Web应用,为用户提供稳定可靠的服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/28480.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自然语言处理:文本分类

介绍 大家好&#xff0c;我这个热衷于分享知识的博主又来啦&#xff01;之前我们一起深入探讨了自然语言处理领域中非常重要的两个方法&#xff1a;朴素贝叶斯和逻辑斯谛回归。在探索的过程中&#xff0c;我们剖析了朴素贝叶斯如何基于概率原理和特征条件独立假设&#xff0c;…

鸿蒙通过用户首选项实现数据持久化

鸿蒙通过用户首选项实现数据持久化 1.1 场景介绍 用户首选项为应用提供Key-Value键值型的数据处理能力&#xff0c;支持应用持久化轻量级数据&#xff0c;并对其修改和查询。当用户希望有一个全局唯一存储的地方&#xff0c;可以采用用户首选项来进行存储。Preferences会将该…

单元测试-pytest框架实践

文章目录 1. 单元测试用例目录2. 自动化测试用例编写步骤3. 命名规则4. 环境安装5. pytest语法5.1 unittest与pytest对比5.2 pytest运行插件5.3 fixture5.4 装饰器 6. pytest.ini7. conftest.py8. 用例编写步骤8.1 按照以下方式检查用例 9. 单元测试示例10. 运行11. 覆盖率12. …

嵌入式 ARM Linux 系统构成(1):Bootloader层

目录 一、Bootloader 概述 1.1 核心作用 1.2 典型启动流程 二、ARM Bootloader 架构详解 2.1 多阶段启动设计 2.2 关键代码流程 2.3. Bootloader的加载过程 2.4. Bootloader的加载方式 2.5. Bootloader 的移植 三、常见的Bootloader介绍 3.1. U-Boot 3.2. vivi …

Ubuntu20.04双系统安装及软件安装(九):谷歌浏览器

Ubuntu20.04双系统安装及软件安装&#xff08;九&#xff09;&#xff1a;谷歌浏览器 打开终端&#xff0c;下载谷歌浏览器软件包&#xff1a; wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb下载完成后直接在原终端执行&#xff1a; sudo…

【五.LangChain技术与应用】【10.LangChain ChatPromptTemplate(下):复杂场景下的应用】

凌晨两点的西二旗,你盯着监控大屏上跳动的错误日志,智能客服系统在流量洪峰中像纸船一样摇晃。用户骂声塞满弹窗:“等了十分钟就这?”“刚才说的怎么不认了?”“我要人工!!”——这时候你需要的不只是ChatPromptTemplate,而是给对话系统装上航天级操控台。 一、模板组…

Django项目实战

1、安装django 查看包安装的位置 pip镜像源 镜像源名称镜像地址​清华源​https://pypi.tuna.tsinghua.edu.cn/simple​阿里云​https://mirrors.aliyun.com/pypi/simple​腾讯云​https://mirrors.cloud.tencent.com/pypi/simple​华为云​https://repo.huaweicloud.co…

【YOLO V5】目标检测 WSL2 AutoDL VScode SSH

【YOLO V5】目标检测 WSL2 AutoDL VScode SSH 前言整体思路理解向YOLO 目标检测完整流程 环境配置Anaconda 获取 YOLO 代码与预训练模型下载 YOLOv5 代码和预训练模型配置 YOLOV5 工程环境解压 YOLOv5 源代码 并 添加预训练模型调整依赖版本选择对应的 Python 解释器 数据集准备…

PMP项目管理—沟通管理篇—1.规划沟通管理

文章目录 基本信息步骤4W1HITTO输入工具与技术输出 沟通需求分析沟通技术沟通模型沟通噪声障碍的类型 沟通漏斗模型 沟通方法相关方参与度评估矩阵传递方式影响沟通效果沟通管理计划 基本信息 步骤 收集信息&#xff0c;加工信息确定项目沟通需求确定项目沟通的方法编制项目沟…

SCI期刊推荐 | 免版面费 | 计算机领域:信息系统、软件工程、自动化和控制

在学术研究领域&#xff0c;选择合适的SCI期刊对科研成果的传播与认可至关重要。了解SCI期刊的研究领域和方向是基础&#xff0c;确保投稿内容与期刊主题相符。同时&#xff0c;要关注期刊的影响因子和评估标准&#xff0c;选择具有较高影响力和学术认可度的期刊。阅读期刊的投…

EasyDSS视频推拉流系统:清理缓存文件时如何确保缓存读写不受影响?

视频推拉流EasyDSS视频直播点播平台可提供一站式的视频转码、点播、直播、视频推拉流、播放H.265视频等服务&#xff0c;搭配RTMP高清摄像头使用&#xff0c;可将无人机设备的实时流推送到平台上&#xff0c;实现无人机视频推流直播、巡检等应用。 有用户咨询&#xff0c;视频推…

探秘基带算法:从原理到5G时代的通信变革【四】Polar 编解码(二)

文章目录 2.3.3 极化编码巴氏参数与信道可靠性比特混合生成矩阵编码举例 2.3.4 极化译码最小单元译码串行抵消译码&#xff08;SC译码&#xff09;算法SCL译码算法 2.3.5 总结**Polar 码的优势****Polar 码的主要问题****Polar 码的应用前景** 2.3.6 **参考文档** 本博客为系列…

GCC RISCV 后端 -- cc1 入口

GCC编译工具链中的 gcc 可执行程序&#xff0c;实际上是个驱动程序&#xff08;Driver&#xff09;&#xff0c;其根据输入的参数&#xff0c;然后调用其它不同的程序&#xff0c;对输入文件进行处理&#xff0c;包括编译、链接等。可以通过以下命令查看&#xff1a; gcc -v h…

用DeepSeek-R1-Distill-data-110k蒸馏中文数据集 微调Qwen2.5-7B-Instruct!

下载模型与数据 模型下载&#xff1a; huggingface&#xff1a; Qwen/Qwen2.5-7B-Instruct HF MirrorWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct 魔搭&a…

基于编译器特性浅析C++程序性能优化

最近在恶补计算机基础知识&#xff0c;学到CSAPP第五章的内容&#xff0c;在这里总结并且展开一下C程序性能优化相关的内容。 衡量程序性能的方式 一般而言&#xff0c;程序的性能可以用CPE&#xff08;Cycles Per Element&#xff09;来衡量&#xff0c;其指的是处理每个元素…

K8s控制器Deployment详解

回顾 ReplicaSet 控制器,该控制器是用来维护集群中运行的 Pod 数量的&#xff0c;但是往往在实际操作的时候&#xff0c;我们反而不会去直接使用 RS&#xff0c;而是会使用更上层的控制器&#xff0c;比如说 Deployment。 Deployment 一个非常重要的功能就是实现了 Pod 的滚动…

大模型巅峰对决:DeepSeek vs GPT-4/Claude/PaLM-2 全面对比与核心差异揭秘

文章目录 一、架构设计深度解剖1.1 核心架构对比图谱1.2 动态MoE架构实现架构差异分析表 二、训练策略全面对比2.1 训练数据工程对比2.2 分布式训练代码对比DeepSeek混合并行实现GPT-4 Megatron实现对比 2.3 关键训练参数对比 三、性能表现多维评测3.1 基准测试全景对比3.2 推理…

【MySQL_02】安装(8.4.4LTS : Windows + Linux)

文章目录 一、版本说明二、官网下载三、Windows安装3.1 安装和配置3.2 四、Linux安装 历史文章点击&#x1f449;&#xff1a;SQL &#x1f408;‍⬛github&#xff1a;https://github.com/mysql &#x1f4bb;官网&#xff1a; https://www.mysql.com &#x1f30f;维基百科…

今天来介绍和讨论 AGI(通用人工智能)

首先介绍&#xff0c;AGI&#xff08;通用人工智能&#xff09;是什么&#xff1f; AGI&#xff08;Artificial General Intelligence&#xff0c;通用人工智能&#xff09;指的是能够像人类一样理解、学习、推理和解决广泛任务的人工智能系统。与目前的AI不同&#xff0c;AGI可…

自动化学习-使用git进行版本管理

目录 一、为什么要学习git 二、git是什么 三、git如何使用 1、git的下载安装和配置 2、git常用的命令 3、gitee远程仓库的使用 &#xff08;1&#xff09;注册 &#xff08;2&#xff09;创建仓库 &#xff08;3&#xff09;配置公钥&#xff08;建立电脑和git…