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

SpringBoot 中大文件(分片上傳)斷點(diǎn)續(xù)傳與極速秒傳功能的實(shí)現(xiàn)

 更新時(shí)間:2020年07月15日 10:18:01   作者:往日時(shí)光--  
這篇文章主要介紹了SpringBoot 中大文件(分片上傳)斷點(diǎn)續(xù)傳與極速秒傳功能的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

1.創(chuàng)建SpringBoot項(xiàng)目

本項(xiàng)目采用springboot + mybatis-plus +jquery +thymeleaf組成

2.項(xiàng)目流程圖

在這里插入圖片描述

3.在pom中添加以下依賴

<!--lombok依賴-->
  <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
  </dependency>
  <!--文件上傳依賴-->
  <dependency>
   <groupId>commons-io</groupId>
   <artifactId>commons-io</artifactId>
   <version>2.4</version>
  </dependency>
  <dependency>
   <groupId>commons-fileupload</groupId>
   <artifactId>commons-fileupload</artifactId>
   <version>1.3.1</version>
  </dependency>

  <!-- mysql的依賴 -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
  </dependency>

  <!-- mybatis-plus依賴 -->
  <dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.3.2</version>
  </dependency>

4.在application.properties配置文件中

spring.resources.static-locations=classpath:/static
server.port=8000
  
#設(shè)置上傳圖片的路徑
file.basepath=D:/BaiduNetdiskDownload/

# 設(shè)置單個(gè)文件大小
spring.servlet.multipart.max-file-size= 50MB
# 設(shè)置單次請(qǐng)求文件的總大小
spring.servlet.multipart.max-request-size= 50MB


##設(shè)置要連接的mysql數(shù)據(jù)庫(kù)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

5.在數(shù)據(jù)庫(kù)創(chuàng)建表

create table file
(
 id INTEGER primary key AUTO_INCREMENT comment 'id',
 path varchar(100) not null COMMENT '相對(duì)路徑',
 name varchar(100) COMMENT '文件名',
 suffix varchar(10) COMMENT '文件后綴',
 size int COMMENT '文件大小|字節(jié)B',
 created_at BIGINT(20) COMMENT '文件創(chuàng)建時(shí)間',
 updated_at bigint(20) COMMENT '文件修改時(shí)間',
 shard_index int comment '已上傳分片',
 shard_size int COMMENT '分片大小|B',
 shard_total int COMMENT '分片總數(shù)',
 file_key varchar(100) COMMENT '文件標(biāo)識(shí)'
)

6.創(chuàng)建實(shí)體類

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;


@Data
@TableName(value = "file")
public class FileDTO {
 /**
 * id
 */
 @TableId(value = "id", type = IdType.AUTO)
 private Integer id;

 /**
 * 相對(duì)路徑
 */
 private String path;

 /**
 * 文件名
 */
 private String name;

 /**
 * 后綴
 */
 private String suffix;

 /**
 * 大小|字節(jié)B
 */
 private Integer size;


 /**
 * 創(chuàng)建時(shí)間
 */
 private Long createdAt;

 /**
 * 修改時(shí)間
 */
 private Long updatedAt;

 /**
 * 已上傳分片
 */
 private Integer shardIndex;

 /**
 * 分片大小|B
 */
 private Integer shardSize;

 /**
 * 分片總數(shù)
 */
 private Integer shardTotal;

 /**
 * 文件標(biāo)識(shí)
 */
 private String fileKey;

}

7.創(chuàng)建mapper

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.upload.entity.FileDTO;
import org.springframework.stereotype.Repository;

@Repository
public interface FileMapper extends BaseMapper<FileDTO> {
}

8.創(chuàng)建service

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.upload.dao.FileMapper;
import com.example.demo.upload.entity.FileDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class FileService {

 @Autowired
 private FileMapper fileMapper;

 //保存文件
 public void save(FileDTO file1){
  //根據(jù) 數(shù)據(jù)庫(kù)的 文件標(biāo)識(shí)來查詢 當(dāng)前視頻 是否存在
  LambdaQueryWrapper<FileDTO> lambda = new QueryWrapper<FileDTO>().lambda();
  lambda.eq(FileDTO::getFileKey,file1.getFileKey());
  List<FileDTO> fileDTOS = fileMapper.selectList(lambda);
  //如果存在就話就修改
  if(fileDTOS.size()!=0){
   //根據(jù)key來修改
   LambdaQueryWrapper<FileDTO> lambda1 = new QueryWrapper<FileDTO>().lambda();
   lambda1.eq(FileDTO::getFileKey,file1.getFileKey());
   fileMapper.update(file1,lambda1);
  }else
  {
   //不存在就添加
   fileMapper.insert(file1);
  }
 }

 //檢查文件
 public List<FileDTO> check(String key){
  LambdaQueryWrapper<FileDTO> lambda = new QueryWrapper<FileDTO>().lambda();
  lambda.eq(FileDTO::getFileKey,key);
  List<FileDTO> dtos = fileMapper.selectList(lambda);
  return dtos;
 }

}

9.創(chuàng)建utils

import lombok.Data;

/**
 * 統(tǒng)一返回值
 *
 * @author zhangshuai
 *
 */
@Data
public class Result {

	// 成功狀態(tài)碼
	public static final int SUCCESS_CODE = 200;

	// 請(qǐng)求失敗狀態(tài)碼
	public static final int FAIL_CODE = 500;

	// 查無資源狀態(tài)碼
	public static final int NOTF_FOUNT_CODE = 404;

	// 無權(quán)訪問狀態(tài)碼
	public static final int ACCESS_DINE_CODE = 403;

	/**
	 * 狀態(tài)碼
	 */
	private int code;

	/**
	 * 提示信息
	 */
	private String msg;

	/**
	 * 數(shù)據(jù)信息
	 */
	private Object data;

	/**
	 * 請(qǐng)求成功
	 *
	 * @return
	 */
	public static Result ok() {
		Result r = new Result();
		r.setCode(SUCCESS_CODE);
		r.setMsg("請(qǐng)求成功!");
		r.setData(null);
		return r;
	}

	/**
	 * 請(qǐng)求失敗
	 *
	 * @return
	 */
	public static Result fail() {
		Result r = new Result();
		r.setCode(FAIL_CODE);
		r.setMsg("請(qǐng)求失?。?);
		r.setData(null);
		return r;
	}

	/**
	 * 請(qǐng)求成功,自定義信息
	 *
	 * @param msg
	 * @return
	 */
	public static Result ok(String msg) {
		Result r = new Result();
		r.setCode(SUCCESS_CODE);
		r.setMsg(msg);
		r.setData(null);
		return r;
	}

	/**
	 * 請(qǐng)求失敗,自定義信息
	 *
	 * @param msg
	 * @return
	 */
	public static Result fail(String msg) {
		Result r = new Result();
		r.setCode(FAIL_CODE);
		r.setMsg(msg);
		r.setData(null);
		return r;
	}

	/**
	 * 請(qǐng)求成功,自定義信息,自定義數(shù)據(jù)
	 *
	 * @param msg
	 * @return
	 */
	public static Result ok(String msg, Object data) {
		Result r = new Result();
		r.setCode(SUCCESS_CODE);
		r.setMsg(msg);
		r.setData(data);
		return r;
	}

	/**
	 * 請(qǐng)求失敗,自定義信息,自定義數(shù)據(jù)
	 *
	 * @param msg
	 * @return
	 */
	public static Result fail(String msg, Object data) {
		Result r = new Result();
		r.setCode(FAIL_CODE);
		r.setMsg(msg);
		r.setData(data);
		return r;
	}
	public Result code(Integer code){
		this.setCode(code);
		return this;
	}


	public Result data(Object data){
		this.setData(data);
		return this;
	}

	public Result msg(String msg){
		this.setMsg(msg);
		return this;
	}

}

10.創(chuàng)建controller

import com.example.demo.upload.entity.FileDTO;
import com.example.demo.upload.service.FileService;
import com.example.demo.upload.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.List;
import java.util.UUID;

@Controller
@RequestMapping("/file")
@Slf4j
public class FileController {

 @Autowired
 FileService fileService;

 public static final String BUSINESS_NAME = "普通分片上傳";

 // 設(shè)置圖片上傳路徑
 @Value("${file.basepath}")
 private String basePath;

 @RequestMapping("/show")
 public String show(){
  return "file";
 }

 /**
  * 上傳
  * @param file
  * @param suffix
  * @param shardIndex
  * @param shardSize
  * @param shardTotal
  * @param size
  * @param key
  * @return
  * @throws IOException
  * @throws InterruptedException
  */
 @RequestMapping("/upload")
 @ResponseBody
 public String upload(MultipartFile file,
       String suffix,
       Integer shardIndex,
       Integer shardSize,
       Integer shardTotal,
       Integer size,
       String key
       ) throws IOException, InterruptedException {
  log.info("上傳文件開始");
  //文件的名稱
  String name = UUID.randomUUID().toString().replaceAll("-", "");
  // 獲取文件的擴(kuò)展名
  String ext = FilenameUtils.getExtension(file.getOriginalFilename());

  //設(shè)置圖片新的名字
  String fileName = new StringBuffer().append(key).append(".").append(suffix).toString(); // course\6sfSqfOwzmik4A4icMYuUe.mp4
  //這個(gè)是分片的名字
  String localfileName = new StringBuffer(fileName)
    .append(".")
    .append(shardIndex)
    .toString(); // course\6sfSqfOwzmik4A4icMYuUe.mp4.1

  // 以絕對(duì)路徑保存重名命后的圖片
  File targeFile=new File(basePath,localfileName);
  //上傳這個(gè)圖片
  file.transferTo(targeFile);
  //數(shù)據(jù)庫(kù)持久化這個(gè)數(shù)據(jù)
  FileDTO file1=new FileDTO();
  file1.setPath(basePath+localfileName);
  file1.setName(name);
  file1.setSuffix(ext);
  file1.setSize(size);
  file1.setCreatedAt(System.currentTimeMillis());
  file1.setUpdatedAt(System.currentTimeMillis());
  file1.setShardIndex(shardIndex);
  file1.setShardSize(shardSize);
  file1.setShardTotal(shardTotal);
  file1.setFileKey(key);
  //插入到數(shù)據(jù)庫(kù)中
  //保存的時(shí)候 去處理一下 這個(gè)邏輯
  fileService.save(file1);
  //判斷當(dāng)前是不是最后一個(gè)分頁(yè) 如果不是就繼續(xù)等待其他分頁(yè) 合并分頁(yè)
  if(shardIndex .equals(shardTotal) ){
   file1.setPath(basePath+fileName);
   this.merge(file1);
  }
  return "上傳成功";
 }

 @RequestMapping("/check")
 @ResponseBody
 public Result check(String key){
  List<FileDTO> check = fileService.check(key);
  //如果這個(gè)key存在的話 那么就獲取上一個(gè)分片去繼續(xù)上傳
  if(check.size()!=0){
   return Result.ok("查詢成功",check.get(0));
  }
  return Result.fail("查詢失敗,可以添加");
 }


 /**
  * @author fengxinglie
  * 合并分頁(yè)
  */
 private void merge(FileDTO fileDTO) throws FileNotFoundException, InterruptedException {
  //合并分片開始
  log.info("分片合并開始");
  String path = fileDTO.getPath(); //獲取到的路徑 沒有.1 .2 這樣的東西
  //截取視頻所在的路徑
  path = path.replace(basePath,"");
  Integer shardTotal= fileDTO.getShardTotal();
  File newFile = new File(basePath + path);
  FileOutputStream outputStream = new FileOutputStream(newFile,true); // 文件追加寫入
  FileInputStream fileInputStream = null; //分片文件
  byte[] byt = new byte[10 * 1024 * 1024];
  int len;
  try {
   for (int i = 0; i < shardTotal; i++) {
    // 讀取第i個(gè)分片
    fileInputStream = new FileInputStream(new File(basePath + path + "." + (i + 1))); // course\6sfSqfOwzmik4A4icMYuUe.mp4.1
    while ((len = fileInputStream.read(byt)) != -1) {
     outputStream.write(byt, 0, len);
    }
   }
  } catch (IOException e) {
   log.error("分片合并異常", e);
  } finally {
   try {
    if (fileInputStream != null) {
     fileInputStream.close();
    }
    outputStream.close();
    log.info("IO流關(guān)閉");
   } catch (Exception e) {
    log.error("IO流關(guān)閉", e);
   }
  }
  log.info("分片結(jié)束了");
  //告訴java虛擬機(jī)去回收垃圾 至于什么時(shí)候回收 這個(gè)取決于 虛擬機(jī)的決定
  System.gc();
  //等待100毫秒 等待垃圾回收去 回收完垃圾
  Thread.sleep(100);
  log.info("刪除分片開始");
  for (int i = 0; i < shardTotal; i++) {
   String filePath = basePath + path + "." + (i + 1);
   File file = new File(filePath);
   boolean result = file.delete();
   log.info("刪除{},{}", filePath, result ? "成功" : "失敗");
  }
  log.info("刪除分片結(jié)束");
 }

}

11.創(chuàng)建html頁(yè)面

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="/md5.js"></script>
<script type="text/javascript" src="/tool.js"></script>
<script type="text/javascript">
 //上傳文件的話 得 單獨(dú)出來
 function test1(shardIndex) {
  console.log(shardIndex);
  //永安里from表單提交
  var fd = new FormData();
  //獲取表單中的file
  var file=$('#inputfile').get(0).files[0];
  //文件分片 以20MB去分片
  var shardSize = 20 * 1024 * 1024;
  //定義分片索引
  var shardIndex = shardIndex;
  //定義分片的起始位置
  var start = (shardIndex-1) * shardSize;
  //定義分片結(jié)束的位置 file哪里來的?
  var end = Math.min(file.size,start + shardSize);
  //從文件中截取當(dāng)前的分片數(shù)據(jù)
  var fileShard = file.slice(start,end);
  //分片的大小
  var size = file.size;
  //總片數(shù)
  var shardTotal = Math.ceil(size / shardSize);
  //文件的后綴名
  var fileName = file.name;
  var suffix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length).toLowerCase();
  //把視頻的信息存儲(chǔ)為一個(gè)字符串
  var filedetails=file.name+file.size+file.type+file.lastModifiedDate;
  //使用當(dāng)前文件的信息用md5加密生成一個(gè)key 這個(gè)加密是根據(jù)文件的信息來加密的 如果相同的文件 加的密還是一樣的
  var key = hex_md5(filedetails);
  var key10 = parseInt(key,16);
  //把加密的信息 轉(zhuǎn)為一個(gè)64位的
  var key62 = Tool._10to62(key10);
  //前面的參數(shù)必須和controller層定義的一樣
  fd.append('file',fileShard);
  fd.append('suffix',suffix);
  fd.append('shardIndex',shardIndex);
  fd.append('shardSize',shardSize);
  fd.append('shardTotal',shardTotal);
  fd.append('size',size);
  fd.append("key",key62)
  $.ajax({
   url:"/file/upload",
   type:"post",
   cache: false,
   data:fd,
   processData: false,
   contentType: false,
   success:function(data){
    //這里應(yīng)該是一個(gè)遞歸調(diào)用
    if(shardIndex < shardTotal){
     var index=shardIndex +1;
     test1(index);
    }else
    {
     alert(data)
    }

   },
   error:function(){
    //請(qǐng)求出錯(cuò)處理
   }
  })
  //發(fā)送ajax請(qǐng)求把參數(shù)傳遞到后臺(tái)里面
 }

 //判斷這個(gè)加密文件存在不存在
 function check() {
  var file=$('#inputfile').get(0).files[0];
  //把視頻的信息存儲(chǔ)為一個(gè)字符串
  var filedetails=file.name+file.size+file.type+file.lastModifiedDate;
  //使用當(dāng)前文件的信息用md5加密生成一個(gè)key 這個(gè)加密是根據(jù)文件的信息來加密的 如果相同的文件 加的密還是一樣的
  var key = hex_md5(filedetails);
  var key10 = parseInt(key,16);
  //把加密的信息 轉(zhuǎn)為一個(gè)64位的
  var key62 = Tool._10to62(key10);
  //檢查這個(gè)key存在不存在
  $.ajax({
   url:"/file/check",
   type:"post",
   data:{'key':key62},
   success:function (data) {
    console.log(data);
    if(data.code==500){
     //這個(gè)方法必須抽離出來
     test1(1);
    }
    else
    {
     if(data.data.shardIndex == data.data.shardTotal)
     {
      alert("極速上傳成功");
     }else
     {
      //找到這個(gè)是第幾片 去重新上傳
      test1(parseInt(data.data.shardIndex));
     }
    }
   }
  })
 }

</script>
<body>
 <table border="1px solid red">
  <tr>
   <td>文件1</td>
   <td>
    <input name="file" type="file" id="inputfile"/>
   </td>
  </tr>
  <tr>
   <td></td>
   <td>
    <button onclick="check()">提交</button>
   </td>
  </tr>
 </table>
</body>
</html>

12.測(cè)試

在這里插入圖片描述

12.2:查看數(shù)據(jù)庫(kù)

在這里插入圖片描述

12.3 :已經(jīng)上傳成功 重新上傳一次

在這里插入圖片描述

12.4:當(dāng)我上傳一半的時(shí)候 (顯示上傳了一個(gè)文件 然后我們繼續(xù)上傳)

在這里插入圖片描述

12.5:繼續(xù)上傳 查看目錄 發(fā)現(xiàn)已經(jīng)成功了

在這里插入圖片描述
在這里插入圖片描述

13.注意事項(xiàng)

13.1:程序中并沒有去判斷 你存在不存在 上傳圖片的地址 所以如果打算使用代碼 請(qǐng)創(chuàng)建 上傳圖片的目錄 D:/BaiduNetdiskDownload/
13.2 :使用代碼前請(qǐng)修改配置文件中的 數(shù)據(jù)庫(kù)連接

14.代碼 直達(dá)地址

到此這篇關(guān)于SpringBoot 中大文件(分片上傳)斷點(diǎn)續(xù)傳與極速秒傳功能的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)springboot大文件斷點(diǎn)續(xù)傳秒傳內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • RocketMQ的消費(fèi)者類型與最佳實(shí)踐詳解

    RocketMQ的消費(fèi)者類型與最佳實(shí)踐詳解

    這篇文章主要介紹了RocketMQ的消費(fèi)者類型與最佳實(shí)踐詳解,在?RocketMQ?5.0?中,更加強(qiáng)調(diào)了客戶端類型的概念,尤其是消費(fèi)者類型,為了滿足多樣的?RocketMQ?中一共有三種不同的消費(fèi)者類型,分別是?PushConsumer、SimpleConsumer?和?PullConsumer,需要的朋友可以參考下
    2023-10-10
  • Java如何實(shí)現(xiàn)將類文件打包為jar包

    Java如何實(shí)現(xiàn)將類文件打包為jar包

    這篇文章主要介紹了Java如何實(shí)現(xiàn)將類文件打包為jar包,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java使用FilenameFilter查找出目錄下指定后綴的文件示例

    Java使用FilenameFilter查找出目錄下指定后綴的文件示例

    這篇文章主要介紹了Java使用FilenameFilter查找出目錄下指定后綴的文件,結(jié)合實(shí)例形式分析了java基于FilenameFilter類的文件遍歷、查找相關(guān)操作技巧,需要的朋友可以參考下
    2019-10-10
  • mybatis中 if-test 數(shù)字判斷的坑及解決

    mybatis中 if-test 數(shù)字判斷的坑及解決

    這篇文章主要介紹了mybatis中 if-test 數(shù)字判斷的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java tomcat中的類加載器和安全機(jī)制你了解嗎

    Java tomcat中的類加載器和安全機(jī)制你了解嗎

    這篇文章主要介紹了Tomcat 類加載器的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-09-09
  • Java用BigDecimal類解決Double類型精度丟失的問題

    Java用BigDecimal類解決Double類型精度丟失的問題

    這篇文章主要介紹了Java用BigDecimal類解決Double類型精度丟失的問題,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • Java面試題之基本語(yǔ)法(圖解)

    Java面試題之基本語(yǔ)法(圖解)

    這篇文章主要介紹了關(guān)于Java面試題之基本語(yǔ)法的相關(guān)資料,文中通過圖片說明介紹的很詳細(xì),相信對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來一起看看吧。
    2017-02-02
  • SpringCloud中的服務(wù)接口(api)

    SpringCloud中的服務(wù)接口(api)

    這篇文章主要介紹了SpringCloud中的服務(wù)接口(api),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • java開發(fā)_圖片截取工具實(shí)現(xiàn)原理

    java開發(fā)_圖片截取工具實(shí)現(xiàn)原理

    本文將詳細(xì)介紹java開發(fā)_圖片截取工具實(shí)現(xiàn)原理,需要了解的朋友可以參考下
    2012-11-11
  • Java源碼解析之平衡二叉樹

    Java源碼解析之平衡二叉樹

    在上一章的文章中,我們講到了二叉排序樹,它很好的平衡了插入與查找的效率,但二叉排序樹如果不平衡,那么查找效率就會(huì)大大降低,今天要講的這個(gè)平衡二叉樹就是一種解決這個(gè)問題的方法.需要的朋友可以參考下
    2021-05-05

最新評(píng)論

沙坪坝区| 抚宁县| 开阳县| 右玉县| 建瓯市| 大关县| 巴里| 定结县| 嘉善县| 贵港市| 图们市| 尤溪县| 化州市| 九龙县| 徐闻县| 沈阳市| 改则县| 冷水江市| 周宁县| 博爱县| 海安县| 朝阳市| 海淀区| 绵竹市| 射阳县| 美姑县| 锡林郭勒盟| 滁州市| 青田县| 武冈市| 安龙县| 炎陵县| 西昌市| 连江县| 天等县| 义乌市| 苗栗市| 潢川县| 伊宁市| 烟台市| 定兴县|