vo是在线工具根据json串生成的,就不加了 ,记得vo要加序列化
http://www.itjson.com/itjson/json2java.html
准备
小程序appid
小程序sercet
redis常量
public class RedisConstant {
/**
* 直播live:list:起始:结束
*/
public static final String LIVE_LIST = "live:list%s:%s";
/**
* 直播回放live:replay:房间号
*/
public static final String LIVE_REPLAY = "live:replay:%s";
/**
* 直播redisRoot
*/
public static final String LIVE_ROOT = "live:%s";
/**
* 直播缓存时间/s
*/
public static final Long LIVE_REDIS_TIME = 30L;
}
小程序工具类
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.erp.core.config.MiniProgramConfiguration;
import com.erp.user.vo.live.LiveRoomInfoVO;
import com.erp.user.vo.live.ReplayVO;
import com.erp.utils.HttpUtils;
import org.apache.http.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
/**
* 小程序工具类
*/
public class MiniProgramUtil {
private static String appid = "";
private static String secret = "";
private static final Logger logger = LoggerFactory.getLogger(MiniProgramUtil.class);
/**
*获取access_token
*/
public static String getAccessToken(){
Map<String, String> params = new HashMap<>();
params.put("appid", appid);
params.put("secret", secret);
params.put("grant_type","client_credential");
JSONObject resultObj = new JSONObject();
try {
String url = HttpUtils.buildUrl("https://api.weixin.qq.com","/cgi-bin/token",params);
HttpResponse response = null;
response = HttpUtils.doGet(url);
BufferedReader b = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"),8*1024);
String line=b.readLine();
resultObj = JSONObject.parseObject(line);
if(resultObj.containsKey("errmsg")){
String errmsg = resultObj.getString("errmsg");
if(!resultObj.getString("errcode").equals("0")){
logger.info("获取access_token失败");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return resultObj.getString("access_token");
}
/**
* 获取小程序直播房间列表
* @return
*/
public static ResponseEntity<LiveRoomInfoVO> getLiveInfo(Integer start, Integer limit) {
RestTemplate restTemplate = new RestTemplate();
String url = String.format("https://api.weixin.qq.com/wxa/business/getliveinfo?access_token=%s",getAccessToken());
Map<String, Integer> params = new HashMap<>();
params.put("start",start);
params.put("limit",limit);
ObjectMapper objectMapper = new ObjectMapper();
String json = "";
try {
json = objectMapper.writeValueAsString(params);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
ResponseEntity<LiveRoomInfoVO> responseEntity = restTemplate.postForEntity(url,json,LiveRoomInfoVO.class);
return responseEntity;
}
/**
* 获取小程序直播回放视频
* @param roomId
* @return
*/
public static ResponseEntity<ReplayVO> getLiveReplay(Integer roomId) {
RestTemplate restTemplate = new RestTemplate();
String url = String.format("https://api.weixin.qq.com/wxa/business/getliveinfo?access_token=%s",getAccessToken());
Map<String, Object> params = new HashMap<>();
params.put("start",0);
params.put("limit",10);
params.put("action","get_replay");
params.put("room_id",roomId);
ObjectMapper objectMapper = new ObjectMapper();
String json = "";
try {
json = objectMapper.writeValueAsString(params);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
ResponseEntity<ReplayVO> responseEntity = restTemplate.postForEntity(url,json,ReplayVO.class);
return responseEntity;
}
}
service
import com.erp.base.wrapper.ResponseWrapper;
public interface LiveService {
/**
* 获取直播房间列表
* @return
*/
ResponseWrapper getLiveInfo(Integer start, Integer limit);
/**
* 获取直播房间回放
* @param roomId
* @return
*/
ResponseWrapper getLiveRoomReplay(Integer roomId);
/**
* 刷新直播间
*/
void refreshLive();
}
serviceImpl
import com.erp.base.constant.Constant;
import com.erp.base.constant.RedisConstant;
import com.erp.base.wrapper.ResponseWrapper;
import com.erp.user.service.LiveService;
import com.erp.user.utils.MiniProgramUtil;
import com.erp.user.vo.live.LiveRoomInfoVO;
import com.erp.user.vo.live.ReplayVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.Objects;
@Service
public class LiveServiceImpl implements LiveService {
@Autowired
private RedisTemplate redisTemplate;
@Override
public ResponseWrapper getLiveInfo(Integer start, Integer limit) {
String redisKey = String.format(RedisConstant.LIVE_LIST, start,limit);
//需要做redis数据缓存
LiveRoomInfoVO liveRoomInfoVO = (LiveRoomInfoVO) redisTemplate.opsForValue().get(redisKey);
if(!Objects.isNull(liveRoomInfoVO)){
return ResponseWrapper.ok(liveRoomInfoVO);
}
ResponseEntity<LiveRoomInfoVO> liveInfo = MiniProgramUtil.getLiveInfo(start, limit);
liveRoomInfoVO = liveInfo.getBody();
redisTemplate.opsForValue().set(redisKey, liveRoomInfoVO, RedisConstant.LIVE_REDIS_TIME);
return ResponseWrapper.ok(liveRoomInfoVO);
}
@Override
public ResponseWrapper getLiveRoomReplay(Integer roomId) {
String redisKey = String.format(RedisConstant.LIVE_REPLAY, roomId);
//缓存是否有数据
ReplayVO replayVO = (ReplayVO) redisTemplate.opsForValue().get(redisKey);
if(!Objects.isNull(replayVO)){
return ResponseWrapper.ok(replayVO);
}
//数据缓存
ResponseEntity<ReplayVO> liveInfo = MiniProgramUtil.getLiveReplay(roomId);
replayVO = liveInfo.getBody();
redisTemplate.opsForValue().set(redisKey, replayVO, RedisConstant.LIVE_REDIS_TIME);
return ResponseWrapper.ok(replayVO);
}
@Override
public void refreshLive() {
String redisKey = String.format(RedisConstant.LIVE_ROOT,"*");
redisTemplate.delete(redisKey);
}
}
controller
import com.erp.base.wrapper.ResponseWrapper;
import com.erp.user.service.LiveService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.constraints.NotNull;
@RestController
@RequestMapping("/api/live")
@Api(value = "LiveController", tags = "直播")
public class LiveController {
@Autowired
private LiveService liveService;
@GetMapping(value = "/room_list")
@ApiOperation(value = "获取直播房间列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "start", value = "' 起始拉取房间,start = 0 表示从第 1 个房间开始拉取 '", required = true, dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "limit", value = "'每次拉取的个数上限,不要设置过大,建议 100 以内 '", required = true, dataType = "int", paramType = "query"),
})
public ResponseWrapper roomList(@NotNull Integer start,
@NotNull Integer limit) {
return liveService.getLiveInfo(start, limit);
}
@GetMapping(value = "/room_replay")
@ApiOperation(value = "获取直播房间回放")
@ApiImplicitParams({
@ApiImplicitParam(name = "roomId", value = "'房间id '", required = true, dataType = "long", paramType = "query"),
})
public ResponseWrapper roomReplay(@NotNull Integer roomId) {
return liveService.getLiveRoomReplay(roomId);
}
@GetMapping(value = "/refresh_live")
@ApiOperation(value = "强制刷新直播间缓存")
public ResponseWrapper refreshLive() {
liveService.refreshLive();
return ResponseWrapper.ok();
}
}
HttpUtils 里面有些方法过期了,酌情使用
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Map;
public class HttpUtils {
public static final int TIME_OUT = 1000 * 30;
protected static final Logger logger = LoggerFactory.getLogger(HttpUtils.class);
public static String doGet(String url, Map<String, String> headers, String params) throws Exception {
String strResult = "";
url += params;
HttpClient httpClient = getHttpClient(url);
HttpGet request = new HttpGet(url);
request.setHeader("Content-Type", "application/json;charset=UTF-8");
if (headers != null) {
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
}
try {
HttpResponse httpResponse = httpClient.execute(request);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
strResult = EntityUtils.toString(httpResponse.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
return strResult;
}
/**
* get
*
* @return
* @throws Exception
*/
public static HttpResponse doGet(String url, Map<String, String> headers, int timeOut) throws Exception {
HttpClient httpClient = getHttpClient(url, timeOut);
HttpGet request = new HttpGet(url);
if (headers != null) {
for (Map.Entry<String, String> e : headers.entrySet()) {
request.addHeader(e.getKey(), e.getValue());
}
}
return httpClient.execute(request);
}
public static HttpResponse doGet(String url) throws Exception {
HttpClient httpClient = getHttpClient(url);
HttpGet request = new HttpGet(url);
return httpClient.execute(request);
}
public static HttpClient getHttpClient(String url, int timeOut) {
HttpClient httpClient = wrapClient(url);
//请求超时
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeOut);
//读取超时
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeOut);
return httpClient;
}
public static HttpClient getHttpClient(String url) {
return getHttpClient(url, TIME_OUT);
}
public static String buildUrl(String host, String path, Map<String, String> querys)
throws UnsupportedEncodingException {
StringBuilder sbUrl = new StringBuilder();
sbUrl.append(host);
if (!StringUtils.isEmpty(path)) {
sbUrl.append(path);
}
if (null != querys) {
StringBuilder sbQuery = new StringBuilder();
for (Map.Entry<String, String> query : querys.entrySet()) {
if (0 < sbQuery.length()) {
sbQuery.append("&");
}
if (StringUtils.isEmpty(query.getKey()) && !StringUtils.isEmpty(query.getValue())) {
sbQuery.append(query.getValue());
}
if (!StringUtils.isEmpty(query.getKey())) {
sbQuery.append(query.getKey());
if (!StringUtils.isEmpty(query.getValue())) {
sbQuery.append("=");
sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
}
}
}
if (0 < sbQuery.length()) {
sbUrl.append("?").append(sbQuery);
}
}
return sbUrl.toString();
}
private static HttpClient wrapClient(String host) {
HttpClient httpClient = new DefaultHttpClient();
if (host.startsWith("https://")) {
sslClient(httpClient);
}
return httpClient;
}
@SuppressWarnings("deprecation")
private static void sslClient(HttpClient httpClient) {
try {
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] xcs, String str) {
}
@Override
public void checkServerTrusted(X509Certificate[] xcs, String str) {
}
};
ctx.init(null, new TrustManager[]{tm}, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
ClientConnectionManager ccm = httpClient.getConnectionManager();
SchemeRegistry registry = ccm.getSchemeRegistry();
registry.register(new Scheme("https", 443, ssf));
} catch (KeyManagementException ex) {
throw new RuntimeException(ex);
} catch (NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
}
如果提示: {“errcode”:43003,“errmsg”:“require https hints: [HEbdmzNre-.V!]”}
请参考:https://developers.weixin.qq.com/community/develop/doc/000ac876484488a0819a9b4bc51800?_at=1589144297228