本文目录导读:

我来提供一个完整的Java短信群发案例,使用阿里云短信服务作为示例。
项目结构
sms-demo/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/sms/
│ │ │ ├── config/
│ │ │ │ └── SmsConfig.java
│ │ │ ├── controller/
│ │ │ │ └── SmsController.java
│ │ │ ├── service/
│ │ │ │ ├── SmsService.java
│ │ │ │ ├── SmsServiceImpl.java
│ │ │ │ └── BatchSmsService.java
│ │ │ ├── model/
│ │ │ │ ├── SmsRequest.java
│ │ │ │ └── SmsResponse.java
│ │ │ ├── utils/
│ │ │ │ └── SmsTemplate.java
│ │ │ └── SmsApplication.java
│ │ └── resources/
│ │ └── application.yml
│ └── test/
│ └── java/
│ └── com/example/sms/
│ └── SmsServiceTest.java
Maven依赖 (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.14</version>
</parent>
<groupId>com.example</groupId>
<artifactId>sms-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 阿里云短信SDK -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.18</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 数据校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
配置文件 (application.yml)
server:
port: 8080
spring:
application:
name: sms-demo
# 阿里云短信配置
aliyun:
sms:
# 访问密钥ID(配置为环境变量或使用密钥管理服务)
access-key-id: ${ALIYUN_ACCESS_KEY_ID}
access-key-secret: ${ALIYUN_ACCESS_KEY_SECRET}
# 短信签名
sign-name: "你的短信签名"
# 模板代码
verify-code-template: "SMS_123456789"
notice-template: "SMS_987654321"
# 短信服务Endpoint
endpoint: "dysmsapi.aliyuncs.com"
配置类
// SmsConfig.java
package com.example.sms.config;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.teaopenapi.models.Config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "aliyun.sms")
public class SmsConfig {
private String accessKeyId;
private String accessKeySecret;
private String signName;
private String verifyCodeTemplate;
private String noticeTemplate;
private String endpoint;
@Bean
public Client smsClient() throws Exception {
Config config = new Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(accessKeySecret);
config.endpoint = endpoint;
return new Client(config);
}
}
数据模型
// SmsRequest.java
package com.example.sms.model;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import java.util.List;
import java.util.Map;
@Data
public class SmsRequest {
// 短信签名
private String signName;
// 模板Code
private String templateCode;
// 手机号列表(群发)
@NotEmpty(message = "手机号列表不能为空")
private List<@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确") String> phoneNumbers;
// 模板参数
private Map<String, String> templateParam;
// 扩展字段
private String extendCode;
// 外部流水扩展字段
private String outId;
}
// SmsResponse.java
package com.example.sms.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SmsResponse {
private boolean success;
private String message;
private String requestId;
private String bizId;
private String code;
public static SmsResponse success(String requestId, String bizId) {
return new SmsResponse(true, "短信发送成功", requestId, bizId, "OK");
}
public static SmsResponse failure(String code, String message) {
return new SmsResponse(false, message, null, null, code);
}
}
// BatchSmsResult.java
package com.example.sms.model;
import lombok.Data;
import java.util.List;
@Data
public class BatchSmsResult {
private int total;
private int successCount;
private int failCount;
private List<String> failedPhones;
private List<String> successPhones;
}
服务层
// SmsService.java
package com.example.sms.service;
import com.example.sms.model.SmsRequest;
import com.example.sms.model.SmsResponse;
public interface SmsService {
// 发送单个短信
SmsResponse sendSingleSms(String phoneNumber, String templateCode, java.util.Map<String, String> params);
// 发送验证码
SmsResponse sendVerifyCode(String phoneNumber, String code, String businessType);
// 发送通知短信
SmsResponse sendNoticeSms(String phoneNumber, String content);
// 批量发送短信(同步)
com.example.sms.model.BatchSmsResult sendBatchSms(SmsRequest request);
// 批量发送短信(异步)
void sendBatchSmsAsync(SmsRequest request, java.util.concurrent.ExecutorService executor);
}
// SmsServiceImpl.java
package com.example.sms.service;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.example.sms.config.SmsConfig;
import com.example.sms.model.BatchSmsResult;
import com.example.sms.model.SmsRequest;
import com.example.sms.model.SmsResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
@Service
public class SmsServiceImpl implements SmsService {
@Autowired
private Client smsClient;
@Autowired
private SmsConfig smsConfig;
// 使用线程池进行异步批量发送
private final ExecutorService executorService = Executors.newFixedThreadPool(10);
@Override
public SmsResponse sendSingleSms(String phoneNumber, String templateCode,
Map<String, String> params) {
try {
SendSmsRequest request = new SendSmsRequest()
.setPhoneNumbers(phoneNumber)
.setSignName(smsConfig.getSignName())
.setTemplateCode(templateCode);
// 设置模板参数(如果有)
if (params != null && !params.isEmpty()) {
request.setTemplateParam(JSONObject.toJSONString(params));
}
// 调用阿里云API
SendSmsResponse response = smsClient.sendSms(request);
SendSmsResponseBody body = response.getBody();
if ("OK".equals(body.getCode())) {
log.info("短信发送成功,手机号:{},BizId:{}", phoneNumber, body.getBizId());
return SmsResponse.success(body.getRequestId(), body.getBizId());
} else {
log.error("短信发送失败,手机号:{},code:{}, message:{}",
phoneNumber, body.getCode(), body.getMessage());
return SmsResponse.failure(body.getCode(), body.getMessage());
}
} catch (Exception e) {
log.error("短信发送异常,手机号:{}", phoneNumber, e);
return SmsResponse.failure("SYSTEM_ERROR", "系统异常,发送失败");
}
}
@Override
public SmsResponse sendVerifyCode(String phoneNumber, String code, String businessType) {
Map<String, String> params = new HashMap<>();
params.put("code", code);
// 使用验证码模板
return sendSingleSms(phoneNumber, smsConfig.getVerifyCodeTemplate(), params);
}
@Override
public SmsResponse sendNoticeSms(String phoneNumber, String content) {
Map<String, String> params = new HashMap<>();
params.put("content", content);
// 使用通知模板
return sendSingleSms(phoneNumber, smsConfig.getNoticeTemplate(), params);
}
@Override
public BatchSmsResult sendBatchSms(SmsRequest request) {
BatchSmsResult result = new BatchSmsResult();
result.setTotal(request.getPhoneNumbers().size());
List<String> successPhones = new ArrayList<>();
List<String> failedPhones = new ArrayList<>();
// 同步批量发送
for (String phoneNumber : request.getPhoneNumbers()) {
SmsResponse response = sendSingleSms(
phoneNumber,
request.getTemplateCode(),
request.getTemplateParam()
);
if (response.isSuccess()) {
successPhones.add(phoneNumber);
} else {
failedPhones.add(phoneNumber);
}
}
result.setSuccessCount(successPhones.size());
result.setFailCount(failedPhones.size());
result.setSuccessPhones(successPhones);
result.setFailedPhones(failedPhones);
return result;
}
@Override
public void sendBatchSmsAsync(SmsRequest request, ExecutorService executor) {
// 异步批量发送
List<CompletableFuture<Void>> futures = new ArrayList<>();
for (String phoneNumber : request.getPhoneNumbers()) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
SmsResponse response = sendSingleSms(
phoneNumber,
request.getTemplateCode(),
request.getTemplateParam()
);
if (response.isSuccess()) {
log.info("异步短信发送成功:{}", phoneNumber);
} else {
log.warn("异步短信发送失败:{},错误:{}",
phoneNumber, response.getMessage());
}
} catch (Exception e) {
log.error("异步短信发送异常:{}", phoneNumber, e);
}
}, executor != null ? executor : executorService);
futures.add(future);
}
// 等待所有短信发送完成(可选)
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.whenComplete((v, throwable) -> {
log.info("所有短信异步发送任务执行完成");
});
}
}
// BatchSmsService.java
package com.example.sms.service;
import com.example.sms.model.SmsRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
@Service
public class BatchSmsService {
@Autowired
private SmsService smsService;
// 配置线程池
private final ExecutorService executorService = Executors.newFixedThreadPool(10);
/**
* 高性能批量发送(分批次)
*/
public void sendHighPerformanceBatch(SmsRequest request, int batchSize) {
List<String> allPhones = request.getPhoneNumbers();
int totalBatches = (int) Math.ceil((double) allPhones.size() / batchSize);
log.info("开始批量发送短信,总数:{},分{}批", allPhones.size(), totalBatches);
List<CompletableFuture<Void>> batchFutures = new ArrayList<>();
for (int i = 0; i < totalBatches; i++) {
int start = i * batchSize;
int end = Math.min(start + batchSize, allPhones.size());
List<String> batchPhones = allPhones.subList(start, end);
// 每批异步处理
CompletableFuture<Void> batchFuture = CompletableFuture.runAsync(() -> {
SmsRequest batchRequest = new SmsRequest();
batchRequest.setPhoneNumbers(batchPhones);
batchRequest.setTemplateCode(request.getTemplateCode());
batchRequest.setTemplateParam(request.getTemplateParam());
// 同步发送该批次
sendBatchSmsSync(batchRequest);
}, executorService);
batchFutures.add(batchFuture);
}
// 等待所有批次完成
CompletableFuture.allOf(batchFutures.toArray(new CompletableFuture[0]))
.join();
log.info("所有批次短信发送完成");
}
/**
* 同步发送一批短信
*/
private void sendBatchSmsSync(SmsRequest request) {
for (String phoneNumber : request.getPhoneNumbers()) {
try {
var response = smsService.sendSingleSms(
phoneNumber,
request.getTemplateCode(),
request.getTemplateParam()
);
if (response.isSuccess()) {
log.debug("短信发送成功:{}", phoneNumber);
} else {
log.warn("短信发送失败:{},原因:{}", phoneNumber, response.getMessage());
}
} catch (Exception e) {
log.error("短信发送异常:{}", phoneNumber, e);
}
}
}
}
控制器
// SmsController.java
package com.example.sms.controller;
import com.example.sms.model.BatchSmsResult;
import com.example.sms.model.SmsRequest;
import com.example.sms.model.SmsResponse;
import com.example.sms.service.BatchSmsService;
import com.example.sms.service.SmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/api/sms")
public class SmsController {
@Autowired
private SmsService smsService;
@Autowired
private BatchSmsService batchSmsService;
/**
* 发送验证码
*/
@PostMapping("/code")
public SmsResponse sendVerifyCode(@RequestParam String phoneNumber,
@RequestParam String code,
@RequestParam(required = false) String businessType) {
log.info("发送验证码请求,手机号:{}", phoneNumber);
return smsService.sendVerifyCode(phoneNumber, code, businessType);
}
/**
* 发送单条短信
*/
@PostMapping("/single")
public SmsResponse sendSingle(@RequestParam String phoneNumber,
@RequestParam String content) {
log.info("发送单条短信请求,手机号:{}", phoneNumber);
return smsService.sendNoticeSms(phoneNumber, content);
}
/**
* 批量发送(同步)
*/
@PostMapping("/batch")
public BatchSmsResult sendBatch(@Valid @RequestBody SmsRequest request) {
log.info("批量发送短信请求,手机号数量:{}", request.getPhoneNumbers().size());
return smsService.sendBatchSms(request);
}
/**
* 批量发送(异步)
*/
@PostMapping("/batch-async")
public Map<String, Object> sendBatchAsync(@Valid @RequestBody SmsRequest request) {
log.info("异步批量发送短信请求,手机号数量:{}", request.getPhoneNumbers().size());
smsService.sendBatchSmsAsync(request, null);
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("message", "短信已加入发送队列");
result.put("phoneCount", request.getPhoneNumbers().size());
return result;
}
/**
* 高性能分批发送
*/
@PostMapping("/high-performance-batch")
public Map<String, Object> sendHighPerformanceBatch(@Valid @RequestBody SmsRequest request,
@RequestParam(defaultValue = "100") int batchSize) {
log.info("高性能批量发送请求,手机号数量:{},批次大小:{}",
request.getPhoneNumbers().size(), batchSize);
batchSmsService.sendHighPerformanceBatch(request, batchSize);
Map<String, Object> result = new HashMap<>();
result.put("success", true);
result.put("message", "批量发送任务执行完成");
result.put("phoneCount", request.getPhoneNumbers().size());
return result;
}
}
工具类
// SmsValidUtil.java
package com.example.sms.utils;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
public class SmsValidUtil {
private static final Pattern PHONE_PATTERN =
Pattern.compile("^1[3-9]\\d{9}$");
/**
* 校验手机号格式
*/
public static boolean isValidPhone(String phone) {
return PHONE_PATTERN.matcher(phone).matches();
}
/**
* 过滤无效手机号
*/
public static List<String> filterValidPhones(List<String> phones) {
return phones.stream()
.filter(SmsValidUtil::isValidPhone)
.collect(java.util.stream.Collectors.toList());
}
/**
* 去除重复手机号
*/
public static List<String> removeDuplicates(List<String> phones) {
Set<String> uniquePhones = new HashSet<>(phones);
return new ArrayList<>(uniquePhones);
}
/**
* 合并手机号列表(去重)
*/
public static List<String> mergePhones(List<String>... phoneLists) {
Set<String> mergedPhones = new HashSet<>();
for (List<String> phones : phoneLists) {
mergedPhones.addAll(phones);
}
return new ArrayList<>(mergedPhones);
}
}
测试类
// SmsServiceTest.java
package com.example.sms;
import com.example.sms.model.SmsRequest;
import com.example.sms.model.SmsResponse;
import com.example.sms.service.BatchSmsService;
import com.example.sms.service.SmsService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SpringBootTest
class SmsServiceTest {
@Autowired
private SmsService smsService;
@Autowired
private BatchSmsService batchSmsService;
@Test
void contextLoads() {
}
@Test
void testSendSingleSms() {
String phoneNumber = "13800138000";
String code = "123456";
SmsResponse response = smsService.sendVerifyCode(phoneNumber, code, "TEST");
System.out.println("发送结果:" + response);
}
@Test
void testSendBatchSms() {
List<String> phones = new ArrayList<>();
phones.add("13800138000");
phones.add("13900139000");
phones.add("13700137000");
Map<String, String> params = new HashMap<>();
params.put("content", "这是一条测试通知");
SmsRequest request = new SmsRequest();
request.setPhoneNumbers(phones);
request.setTemplateCode("SMS_987654321");
request.setTemplateParam(params);
var result = smsService.sendBatchSms(request);
System.out.println("批量发送结果:" + result);
}
@Test
void testAsyncBatchSms() {
List<String> phones = new ArrayList<>();
for (int i = 0; i < 10; i++) {
phones.add("1380013" + String.format("%04d", i));
}
Map<String, String> params = new HashMap<>();
params.put("content", "这是一条异步测试通知");
SmsRequest request = new SmsRequest();
request.setPhoneNumbers(phones);
request.setTemplateCode("SMS_987654321");
request.setTemplateParam(params);
smsService.sendBatchSmsAsync(request, null);
System.out.println("已提交异步发送任务");
}
@Test
void testHighPerformanceBatch() {
List<String> phones = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
phones.add("138" + String.format("%08d", i));
}
Map<String, String> params = new HashMap<>();
params.put("content", "这是一条高性能测试通知");
SmsRequest request = new SmsRequest();
request.setPhoneNumbers(phones);
request.setTemplateCode("SMS_987654321");
request.setTemplateParam(params);
long startTime = System.currentTimeMillis();
batchSmsService.sendHighPerformanceBatch(request, 100);
long endTime = System.currentTimeMillis();
System.out.println("高性能批量发送耗时:" + (endTime - startTime) + "ms");
}
}
主启动类
// SmsApplication.java
package com.example.sms;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class SmsApplication {
public static void main(String[] args) {
SpringApplication.run(SmsApplication.class, args);
System.out.println("短信服务启动成功!");
}
}
使用示例
// 调用示例
// 1. 发送验证码
Map<String, String> result = restTemplate.postForObject(
"http://localhost:8080/api/sms/code?phoneNumber=13800138000&code=123456",
null,
Map.class
);
// 2. 批量发送
SmsRequest request = new SmsRequest();
request.setPhoneNumbers(Arrays.asList("13800138000", "13900139000"));
request.setTemplateCode("SMS_987654321");
Map<String, String> params = new HashMap<>();
params.put("content", "Hello, 这是一条测试短信");
request.setTemplateParam(params);
Map<String, Object> batchResult = restTemplate.postForObject(
"http://localhost:8080/api/sms/batch",
request,
Map.class
);
注意事项
- 安全配置:API密钥不要硬编码在代码中,应使用环境变量或密钥管理服务
- 限流控制:根据阿里云服务限制,注意发送频率和每日限制
- 错误处理:实现完善的错误处理和重试机制
- 性能优化:使用线程池进行批量异步发送
- 日志记录:记录完整的发送日志,便于排查问题
- 敏感信息加密:对敏感信息进行加密存储和传输
- 成本控制:合理设计短信发送策略,避免不必要的发送费用
这个案例提供了完整的短信群发解决方案,包括单发、批量发送、异步发送和高性能分批发送等功能,可根据实际需求进行调整。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播