最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot控制層參數(shù)綁定@RequestPart 注解的使用

 更新時間:2026年02月10日 14:32:25   作者:BillKu  
@RequestPart是一個非常重要但常被忽略的注解,專門用于處理multipart/form-data請求中的復雜數(shù)據(jù)類型,下面給大家介紹Spring Boot控制層參數(shù)綁定@RequestPart 注解的使用,感興趣的朋友跟隨小編一起看看吧

@RequestPart 注解詳解

@RequestPart 是一個非常重要但常被忽略的注解,專門用于處理 multipart/form-data 請求中的復雜數(shù)據(jù)類型。下面詳細講解這個特殊的注解。

一、@RequestPart 基礎概念

1.1與 @RequestParam 的核心區(qū)別

特性@RequestPart@RequestParam
數(shù)據(jù)格式支持任何內(nèi)容類型只支持 application/x-www-form-urlencoded
內(nèi)容類型每個部分有獨立的 Content-Type整個請求統(tǒng)一的 Content-Type
數(shù)據(jù)處理使用 HttpMessageConverter使用 Servlet API 的參數(shù)解析
文件處理天然支持,并支持其他類型只支持文件(作為 MultipartFile)
JSON 綁定直接綁定到對象不支持

1.2主要應用場景

  • 上傳文件的同時發(fā)送 JSON 數(shù)據(jù)
  • 單個請求中混合不同類型的數(shù)據(jù)
  • REST API 中的文件上傳

二、@RequestPart 詳細用法

2.1基本文件上傳

@RestController
@RequestMapping("/api/upload")
public class UploadController {
    // 基礎用法 - 上傳單個文件
    @PostMapping("/single")
    public String uploadSingle(@RequestPart("file") MultipartFile file) {
        // 這里使用 @RequestPart 或 @RequestParam 都可以
        return "Uploaded: " + file.getOriginalFilename();
    }
    // 上傳多個文件
    @PostMapping("/multiple")
    public String uploadMultiple(@RequestPart("files") MultipartFile[] files) {
        return "Uploaded " + files.length + " files";
    }
    // 使用 List 接收文件
    @PostMapping("/list")
    public String uploadList(@RequestPart("files") List<MultipartFile> files) {
        return "Uploaded " + files.size() + " files";
    }
}

2.2文件 + 普通參數(shù)(@RequestPart 的優(yōu)勢)

@RestController
@RequestMapping("/api/advanced")
public class AdvancedUploadController {
    // 2.2.1 文件 + 字符串參數(shù)
    @PostMapping(value = "/with-text", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadWithText(
            @RequestPart("file") MultipartFile file,
            @RequestPart("description") String description) {
        return String.format("File: %s, Description: %s", 
            file.getOriginalFilename(), description);
    }
    // 2.2.2 文件 + JSON 對象(@RequestPart 的獨特優(yōu)勢)
    @PostMapping(value = "/with-json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadWithJson(
            @RequestPart("file") MultipartFile file,
            @RequestPart("metadata") FileMetadata metadata) {  // 自動將JSON轉(zhuǎn)換為對象
        return String.format("File: %s, Metadata: %s", 
            file.getOriginalFilename(), metadata.toString());
    }
    // 2.2.3 多個不同類型的部分
    @PostMapping(value = "/complex", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Map<String, Object> complexUpload(
            @RequestPart("profileImage") MultipartFile image,
            @RequestPart("profileData") UserProfile profile,
            @RequestPart("settings") String settingsJson,
            @RequestPart("documents") MultipartFile[] documents) {
        Map<String, Object> result = new HashMap<>();
        result.put("image", image.getOriginalFilename());
        result.put("profile", profile);
        result.put("settings", settingsJson);
        result.put("documentCount", documents.length);
        return result;
    }
}
// 元數(shù)據(jù)類
public class FileMetadata {
    private String title;
    private String category;
    private List<String> tags;
    private boolean isPublic;
    // getters/setters
}
// 用戶資料類
public class UserProfile {
    private String username;
    private String bio;
    private LocalDate birthDate;
    // getters/setters
}

2.3使用 @RequestPart 綁定到 Map 和 List

@RestController
@RequestMapping("/api/flexible")
public class FlexibleUploadController {
    // 3.1 綁定到 Map(接收 JSON 對象)
    @PostMapping(value = "/map", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadWithMap(
            @RequestPart("file") MultipartFile file,
            @RequestPart("attributes") Map<String, Object> attributes) {
        attributes.put("filename", file.getOriginalFilename());
        attributes.put("size", file.getSize());
        return "Processed with " + attributes.size() + " attributes";
    }
    // 3.2 綁定到 List(接收 JSON 數(shù)組)
    @PostMapping(value = "/list-json", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadWithJsonList(
            @RequestPart("files") MultipartFile[] files,
            @RequestPart("tags") List<String> tags) {  // tags 部分是 JSON 數(shù)組
        return String.format("Files: %d, Tags: %s", files.length, tags);
    }
    // 3.3 復雜的嵌套 JSON
    @PostMapping(value = "/nested", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadWithNestedJson(
            @RequestPart("document") MultipartFile document,
            @RequestPart("config") Map<String, Object> config) {
        // config 可以是復雜的嵌套 JSON
        return "Config: " + config;
    }
}

三、@RequestPart 的高級特性

3.1驗證 @RequestPart 參數(shù)

@RestController
@RequestMapping("/api/validated")
public class ValidatedUploadController {
    // 4.1 對 JSON 部分進行驗證
    @PostMapping(value = "/validated", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<?> uploadValidated(
            @RequestPart("file") MultipartFile file,
            @Valid @RequestPart("metadata") FileMetadata metadata,
            BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseEntity.badRequest()
                    .body(bindingResult.getAllErrors());
        }
        if (file.isEmpty()) {
            return ResponseEntity.badRequest()
                    .body("File cannot be empty");
        }
        return ResponseEntity.ok("Upload successful");
    }
    // 4.2 分組驗證
    @PostMapping(value = "/group-validated", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadGroupValidated(
            @RequestPart("file") MultipartFile file,
            @Validated(FileMetadata.CreateGroup.class) 
            @RequestPart("metadata") FileMetadata metadata) {
        return "Group validation passed";
    }
}

3.2內(nèi)容類型控制

@RestController
@RequestMapping("/api/content-type")
public class ContentTypeController {
    // 5.1 指定特定內(nèi)容類型
    @PostMapping(value = "/specific", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadSpecificType(
            @RequestPart(value = "config", consumes = "application/json") 
            AppConfig config,
            @RequestPart("file") MultipartFile file) {
        return "Config type: " + config.getClass().getSimpleName();
    }
    // 5.2 支持多種內(nèi)容類型
    @PostMapping(value = "/flexible-type", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadFlexibleType(
            @RequestPart(value = "data", consumes = {"application/json", "application/xml"}) 
            String data) {
        return "Received data: " + data.substring(0, Math.min(50, data.length()));
    }
}

3.3使用 HttpEntity

@RestController
@RequestMapping("/api/entity")
public class EntityUploadController {
    // 6.1 使用 HttpEntity 獲取完整部分信息
    @PostMapping(value = "/http-entity", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String uploadWithEntity(
            @RequestPart("file") MultipartFile file,
            @RequestPart("metadata") HttpEntity<FileMetadata> metadataEntity) {
        FileMetadata metadata = metadataEntity.getBody();
        HttpHeaders headers = metadataEntity.getHeaders();
        return String.format(
            "File: %s, Metadata: %s, Content-Type: %s",
            file.getOriginalFilename(),
            metadata.getTitle(),
            headers.getContentType()
        );
    }
    // 6.2 直接使用 RequestPart 的完整信息
    @PostMapping(value = "/full-control", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String fullControlUpload(
            @RequestPart("file") MultipartFile file,
            @RequestPart("config") RequestPartConfig configPart) {
        // 自定義處理邏輯
        return "Processed with full control";
    }
}

四、@RequestPart 與 @RequestParam 對比示例

4.1相同點和不同點演示

@RestController
@RequestMapping("/api/compare")
public class CompareController {
    // 場景1:上傳文件 - 兩者都可以
    @PostMapping(value = "/file-both", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String fileBoth(
            @RequestParam("file1") MultipartFile file1,      // 使用 @RequestParam
            @RequestPart("file2") MultipartFile file2) {     // 使用 @RequestPart
        return "Both work for files";
    }
    // 場景2:JSON數(shù)據(jù) - 只有 @RequestPart 可以
    @PostMapping(value = "/json-only", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String jsonOnly(
            // @RequestParam("data") UserData data,  // ? 這會失敗,無法直接綁定對象
            @RequestPart("data") UserData data) {    // ? 可以正確綁定
        return "Only @RequestPart works for JSON";
    }
    // 場景3:混合數(shù)據(jù) - @RequestPart 的優(yōu)勢
    @PostMapping(value = "/mixed", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String mixedUpload(
            @RequestPart("document") MultipartFile document,
            @RequestPart("metadata") DocumentMetadata metadata,
            @RequestParam("description") String description,  // 簡單字段可以用 @RequestParam
            @RequestParam("tags") String tags) {
        return String.format(
            "Document: %s, Metadata: %s, Desc: %s, Tags: %s",
            document.getOriginalFilename(),
            metadata.getTitle(),
            description,
            tags
        );
    }
}
class UserData {
    private String name;
    private int age;
    // getters/setters
}
class DocumentMetadata {
    private String title;
    private String author;
    private LocalDate createdDate;
    // getters/setters
}

4.2前端請求示例

// 使用 FormData 發(fā)送混合數(shù)據(jù)
const formData = new FormData();
// 1. 添加文件
formData.append('file', fileInput.files[0]);
// 2. 添加 JSON 數(shù)據(jù)(@RequestPart 可以處理)
const metadata = {
    title: 'My Document',
    author: 'John Doe',
    tags: ['important', 'urgent']
};
formData.append('metadata', JSON.stringify(metadata));
// 3. 添加純文本(兩者都可以處理)
formData.append('description', 'This is a document');
// 4. 發(fā)送請求
fetch('/api/compare/mixed', {
    method: 'POST',
    body: formData
    // 注意:不要手動設置 Content-Type,
    // 瀏覽器會自動設置為 multipart/form-data
});

五、實際應用場景

5.1電商商品上傳

@RestController
@RequestMapping("/api/products")
public class ProductController {
    @PostMapping(value = "/create", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<ProductResponse> createProduct(
            @Valid @RequestPart("product") ProductDTO productDTO,
            @RequestPart("mainImage") MultipartFile mainImage,
            @RequestPart(value = "galleryImages", required = false) MultipartFile[] galleryImages,
            @RequestPart(value = "specifications", required = false) String specificationsJson) {
        // 1. 保存商品基本信息(自動從JSON轉(zhuǎn)換)
        Product product = productService.create(productDTO);
        // 2. 保存主圖
        String mainImageUrl = fileService.saveImage(mainImage);
        product.setMainImageUrl(mainImageUrl);
        // 3. 保存圖庫圖片
        if (galleryImages != null) {
            List<String> galleryUrls = Arrays.stream(galleryImages)
                    .map(fileService::saveImage)
                    .collect(Collectors.toList());
            product.setGalleryImageUrls(galleryUrls);
        }
        // 4. 處理規(guī)格信息(JSON字符串)
        if (specificationsJson != null) {
            Map<String, Object> specs = objectMapper.readValue(
                specificationsJson, 
                new TypeReference<Map<String, Object>>() {}
            );
            product.setSpecifications(specs);
        }
        return ResponseEntity.ok(ProductResponse.success(product));
    }
}
// DTO類
public class ProductDTO {
    @NotBlank
    private String name;
    @NotNull
    @DecimalMin("0.01")
    private BigDecimal price;
    @Min(0)
    private Integer stock;
    private String description;
    private Long categoryId;
    // getters/setters
}

5.2用戶注冊帶頭像

@RestController
@RequestMapping("/api/users")
public class UserRegistrationController {
    @PostMapping(value = "/register", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<?> registerUser(
            @Valid @RequestPart("user") UserRegistrationRequest request,
            @RequestPart(value = "avatar", required = false) MultipartFile avatar,
            @RequestPart(value = "documents", required = false) List<MultipartFile> documents) {
        // 1. 驗證用戶名唯一性
        if (userService.existsByUsername(request.getUsername())) {
            return ResponseEntity.badRequest()
                    .body(Map.of("error", "用戶名已存在"));
        }
        // 2. 創(chuàng)建用戶
        User user = userService.createUser(request);
        // 3. 保存頭像
        if (avatar != null && !avatar.isEmpty()) {
            String avatarUrl = fileService.saveAvatar(avatar, user.getId());
            user.setAvatarUrl(avatarUrl);
        }
        // 4. 保存證件照
        if (documents != null && !documents.isEmpty()) {
            List<Document> savedDocuments = documentService.saveDocuments(
                documents, user.getId()
            );
            user.setDocuments(savedDocuments);
        }
        return ResponseEntity.ok(
            UserResponse.fromEntity(user, jwtService.generateToken(user))
        );
    }
}

5.3批量導入數(shù)據(jù)

@RestController
@RequestMapping("/api/import")
public class ImportController {
    @PostMapping(value = "/bulk", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public BulkImportResponse bulkImport(
            @RequestPart("template") MultipartFile templateFile,
            @RequestPart("config") ImportConfig config,
            @RequestPart("mapping") Map<String, String> fieldMapping,
            @RequestParam("dryRun") boolean dryRun) {
        // 1. 驗證文件類型
        if (!templateFile.getOriginalFilename().endsWith(".xlsx")) {
            throw new IllegalArgumentException("只支持 Excel 文件");
        }
        // 2. 讀取模板文件
        List<Map<String, Object>> data = excelReader.read(templateFile);
        // 3. 根據(jù)配置處理數(shù)據(jù)
        ImportResult result = importService.process(
            data, config, fieldMapping, dryRun
        );
        return BulkImportResponse.builder()
                .totalCount(result.getTotalCount())
                .successCount(result.getSuccessCount())
                .failedCount(result.getFailedCount())
                .errors(result.getErrors())
                .dryRun(dryRun)
                .build();
    }
}

六、常見問題和解決方案

6.1問題1:@RequestPart 與 @RequestParam 混淆

// ? 錯誤示例:嘗試用 @RequestParam 接收 JSON
@PostMapping(value = "/wrong", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String wrongExample(
        @RequestParam("jsonData") UserData data) {  // 這會失?。?
    return "This won't work";
}
// ? 正確示例:使用 @RequestPart
@PostMapping(value = "/correct", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String correctExample(
        @RequestPart("jsonData") UserData data) {  // 正確!
    return "This works";
}

6.2問題2:缺少 consumes 屬性

// ? 可能的問題:忘記指定 consumes
@PostMapping("/implicit")
public String implicit(
        @RequestPart("file") MultipartFile file) {
    // 這通??梢怨ぷ鳎鞔_指定更好
    return "Implicit";
}
// ? 最佳實踐:明確指定
@PostMapping(value = "/explicit", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String explicit(
        @RequestPart("file") MultipartFile file) {
    return "Explicit is better";
}

6.3問題3:前端沒有正確設置 Content-Type

@RestControllerAdvice
public class MultipartExceptionHandler {
    @ExceptionHandler(MultipartException.class)
    public ResponseEntity<?> handleMultipartException(
            MultipartException ex, HttpServletRequest request) {
        String message = "文件上傳失敗: ";
        if (ex instanceof MissingServletRequestPartException) {
            message += "缺少必要的數(shù)據(jù)部分";
        } else if (ex instanceof MaxUploadSizeExceededException) {
            message += "文件大小超過限制";
        } else {
            message += ex.getMessage();
        }
        // 檢查是否是 Content-Type 問題
        String contentType = request.getContentType();
        if (contentType == null || !contentType.contains("multipart/form-data")) {
            message += "。請使用 multipart/form-data 格式";
        }
        return ResponseEntity.badRequest()
                .body(Map.of("error", message));
    }
}

6.4配置建議

spring:
  servlet:
    multipart:
      enabled: true
      max-file-size: 10MB  # 單個文件大小限制
      max-request-size: 100MB  # 整個請求大小限制
      file-size-threshold: 2MB  # 內(nèi)存閾值,超過的會寫入磁盤
      location: ${java.io.tmpdir}  # 臨時目錄

七、總結(jié)對比表

特性@RequestPart@RequestParam (multipart時)說明
JSON綁定? 直接綁定到對象? 只能綁定到字符串@RequestPart 可以使用 HttpMessageConverter
內(nèi)容類型每個部分獨立整個請求統(tǒng)一@RequestPart 支持混合內(nèi)容類型
文件上傳? MultipartFile? MultipartFile兩者都可以
簡單字段? 字符串? 字符串兩者都可以
驗證支持? @Valid? 不支持@RequestPart 支持 Bean Validation
HttpMessageConverter? 使用? 不使用@RequestPart 可以利用 JSON 轉(zhuǎn)換器等
RequestEntity 包裝? 支持? 不支持@RequestPart 可以獲取完整的部分信息
consumes 屬性可以指定每個部分不支持@RequestPart(value="data", consumes="application/json")

八、選擇建議

使用 @RequestPart 當:

  • 需要上傳文件 并且 同時發(fā)送 JSON 數(shù)據(jù)
  • 請求中包含多種不同類型的內(nèi)容(JSON、XML、文件等)
  • 需要對非文件部分進行 Bean Validation 驗證
  • 需要獲取部分的完整信息(如請求頭)

使用 @RequestParam 當:

  • 只上傳文件,沒有復雜的結(jié)構(gòu)化數(shù)據(jù)
  • 只有簡單的鍵值對參數(shù)
  • 需要向后兼容舊的表單提交

最佳實踐:

// 混合使用示例
@PostMapping(value = "/best-practice", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String bestPractice(
        @RequestPart("document") MultipartFile document,      // 文件用 @RequestPart
        @RequestPart("metadata") DocumentMetadata metadata,   // JSON對象用 @RequestPart
        @RequestParam("description") String description,      // 簡單字段用 @RequestParam
        @RequestParam(value = "tags", required = false) String tags) {
    // 業(yè)務邏輯
    return "Processed successfully";
}

記?。?code>@RequestPart 是 @RequestParam 的增強版本,專門為 multipart/form-data 請求設計,支持更復雜的數(shù)據(jù)綁定場景。在實際開發(fā)中,根據(jù)數(shù)據(jù)復雜度選擇合適的注解。

到此這篇關(guān)于Spring Boot控制層參數(shù)綁定 @RequestPart 注解詳解的文章就介紹到這了,更多相關(guān)Spring Boot @RequestPart 注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot項目中PropertySource如何讀取yaml配置文件

    springboot項目中PropertySource如何讀取yaml配置文件

    這篇文章主要介紹了springboot項目中PropertySource如何讀取yaml配置文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Spring中@Transactional注解關(guān)鍵屬性和用法小結(jié)

    Spring中@Transactional注解關(guān)鍵屬性和用法小結(jié)

    在Spring框架中,@Transactional 是一個注解,用于聲明事務性的方法,它提供了一種聲明式的事務管理方式,避免了在代碼中直接編寫事務管理相關(guān)的代碼,本文給大家介紹@Transactional 注解的一些關(guān)鍵屬性和用法,感興趣的朋友一起看看吧
    2023-12-12
  • Java靜態(tài)static關(guān)鍵字原理詳解

    Java靜態(tài)static關(guān)鍵字原理詳解

    這篇文章主要介紹了Java靜態(tài)static關(guān)鍵字原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • Java實現(xiàn)TopK問題的方法

    Java實現(xiàn)TopK問題的方法

    這篇文章主要介紹了Java實現(xiàn)TopK問題的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • javascript最新2020經(jīng)典面試題

    javascript最新2020經(jīng)典面試題

    這篇文章主要介紹了javascript最新2020經(jīng)典面試題的相關(guān)內(nèi)容,有需要的朋友們可以學習下。
    2020-02-02
  • Java實現(xiàn)OTP(動態(tài)口令)服務

    Java實現(xiàn)OTP(動態(tài)口令)服務

    OTP是一種動態(tài)生成的短時有效密碼,用于身份驗證,通常在登錄或執(zhí)行敏感操作時提供額外的安全保障,本文主要介紹了Java實現(xiàn)OTP(動態(tài)口令)服務,感興趣的可以了解一下
    2025-03-03
  • 解答為什么 Java 線程沒有Running狀態(tài)

    解答為什么 Java 線程沒有Running狀態(tài)

    Java 線程沒有Running狀態(tài)指的是一個在 JVM 中執(zhí)行 的線程處于的狀態(tài),本文小編將為大家詳解一二,需要的朋友可以參考下面文章具體內(nèi)容
    2021-09-09
  • springboot加載配值文件的實現(xiàn)步驟

    springboot加載配值文件的實現(xiàn)步驟

    本文主要介紹了springboot加載配值文件的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-03-03
  • Java并發(fā)編程Semaphore計數(shù)信號量詳解

    Java并發(fā)編程Semaphore計數(shù)信號量詳解

    這篇文章主要介紹了Java并發(fā)編程Semaphore計數(shù)信號量詳解,具有一定參考價值,需要的朋友可以了解下。
    2017-10-10
  • Spring如何在xml文件中配置Bean

    Spring如何在xml文件中配置Bean

    這篇文章主要介紹了Spring如何在xml文件中配置Bean的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-07-07

最新評論

琼中| 博客| 横峰县| 洛川县| 洪湖市| 封开县| SHOW| 阿瓦提县| 宁都县| 凯里市| 徐水县| 通山县| 上犹县| 滨海县| 钟山县| 吉首市| 桓台县| 东山县| 五寨县| 聂荣县| 南郑县| 洛宁县| 新巴尔虎右旗| 绵阳市| 长沙市| 凤冈县| 肇庆市| 全椒县| 绥芬河市| 汉寿县| 万荣县| 吉林省| 霍邱县| 滦南县| 防城港市| 宁晋县| 从化市| 台州市| 永宁县| 江北区| 新河县|