SSM從入門到實戰:3.3 SpringMVC數據綁定與驗證

👋 大家好,我是 阿問學長!專注于分享優質開源項目解析、畢業設計項目指導支持、幼小初高教輔資料推薦等,歡迎關注交流!🚀

📖 本文概述

本文是SSM框架系列SpringMVC基礎篇的第三篇,將深入探討SpringMVC的數據綁定機制和數據驗證功能。通過詳細的代碼示例和最佳實踐,幫助讀者掌握數據綁定的原理和驗證框架的使用。

🎯 學習目標

  • 深入理解SpringMVC的數據綁定原理
  • 掌握各種數據類型的綁定方法
  • 學會使用Bean Validation進行數據驗證
  • 了解自定義驗證器的實現
  • 掌握數據轉換和格式化技巧

1. 數據綁定原理

1.1 數據綁定概述

SpringMVC的數據綁定是將HTTP請求參數自動轉換為Java對象的過程:

/*** 數據綁定原理演示*/
public class DataBindingPrinciple {/*** 傳統Servlet方式處理表單數據*/public void traditionalWay(HttpServletRequest request) {// 手動獲取參數String username = request.getParameter("username");String email = request.getParameter("email");String ageStr = request.getParameter("age");// 手動類型轉換Integer age = null;if (ageStr != null && !ageStr.isEmpty()) {try {age = Integer.parseInt(ageStr);} catch (NumberFormatException e) {// 處理轉換異常}}// 手動創建對象User user = new User();user.setUsername(username);user.setEmail(email);user.setAge(age);// 手動驗證if (username == null || username.trim().isEmpty()) {// 處理驗證錯誤}}/*** SpringMVC數據綁定方式*/@PostMapping("/user")public String springMvcWay(@Valid @ModelAttribute User user, BindingResult bindingResult) {// SpringMVC自動完成:// 1. 參數獲取// 2. 類型轉換// 3. 對象創建和屬性設置// 4. 數據驗證if (bindingResult.hasErrors()) {return "user/form";}// 直接使用綁定好的對象userService.save(user);return "redirect:/user/list";}
}

1.2 數據綁定流程

/*** SpringMVC數據綁定流程詳解*/
public class DataBindingFlow {/*** 數據綁定的完整流程*/public void bindingProcess() {/** 1. 請求參數解析* HTTP請求: POST /user* Content-Type: application/x-www-form-urlencoded* Body: username=john&email=john@example.com&age=25&birthday=2023-01-01*//** 2. 參數名稱解析* SpringMVC解析出參數名稱:* - username* - email  * - age* - birthday*//** 3. 目標對象創建* 根據方法參數類型創建User對象實例*//** 4. 屬性路徑解析* 將參數名稱映射到對象屬性路徑:* - username -> user.username* - email -> user.email* - age -> user.age* - birthday -> user.birthday*//** 5. 類型轉換* 將字符串參數轉換為目標類型:* - "john" -> String (無需轉換)* - "25" -> Integer* - "2023-01-01" -> Date*//** 6. 屬性設置* 調用setter方法設置屬性值:* - user.setUsername("john")* - user.setEmail("john@example.com")* - user.setAge(25)* - user.setBirthday(Date對象)*//** 7. 數據驗證* 如果有@Valid注解,執行Bean Validation*//** 8. 綁定結果* 將綁定過程中的錯誤信息存儲到BindingResult中*/}
}

2. 基本數據類型綁定

2.1 簡單類型綁定

/*** 簡單數據類型綁定演示*/
@Controller
@RequestMapping("/binding")
public class SimpleTypeBindingController {/*** 基本數據類型綁定*/@GetMapping("/simple")public String simpleTypes(String name,                    // 字符串類型int age,                       // 基本類型intInteger score,                 // 包裝類型Integerboolean active,                // 布爾類型Boolean enabled,               // 包裝類型Booleandouble salary,                 // 雙精度浮點BigDecimal amount,             // 大數值類型Model model) {model.addAttribute("name", name);model.addAttribute("age", age);model.addAttribute("score", score);model.addAttribute("active", active);model.addAttribute("enabled", enabled);model.addAttribute("salary", salary);model.addAttribute("amount", amount);return "binding/simple";}/*** 數組類型綁定*/@GetMapping("/array")public String arrayTypes(String[] names,                // 字符串數組int[] scores,                  // 基本類型數組Integer[] ages,                // 包裝類型數組Model model) {model.addAttribute("names", names);model.addAttribute("scores", scores);model.addAttribute("ages", ages);return "binding/array";}/*** 集合類型綁定*/@GetMapping("/collection")public String collectionTypes(@RequestParam List<String> hobbies,        // List集合@RequestParam Set<String> skills,          // Set集合@RequestParam Map<String, String> params,  // Map集合Model model) {model.addAttribute("hobbies", hobbies);model.addAttribute("skills", skills);model.addAttribute("params", params);return "binding/collection";}
}

2.2 日期時間類型綁定

/*** 日期時間類型綁定演示*/
@Controller
@RequestMapping("/date")
public class DateTimeBindingController {/*** 全局日期格式配置*/@InitBinderpublic void initBinder(WebDataBinder binder) {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");dateFormat.setLenient(false);binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));// 時間戳格式SimpleDateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");timestampFormat.setLenient(false);binder.registerCustomEditor(Date.class, "createTime", new CustomDateEditor(timestampFormat, false));}/*** 日期類型綁定*/@PostMapping("/submit")public String dateBinding(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday,           // 使用注解格式化@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date createTime, // 時間戳格式@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate localDate, // ISO日期格式@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime localDateTime, // ISO時間格式Model model) {model.addAttribute("birthday", birthday);model.addAttribute("createTime", createTime);model.addAttribute("localDate", localDate);model.addAttribute("localDateTime", localDateTime);return "date/result";}/*** 自定義日期轉換器*/@Componentpublic static class StringToDateConverter implements Converter<String, Date> {private static final String[] DATE_PATTERNS = {"yyyy-MM-dd","yyyy/MM/dd","yyyy-MM-dd HH:mm:ss","yyyy/MM/dd HH:mm:ss"};@Overridepublic Date convert(String source) {if (source == null || source.trim().isEmpty()) {return null;}for (String pattern : DATE_PATTERNS) {try {SimpleDateFormat format = new SimpleDateFormat(pattern);format.setLenient(false);return format.parse(source.trim());} catch (ParseException e) {// 嘗試下一個格式}}throw new IllegalArgumentException("無法解析日期: " + source);}}
}

3. 復雜對象綁定

3.1 嵌套對象綁定

/*** 復雜對象綁定演示*/
@Controller
@RequestMapping("/complex")
public class ComplexObjectBindingController {/*** 嵌套對象綁定*/@PostMapping("/nested")public String nestedObjectBinding(@ModelAttribute UserForm userForm, BindingResult bindingResult,Model model) {/** 請求參數示例:* username=john* email=john@example.com* profile.realName=John Doe* profile.phone=1234567890* profile.address.province=Beijing* profile.address.city=Beijing* profile.address.street=Chaoyang Road*/if (bindingResult.hasErrors()) {model.addAttribute("errors", bindingResult.getAllErrors());return "complex/form";}model.addAttribute("userForm", userForm);return "complex/result";}/*** 集合對象綁定*/@PostMapping("/list")public String listObjectBinding(@ModelAttribute UserListForm form,BindingResult bindingResult,Model model) {/** 請求參數示例:* users[0].username=user1* users[0].email=user1@example.com* users[0].age=25* users[1].username=user2* users[1].email=user2@example.com* users[1].age=30*/if (bindingResult.hasErrors()) {return "complex/list-form";}model.addAttribute("form", form);return "complex/list-result";}/*** Map對象綁定*/@PostMapping("/map")public String mapObjectBinding(@ModelAttribute UserMapForm form,Model model) {/** 請求參數示例:* userMap['admin'].username=admin* userMap['admin'].email=admin@example.com* userMap['user'].username=user* userMap['user'].email=user@example.com*/model.addAttribute("form", form);return "complex/map-result";}
}/*** 表單對象定義*/
public class UserForm {private String username;private String email;private UserProfile profile;// getter/setter...
}public class UserProfile {private String realName;private String phone;private Address address;// getter/setter...
}public class Address {private String province;private String city;private String street;// getter/setter...
}public class UserListForm {private List<User> users = new ArrayList<>();// getter/setter...
}public class UserMapForm {private Map<String, User> userMap = new HashMap<>();// getter/setter...
}

4. 數據驗證

4.1 Bean Validation基礎

/*** Bean Validation基礎驗證*/
public class User {@NotNull(message = "用戶ID不能為空")private Long id;@NotBlank(message = "用戶名不能為空")@Size(min = 3, max = 20, message = "用戶名長度必須在3-20個字符之間")@Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "用戶名只能包含字母、數字和下劃線")private String username;@NotBlank(message = "郵箱不能為空")@Email(message = "郵箱格式不正確")private String email;@NotBlank(message = "密碼不能為空")@Size(min = 6, max = 20, message = "密碼長度必須在6-20個字符之間")private String password;@Min(value = 18, message = "年齡不能小于18歲")@Max(value = 100, message = "年齡不能大于100歲")private Integer age;@DecimalMin(value = "0.0", message = "工資不能為負數")@DecimalMax(value = "999999.99", message = "工資不能超過999999.99")@Digits(integer = 6, fraction = 2, message = "工資格式不正確")private BigDecimal salary;@Past(message = "生日必須是過去的日期")@DateTimeFormat(pattern = "yyyy-MM-dd")private Date birthday;@Future(message = "過期時間必須是將來的日期")private Date expireTime;@AssertTrue(message = "必須同意用戶協議")private Boolean agreeTerms;@Valid // 級聯驗證private UserProfile profile;@Valid@Size(min = 1, message = "至少需要一個角色")private List<Role> roles;// getter/setter...
}/*** 用戶資料驗證*/
public class UserProfile {@NotBlank(message = "真實姓名不能為空")@Size(max = 50, message = "真實姓名長度不能超過50個字符")private String realName;@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手機號格式不正確")private String phone;@URL(message = "頭像URL格式不正確")private String avatar;@Validprivate Address address;// getter/setter...
}

4.2 分組驗證

/*** 分組驗證演示*/
public class User {// 驗證分組接口public interface Create {}public interface Update {}public interface Delete {}@NotNull(groups = {Update.class, Delete.class}, message = "更新和刪除時ID不能為空")private Long id;@NotBlank(groups = {Create.class, Update.class}, message = "用戶名不能為空")@Size(min = 3, max = 20, groups = {Create.class, Update.class}, message = "用戶名長度必須在3-20個字符之間")private String username;@NotBlank(groups = Create.class, message = "創建用戶時密碼不能為空")@Size(min = 6, max = 20, groups = Create.class, message = "密碼長度必須在6-20個字符之間")private String password;@Email(groups = {Create.class, Update.class}, message = "郵箱格式不正確")private String email;// getter/setter...
}/*** 控制器中使用分組驗證*/
@Controller
@RequestMapping("/user")
public class UserValidationController {/*** 創建用戶 - 使用Create分組*/@PostMapping("/create")public String createUser(@Validated(User.Create.class) @ModelAttribute User user,BindingResult bindingResult,Model model) {if (bindingResult.hasErrors()) {model.addAttribute("errors", bindingResult.getAllErrors());return "user/create";}userService.save(user);return "redirect:/user/list";}/*** 更新用戶 - 使用Update分組*/@PostMapping("/update")public String updateUser(@Validated(User.Update.class) @ModelAttribute User user,BindingResult bindingResult,Model model) {if (bindingResult.hasErrors()) {model.addAttribute("errors", bindingResult.getAllErrors());return "user/edit";}userService.update(user);return "redirect:/user/list";}/*** 刪除用戶 - 使用Delete分組*/@PostMapping("/delete")public String deleteUser(@Validated(User.Delete.class) @ModelAttribute User user,BindingResult bindingResult,RedirectAttributes redirectAttributes) {if (bindingResult.hasErrors()) {redirectAttributes.addFlashAttribute("error", "刪除失敗:參數錯誤");return "redirect:/user/list";}userService.deleteById(user.getId());redirectAttributes.addFlashAttribute("message", "刪除成功");return "redirect:/user/list";}
}

4.3 自定義驗證器

/*** 自定義驗證注解*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueUsernameValidator.class)
@Documented
public @interface UniqueUsername {String message() default "用戶名已存在";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}/*** 自定義驗證器實現*/
@Component
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {@Autowiredprivate UserService userService;@Overridepublic void initialize(UniqueUsername constraintAnnotation) {// 初始化方法,可以獲取注解參數}@Overridepublic boolean isValid(String username, ConstraintValidatorContext context) {if (username == null || username.trim().isEmpty()) {return true; // 空值由@NotBlank驗證}// 檢查用戶名是否已存在return !userService.existsByUsername(username);}
}/*** 復雜自定義驗證注解*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordMatchValidator.class)
@Documented
public @interface PasswordMatch {String message() default "密碼和確認密碼不匹配";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};String password();String confirmPassword();
}/*** 密碼匹配驗證器*/
public class PasswordMatchValidator implements ConstraintValidator<PasswordMatch, Object> {private String passwordField;private String confirmPasswordField;@Overridepublic void initialize(PasswordMatch constraintAnnotation) {this.passwordField = constraintAnnotation.password();this.confirmPasswordField = constraintAnnotation.confirmPassword();}@Overridepublic boolean isValid(Object obj, ConstraintValidatorContext context) {try {Object password = getFieldValue(obj, passwordField);Object confirmPassword = getFieldValue(obj, confirmPasswordField);if (password == null && confirmPassword == null) {return true;}if (password != null && password.equals(confirmPassword)) {return true;}// 自定義錯誤消息context.disableDefaultConstraintViolation();context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()).addPropertyNode(confirmPasswordField).addConstraintViolation();return false;} catch (Exception e) {return false;}}private Object getFieldValue(Object obj, String fieldName) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);return field.get(obj);}
}/*** 使用自定義驗證的表單對象*/
@PasswordMatch(password = "password", confirmPassword = "confirmPassword")
public class UserRegistrationForm {@UniqueUsername@NotBlank(message = "用戶名不能為空")private String username;@NotBlank(message = "密碼不能為空")@Size(min = 6, max = 20, message = "密碼長度必須在6-20個字符之間")private String password;@NotBlank(message = "確認密碼不能為空")private String confirmPassword;@Email(message = "郵箱格式不正確")private String email;// getter/setter...
}

5. 數據轉換和格式化

5.1 類型轉換器

/*** 自定義類型轉換器*/
@Component
public class StringToUserConverter implements Converter<String, User> {@Autowiredprivate UserService userService;@Overridepublic User convert(String source) {if (source == null || source.trim().isEmpty()) {return null;}try {Long userId = Long.parseLong(source);return userService.findById(userId);} catch (NumberFormatException e) {// 嘗試按用戶名查找return userService.findByUsername(source);}}
}/*** 枚舉轉換器*/
@Component
public class StringToUserStatusConverter implements Converter<String, UserStatus> {@Overridepublic UserStatus convert(String source) {if (source == null || source.trim().isEmpty()) {return null;}try {// 嘗試按序號轉換int ordinal = Integer.parseInt(source);UserStatus[] values = UserStatus.values();if (ordinal >= 0 && ordinal < values.length) {return values[ordinal];}} catch (NumberFormatException e) {// 嘗試按名稱轉換try {return UserStatus.valueOf(source.toUpperCase());} catch (IllegalArgumentException ex) {// 忽略異常,返回null}}return null;}
}/*** 轉換器配置*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addFormatters(FormatterRegistry registry) {registry.addConverter(new StringToUserConverter());registry.addConverter(new StringToUserStatusConverter());registry.addFormatter(new DateFormatter("yyyy-MM-dd"));registry.addFormatter(new NumberStyleFormatter("#,##0.00"));}
}

5.2 格式化器

/*** 自定義格式化器*/
@Component
public class MoneyFormatter implements Formatter<BigDecimal> {@Overridepublic BigDecimal parse(String text, Locale locale) throws ParseException {if (text == null || text.trim().isEmpty()) {return null;}// 移除貨幣符號和千分位分隔符String cleanText = text.replaceAll("[¥$,]", "");try {return new BigDecimal(cleanText);} catch (NumberFormatException e) {throw new ParseException("無法解析金額: " + text, 0);}}@Overridepublic String print(BigDecimal money, Locale locale) {if (money == null) {return "";}NumberFormat formatter = NumberFormat.getCurrencyInstance(locale);return formatter.format(money);}
}/*** 使用格式化注解*/
public class Product {@NumberFormat(style = NumberFormat.Style.CURRENCY)private BigDecimal price;@NumberFormat(pattern = "#,##0.00")private BigDecimal weight;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date createDate;@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)private LocalDateTime updateTime;// getter/setter...
}

6. 錯誤處理和國際化

6.1 驗證錯誤處理

/*** 驗證錯誤處理*/
@Controller
@RequestMapping("/validation")
public class ValidationErrorController {/*** 處理驗證錯誤*/@PostMapping("/submit")public String handleValidation(@Valid @ModelAttribute UserForm userForm,BindingResult bindingResult,Model model) {if (bindingResult.hasErrors()) {// 獲取所有錯誤List<ObjectError> allErrors = bindingResult.getAllErrors();// 獲取字段錯誤List<FieldError> fieldErrors = bindingResult.getFieldErrors();// 獲取全局錯誤List<ObjectError> globalErrors = bindingResult.getGlobalErrors();// 構建錯誤信息Map<String, String> errorMap = new HashMap<>();for (FieldError error : fieldErrors) {errorMap.put(error.getField(), error.getDefaultMessage());}model.addAttribute("errors", errorMap);model.addAttribute("globalErrors", globalErrors);return "validation/form";}return "validation/success";}/*** AJAX驗證錯誤處理*/@PostMapping("/ajax-submit")@ResponseBodypublic ResponseEntity<?> handleAjaxValidation(@Valid @RequestBody UserForm userForm,BindingResult bindingResult) {if (bindingResult.hasErrors()) {Map<String, Object> response = new HashMap<>();Map<String, String> errors = new HashMap<>();for (FieldError error : bindingResult.getFieldErrors()) {errors.put(error.getField(), error.getDefaultMessage());}response.put("success", false);response.put("errors", errors);return ResponseEntity.badRequest().body(response);}// 處理成功Map<String, Object> response = new HashMap<>();response.put("success", true);response.put("message", "提交成功");return ResponseEntity.ok(response);}
}

6.2 國際化支持

# messages.properties (默認)
user.username.notblank=用戶名不能為空
user.username.size=用戶名長度必須在{min}-{max}個字符之間
user.email.email=郵箱格式不正確
user.age.min=年齡不能小于{value}歲# messages_en.properties (英文)
user.username.notblank=Username cannot be blank
user.username.size=Username length must be between {min}-{max} characters
user.email.email=Email format is incorrect
user.age.min=Age cannot be less than {value} years old# messages_zh_CN.properties (中文)
user.username.notblank=用戶名不能為空
user.username.size=用戶名長度必須在{min}-{max}個字符之間
user.email.email=郵箱格式不正確
user.age.min=年齡不能小于{value}歲
/*** 國際化配置*/
@Configuration
public class InternationalizationConfig {@Beanpublic MessageSource messageSource() {ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();messageSource.setBasename("messages");messageSource.setDefaultEncoding("UTF-8");return messageSource;}@Beanpublic LocaleResolver localeResolver() {SessionLocaleResolver resolver = new SessionLocaleResolver();resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);return resolver;}@Beanpublic LocaleChangeInterceptor localeChangeInterceptor() {LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();interceptor.setParamName("lang");return interceptor;}
}/*** 使用國際化的驗證*/
public class User {@NotBlank(message = "{user.username.notblank}")@Size(min = 3, max = 20, message = "{user.username.size}")private String username;@Email(message = "{user.email.email}")private String email;@Min(value = 18, message = "{user.age.min}")private Integer age;// getter/setter...
}

7. 小結

本文深入介紹了SpringMVC的數據綁定和驗證機制:

  1. 數據綁定原理:從HTTP參數到Java對象的自動轉換過程
  2. 基本類型綁定:簡單類型、數組、集合、日期時間的綁定
  3. 復雜對象綁定:嵌套對象、集合對象、Map對象的綁定
  4. 數據驗證:Bean Validation、分組驗證、自定義驗證器
  5. 類型轉換:自定義轉換器和格式化器
  6. 錯誤處理:驗證錯誤處理和國際化支持

掌握數據綁定和驗證的關鍵點:

  • 理解數據綁定的完整流程
  • 正確使用各種驗證注解
  • 合理設計驗證分組
  • 實現自定義驗證邏輯
  • 處理驗證錯誤和用戶體驗

🔗 下一篇預告

下一篇文章將介紹SpringMVC視圖解析與模板引擎,學習如何處理視圖渲染和模板技術的集成。


相關文章:

  • 上一篇:SpringMVC請求處理與控制器
  • 下一篇:SpringMVC視圖解析與模板引擎
  • 返回目錄

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

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

相關文章

ctfshow_萌新web16-web20-----文件包含日志注入

_萌新web16解開md5?c36d_萌新web17-----文件包含禁用了php關鍵字&#xff0c;這個題禁了遠程文件包含,進行日志注入發現日志中有user-agent信息&#xff0c;因此我們可以在user-agent中寫入木馬抓包burpsuitUser-agent:<?php eval($_POST[cmd])?>抓包然后連接蟻劍_萌新…

Flink的CheckPoint與SavePoint

Flink的Checkpoint&#xff08;檢查點&#xff09;和Savepoint&#xff08;保存點&#xff09;是兩種不同的狀態快照機制&#xff0c;主要區別如下&#xff1a;1. ?Checkpoint??核心功能?&#xff1a;周期性觸發的容錯機制&#xff0c;用于故障恢復時保證狀態一致性57。?觸…

Ansible 自動化運維工具:介紹與完整部署(RHEL 9)

Ansible 自動化運維工具&#xff1a;介紹與完整部署&#xff08;RHEL 9&#xff09;Ansible 的介紹與安裝 一、自動化運維的必要性 傳統手動運維依賴圖形/命令行界面、檢查清單或記憶執行任務&#xff0c;存在以下核心問題&#xff1a; 易出錯&#xff1a;易跳過步驟或執行錯誤…

構建生產級 RAG 系統:從數據處理到智能體(Agent)的全流程深度解析

文章目錄一、 整體架構設計&#xff1a;邁向智能體&#xff08;Agent&#xff09;驅動的 RAG二、 數據準備與預處理&#xff1a;構建高質量知識庫2.1 數據加載與初步提取2.2 多策略分塊 (Multi-Strategy Chunking)邏輯分塊&#xff1a;按故障章節和關鍵說明傳統分塊&#xff1a…

Duplicate Same Files Searcher v10.7.0,秒掃全盤重復檔,符號鏈接一鍵瘦身

[軟件名稱]: Duplicate Same Files Searcher v10.7.0 [軟件大小]: 3.3 MB [軟件大小]: 夸克網盤 | 百度網盤 軟件介紹 Duplicate Same Files Searcher&#xff08;重復文件搜索&#xff09;是一款強大且專業的重復文件查找與清理工具。通過使用該軟件&#xff0c;用戶可以方…

C/C++ 數據結構 —— 樹(2)

? &#x1f381;個人主頁&#xff1a;工藤新一 ? &#x1f50d;系列專欄&#xff1a;C面向對象&#xff08;類和對象篇&#xff09; ? &#x1f31f;心中的天空之城&#xff0c;終會照亮我前方的路 ? &#x1f389;歡迎大家點贊&#x1f44d;評論&#x1f4dd;收藏?文章…

EEA架構介紹

前言 本文主要對EEA架構的理解進行了記錄&#xff0c;以加深理解及方便后續查漏補缺。 EEA架構 硬件架構 EEA架構作用 提升算力利用率、數據統一交互&#xff0c;實現整車功能協同、縮短線束、降低重量、降低故障率、提升裝配自動化 EEA架構發展趨勢 分布式–>域集中式–>…

【目標跟蹤】《FastTracker: Real-Time and Accurate Visual Tracking》論文閱讀筆記

0.參考 論文:https://arxiv.org/pdf/2508.14370v1 代碼:github.com/HamidrezaHashempoor/FastTracker, huggingface.co/datasets/HamidrezaHashemp/FastTracker-Benchmark. 1.摘要 提高多目標跟蹤在多物體跟蹤上的性能(從前主要是針對行人場景做的優化)。 該方法包含兩…

C++ 內存安全與智能指針深度解析

C 內存安全與智能指針深度解析面試官考察“野指針”&#xff0c;實際上是在考察你對 C “資源所有權” (Ownership) 和 “生命周期管理” (Lifetime Management) 的理解。現代 C 的答案不是“如何手動避免”&#xff0c;而是“如何自動化管理”。第一部分&#xff1a;核心知識點…

Vue SFC Playground 如何正確引入 naive-ui

網羅開發&#xff08;小紅書、快手、視頻號同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企業從事人工智能項目研發管理工作&#xff0c;平時熱衷于分享各種編程領域的軟硬技能知識以及前沿技術&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

音頻轉文本技術詳解:API接口、實用示例與最佳實踐

音頻轉文本技術詳解&#xff1a;API接口、實用示例與最佳實踐 目錄 概述接口類型與模型說明支持的音頻格式與文件大小限制快速入門音頻轉錄&#xff08;Transcription&#xff09;音頻翻譯&#xff08;Translation&#xff09;支持的語言列表時間戳功能處理較長音頻上下文提示…

QT-布局管理器

Qt布局管理器 一、布局管理器介紹布局管理器&#xff08;Layout Manager&#xff09;是在圖形用戶界面&#xff08;GUI&#xff09;應用程序中用于自動管理和排列窗口部件&#xff08;Widget&#xff09;的工具。Qt 共提供了 5 種布局管理器&#xff0c;來幫助開發者方便地組織…

Linux CentOS 安裝 .net core 3.1

打開終端&#xff0c;輸入以下命令以添加 .NET Core Yum 倉庫&#xff1a;sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm安裝 .NET Core SDK&#xff1a;sudo yum install dotnet-sdk-3.1驗證安裝&#xff1a;dotnet --versionre…

深度剖析Spring AI源碼(三):ChatClient詳解,優雅的流式API設計

深度剖析Spring AI源碼&#xff08;三&#xff09;&#xff1a;ChatClient詳解&#xff0c;優雅的流式API設計“The best APIs are those that make simple things simple and complex things possible.” —— Alan Kay (計算機科學巨匠) Spring AI的ChatClient API正是這句話…

C語言基礎:(二十五)預處理詳解

目錄 前言 一、預處理符號 二、#define 定義常量 三、#define 定義宏 四、帶有副作用的宏參數 五、宏替換的規則 六、宏函數對比 七、# 和 ## 7.1 #運算符 7.2 ##運算符 八、命名約定 九、#undef 十、命令行定義 十一、條件編譯 十二、頭文件的包含 12.1 頭…

本地文件夾即時變身 Web 服務器(文件服務器)

一&#xff1a;http-server npm install --global http-server 使用&#xff0c;在一個目錄下打開 cmd http-server [path] [options] [path] defaults to ./public if the folder exists, and ./ otherwise. 可以下載文件&#xff0c;但是不能下載文件夾。 二&#xff1a;…

Golang云端編程入門指南:前沿框架與技術全景解析

Golang云端編程入門指南&#xff1a;前沿框架與技術全景解析 1 引言&#xff1a;Go語言在云原生時代的優勢 Go語言&#xff08;Golang&#xff09;由Google開發&#xff0c;憑借其簡潔的語法、卓越的并發性能和高效的編譯速度&#xff0c;已成為云端應用開發的首選語言之一。…

藍凌EKP產品:從 XML 到 JSON ——表單存儲的性能優化實踐

1. 背景介紹藍凌 EKP 的表單引擎&#xff0c;是整個低代碼平臺的核心能力之一。它不僅僅是“存儲表單”&#xff0c;更是 企業級應用快速構建的基礎設施。它支持各種復雜表單配置&#xff08;字段、布局、校驗、權限、聯動、子表單&#xff09;。它能靈活綁定流程&#xff0c;實…

STM32高級定時器-輸出比較模式

一.輸出比較原理1.輸出比較 通過定時器的外部引腳對外輸出控制信號&#xff0c;將通道X(x1,2,3,4)通常設置為PWM1、PWM2模式。 2.比較寄存器 當計數器CNT和比較寄存器CCR的值相等時&#xff0c;輸出參考信號OCxREF的信號的極性發生改變&#xff0c;其中OCxREF1(高電平)稱為有效…

深入理解Unity中的`.meta`文件:以紋理文件為例

在Unity開發中&#xff0c;.meta文件是一個經常被提及但又容易被忽視的組成部分。這些隱藏的元數據文件在項目的穩定性和一致性中扮演著重要角色&#xff0c;尤其是在處理紋理文件時。本文將深入探討.meta文件的作用、內容、版本控制以及常見問題&#xff0c;幫助開發者更好地理…