靈悉的Android端開發(fā)中引入了ExoPlayer播放視頻揭绑,這部分功能的服務端是如何完成的他匪,且聽我一一道來邦蜜。
首先亥至,數(shù)據(jù)源于網(wǎng)絡姐扮,僅供學習交流。
其中數(shù)據(jù)接口來源于XX采集壤靶,再次強調(diào)僅供學習贮乳。
但是接口返回的數(shù)據(jù)為xml格式塘揣,需要解析以便使用宿崭。
其中pom.xml
中引入如下
<!-- httpClient start -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.5</version>
</dependency>
<!-- httpClient end-->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.1</version>
</dependency>
這個部分代碼直接放出,如下
IncVO.java
/**
* @author : happyc
* e-mail : bafs.jy@live.com
* time : 2019/04/20
* desc : 資源采集參數(shù)
* version : 1.0
*/
public class IncVO {
private String ac;
private String h;
private String pg;
private String page;
private String t;
private String type;
private String ids;
private String mid;
private String limit;
private String wd;
private String param;
public String getAc() {
return ac;
}
public void setAc(String ac) {
this.ac = ac;
}
public String getH() {
return h;
}
public void setH(String h) {
this.h = h;
}
public String getPg() {
return pg;
}
public void setPg(String pg) {
this.pg = pg;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public String getT() {
return t;
}
public void setT(String t) {
this.t = t;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getIds() {
return ids;
}
public void setIds(String ids) {
this.ids = ids;
}
public String getMid() {
return mid;
}
public void setMid(String mid) {
this.mid = mid;
}
public String getLimit() {
return limit;
}
public void setLimit(String limit) {
this.limit = limit;
}
public String getWd() {
return wd;
}
public void setWd(String wd) {
this.wd = wd;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
ResourceGatheringServiceImpl.java
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import me.happycao.lingxi.service.ResourceGatheringService;
import me.happycao.lingxi.util.RestUtil;
import me.happycao.lingxi.util.XmlUtil;
import me.happycao.lingxi.vo.IncVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @author : happyc
* e-mail : bafs.jy@live.com
* time : 2019/04/20
* desc : 資源采集
* version : 1.0
*/
@Service
public class ResourceGatheringServiceImpl implements ResourceGatheringService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Value("${inc-cnf.apiUrl}")
private String incUrl;
@Override
public JSONObject directApi(IncVO incVO) {
return getData(incVO, 1);
}
@Override
public JSONObject parseApi(IncVO incVO) {
return getData(incVO, 2);
}
private JSONObject getData(IncVO incVO, Integer flag) {
if (incVO == null) {
incVO = new IncVO();
incVO.setT("4");
incVO.setH("24");
incVO.setAc("videolist");
}
String content = RestUtil.doGet()
.url(incUrl)
.addUrlParam("ac", incVO.getAc())
.addUrlParam("h", incVO.getH())
.addUrlParam("pg", incVO.getPg())
.addUrlParam("page", incVO.getPage())
.addUrlParam("t", incVO.getT())
.addUrlParam("type", incVO.getType())
.addUrlParam("ids", incVO.getIds())
.addUrlParam("mid", incVO.getMid())
.addUrlParam("limit", incVO.getLimit())
.addUrlParam("wd", incVO.getWd())
.addUrlParam("param", incVO.getParam())
.exchange(String.class);
try {
if (flag == 1) {
return XmlUtil.xml2Json(content);
} else {
JSONObject jsonObject = XmlUtil.parseIncXml2Json(content);
String rssFlag = jsonObject.getString("flag");
if ("2".equals(rssFlag)) {
JSONArray videoArray = jsonObject.getJSONArray("video");
if (!videoArray.isEmpty()) {
StringBuilder ids = new StringBuilder();
for (int i = 0, size = videoArray.size(); i < size; i++) {
JSONObject video = videoArray.getJSONObject(i);
String id = video.getString("id");
ids.append(",").append(id);
}
ids.deleteCharAt(0);
incVO = new IncVO();
incVO.setAc("videolist");
incVO.setIds(ids.toString());
return getData(incVO, 2);
}
}
return jsonObject;
}
} catch (Exception e) {
return new JSONObject();
}
}
}
XmlUtil.java
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import java.util.Iterator;
import java.util.List;
/**
* @author : happyc
* e-mail : bafs.jy@live.com
* time : 2019/04/20
* desc : xml util
* version : 1.0
*/
public class XmlUtil {
/**
* 解析xml轉(zhuǎn)換為JSON對象
*
* @param xml xml字符串
* @return json字符串
*/
public static JSONObject parseIncXml2Json(String xml) throws Exception {
String[] listProperty = {"page", "pagecount", "pagesize", "recordcount"};
String[] videoProperty1 = {"id", "last", "tid", "name", "type", "pic",
"lang", "area", "year", "note", "actor", "director", "des"};
String[] videoProperty2 = {"dt", "note", "last", "name", "id", "type", "tid"};
JSONObject rssJson = new JSONObject();
JSONArray videoJsonArray = new JSONArray();
Document document = DocumentHelper.parseText(xml);
Element root = document.getRootElement();
Element list = root.element("list");
if (list != null) {
for (String property : listProperty) {
rssJson.put(property, list.attributeValue(property));
}
Iterator<Element> videoIterator = list.elementIterator("video");
while (videoIterator.hasNext()) {
Element video = videoIterator.next();
JSONObject videoJson = new JSONObject();
Element dt = video.element("dt");
boolean pass = false;
if (dt != null) {
rssJson.put("flag", 2);
for (String property : videoProperty2) {
videoJson.put(property, video.elementTextTrim(property));
}
}
Element dl = video.element("dl");
if (dl != null) {
rssJson.put("flag", 1);
for (String property : videoProperty1) {
if ("type".equals(property)) {
if ("倫理".equals(video.elementTextTrim(property))) {
pass = true;
}
}
videoJson.put(property, video.elementTextTrim(property));
}
Iterator<Element> ddIterator = dl.elementIterator("dd");
JSONArray sourceJsonArray = new JSONArray();
while (ddIterator.hasNext()) {
Element dd = ddIterator.next();
JSONObject sourceJson = new JSONObject();
String flag = dd.attributeValue("flag");
String stringValue = dd.getStringValue();
String[] split = stringValue.split("#");
JSONArray episodeJsonArray = new JSONArray();
for (String v : split) {
String[] s = v.split("\\$");
JSONObject episodeJson = new JSONObject();
episodeJson.put("title", s[0]);
episodeJson.put("url", s[1]);
episodeJsonArray.add(episodeJson);
}
sourceJson.put("flag", flag);
sourceJson.put("episode", episodeJsonArray);
sourceJsonArray.add(sourceJson);
}
videoJson.put("source", sourceJsonArray);
}
if (!pass) {
videoJsonArray.add(videoJson);
}
}
rssJson.put("video", videoJsonArray);
}
return rssJson;
}
/**
* 將xml轉(zhuǎn)換為JSON對象
*
* @param xml xml字符串
* @return json字符串
* @throws Exception 異常
*/
public static JSONObject xml2Json(String xml) throws Exception {
JSONObject jsonObject = new JSONObject();
Document document = DocumentHelper.parseText(xml);
Element root = document.getRootElement();
iterateNodes(root, jsonObject);
return jsonObject;
}
/**
* 遍歷元素
*
* @param node 元素
* @param json 將元素遍歷完成之后放的JSON對象
*/
private static void iterateNodes(Element node, JSONObject json) {
String nodeName = node.getName();
// 判斷已遍歷的JSON中是否已經(jīng)有了該元素的名稱
if (json.containsKey(nodeName)) {
// 該元素在同級下有多個處理
Object object = json.get(nodeName);
JSONArray array;
if (object instanceof JSONArray) {
array = (JSONArray) object;
} else {
array = new JSONArray();
array.add(object);
}
// 子元素
List<Element> listElement = node.elements();
if (listElement.isEmpty()) {
String nodeValue = node.getTextTrim();
// 有無Attribute
JSONObject jsonObject = new JSONObject();
Iterator<Attribute> attributeIterator = node.attributeIterator();
if (attributeIterator.hasNext()) {
Attribute attribute = attributeIterator.next();
jsonObject.put(attribute.getName(), attribute.getStringValue());
}
if (jsonObject.isEmpty()) {
array.add(nodeValue);
} else {
jsonObject.put(nodeName, nodeValue);
array.add(jsonObject);
}
json.put(nodeName, array);
return;
}
// 有子元素
JSONObject newJson = new JSONObject();
for (Element e : listElement) {
iterateNodes(e, newJson);
}
array.add(newJson);
json.put(nodeName, array);
return;
}
// 元素同級第一次遍歷
List<Element> listElement = node.elements();
if (listElement.isEmpty()) {
String nodeValue = node.getTextTrim();
// Attribute
JSONObject jsonObject = new JSONObject();
Iterator<Attribute> attributeIterator = node.attributeIterator();
if (attributeIterator.hasNext()) {
Attribute attribute = attributeIterator.next();
jsonObject.put(attribute.getName(), attribute.getStringValue());
}
if (jsonObject.isEmpty()) {
json.put(nodeName, nodeValue);
} else {
jsonObject.put(nodeName, nodeValue);
json.put(nodeName, jsonObject);
}
return;
}
// 有子節(jié)點知允,新建JSONObject來存儲
JSONObject object = new JSONObject();
for (Element e : listElement) {
iterateNodes(e, object);
}
json.put(nodeName, object);
// Attribute
Iterator<Attribute> attributeIterator = node.attributeIterator();
while (attributeIterator.hasNext()) {
Attribute next = attributeIterator.next();
json.put(next.getName(), next.getValue());
}
}
}
RestUtil.java
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author : happyc
* e-mail : bafs.jy@live.com
* time : 2019/04/20
* desc : http util
* version : 1.0
*/
public final class RestUtil {
private static Logger logger = LoggerFactory.getLogger(RestUtil.class);
private static final String CONTENT_TYPE = "Content-Type";
private static final String APPLICATION_JSON_UTF8 = "application/json;charset=UTF-8";
private static final String CHARSET = "UTF-8";
enum HttpMethod {
/**
* mode
*/
GET,
POST,
PUT,
DELETE
}
/**
* get請求
*/
public static Builder doGet() {
return new Builder(HttpMethod.GET);
}
/**
* post請求
*/
public static Builder doPost() {
return new Builder(HttpMethod.POST);
}
public static Builder doPut() {
return new Builder(HttpMethod.PUT);
}
public static Builder doDelete() {
return new Builder(HttpMethod.DELETE);
}
public static class Builder {
private HttpMethod method;
private boolean isJson;
private String url;
private Map<String, String> headers;
private Map<String, String> formParams;
private Map<String, List<String>> urlParams;
private String requestBody;
public Builder(HttpMethod method) {
this.method = method;
this.isJson = false;
this.url = "";
this.headers = new HashMap<>();
this.formParams = new HashMap<>();
this.urlParams = new HashMap<>();
this.requestBody = "";
}
/**
* 請求url
*/
public Builder url(String url) {
this.url = url;
return this;
}
/**
* json
*/
public Builder isJson() {
this.isJson = true;
return this;
}
/**
* 添加請求頭
*/
public Builder addHeader(String key, String value) {
if (!StringUtils.isEmpty(key) && !StringUtils.isEmpty(value)) {
this.headers.put(key, value);
}
return this;
}
/**
* 添加請求頭
*/
public Builder addHeaders(Map<String, String> headers) {
if (headers != null && !headers.isEmpty()) {
this.headers.putAll(headers);
}
return this;
}
/**
* 添加參數(shù)
*/
public Builder addParam(String key, String value) {
if (key == null || value == null) {
return this;
}
this.formParams.put(key, value);
return this;
}
/**
* 添加url參數(shù)
*/
public Builder addUrlParam(String key, String value) {
if (value == null) {
return this;
}
List<String> list = new ArrayList<>();
list.add(value);
this.urlParams.put(key, list);
return this;
}
/**
* 添加url參數(shù)
*/
public Builder addUrlParam(String key, List<String> values) {
if (values == null || values.size() == 0) {
return this;
}
this.urlParams.put(key, values);
return this;
}
/**
* 設置body參數(shù)
*/
public Builder setBody(String requestBody) {
this.requestBody = requestBody;
this.isJson = true;
return this;
}
/**
* 設置body參數(shù)
*/
public Builder setBody(Object requestBody) {
this.requestBody = JSONObject.toJSONString(requestBody);
this.isJson = true;
return this;
}
/**
* 構建請求頭
*/
private void buildHeader(HttpRequestBase httpRequest) {
if (!headers.isEmpty()) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
if (CONTENT_TYPE.equals(entry.getKey())) {
break;
}
httpRequest.addHeader(entry.getKey(), entry.getValue());
}
}
}
/**
* 構建HttpClient
*/
private CloseableHttpClient buildHttpClient() {
return HttpClients.createDefault();
}
/**
* 拼裝url參數(shù)
*/
private static String buildUrlParams(String url, Map<String, List<String>> params) {
try {
StringBuilder sb = new StringBuilder();
sb.append(url);
if (url.indexOf('&') > 0 || url.indexOf('?') > 0) {
sb.append("&");
} else {
sb.append("?");
}
for (Map.Entry<String, List<String>> urlParams : params.entrySet()) {
List<String> urlValues = urlParams.getValue();
for (String value : urlValues) {
// 對參數(shù)進行utf-8編碼
String urlValue = URLEncoder.encode(value, CHARSET);
sb.append(urlParams.getKey()).append("=").append(urlValue).append("&");
}
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return url;
}
/**
* 構建FormEntity
*/
private HttpEntity buildFormEntity() {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setContentType(ContentType.MULTIPART_FORM_DATA);
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
if (!formParams.isEmpty()) {
for (Map.Entry<String, String> param : this.formParams.entrySet()) {
builder.addPart(param.getKey(), new StringBody(param.getValue(), ContentType.MULTIPART_FORM_DATA));
}
}
return builder.build();
}
/**
* 構建StringEntity
*/
private StringEntity buildStringEntity() {
requestBody = requestBody == null ? "" : requestBody;
StringEntity stringEntity = new StringEntity(requestBody, CHARSET);
stringEntity.setContentType(APPLICATION_JSON_UTF8);
return stringEntity;
}
/**
* 發(fā)起請求
*/
public <T> T exchange(Class<T> bean) {
// url參數(shù)
if (!urlParams.isEmpty()) {
url = buildUrlParams(url, urlParams);
}
logger.debug("url is {}", url);
// 請求方式
switch (method) {
case GET:
return exchangeGet(bean);
case POST:
return exchangePost(bean);
case PUT:
return exchangePut(bean);
case DELETE:
return exchangeDelete(bean);
default:
return exchangeGet(bean);
}
}
private <T> T exchangePut(Class<T> bean) {
HttpPut httpPut = new HttpPut(url);
buildHeader(httpPut);
if (isJson) {
httpPut.setEntity(buildStringEntity());
} else {
httpPut.setEntity(buildFormEntity());
}
CloseableHttpClient httpClient = buildHttpClient();
CloseableHttpResponse response;
try {
response = httpClient.execute(httpPut);
} catch (IOException e) {
logger.error(e.getMessage(), e);
return null;
}
return parsingResponse(response, httpClient, bean);
}
private <T> T exchangeDelete(Class<T> bean) {
HttpDelete httpDelete = new HttpDelete(url);
buildHeader(httpDelete);
CloseableHttpClient httpClient = buildHttpClient();
CloseableHttpResponse response;
try {
response = httpClient.execute(httpDelete);
} catch (IOException e) {
logger.error(e.getMessage(), e);
return null;
}
return parsingResponse(response, httpClient, bean);
}
/**
* 執(zhí)行post請求
*/
private <T> T exchangePost(Class<T> bean) {
HttpPost httpPost = new HttpPost(url);
buildHeader(httpPost);
if (isJson) {
httpPost.setEntity(buildStringEntity());
} else {
httpPost.setEntity(buildFormEntity());
}
CloseableHttpClient httpClient = buildHttpClient();
CloseableHttpResponse response;
try {
response = httpClient.execute(httpPost);
} catch (IOException e) {
logger.error(e.getMessage(), e);
return null;
}
return parsingResponse(response, httpClient, bean);
}
/**
* 執(zhí)行get請求
*/
private <T> T exchangeGet(Class<T> bean) {
HttpGet httpGet = new HttpGet(url);
buildHeader(httpGet);
CloseableHttpClient httpClient = buildHttpClient();
CloseableHttpResponse response;
try {
response = httpClient.execute(httpGet);
} catch (IOException e) {
logger.error(e.getMessage(), e);
return null;
}
return parsingResponse(response, httpClient, bean);
}
/**
* 解析結果
*/
private <T> T parsingResponse(CloseableHttpResponse response, CloseableHttpClient httpClient, Class<T> bean) {
if (response == null) {
return null;
}
HttpEntity entity = response.getEntity();
if (entity == null) {
return null;
}
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
logger.error("Status Code {}", statusCode);
}
String body;
try {
body = EntityUtils.toString(entity, CHARSET);
if (body == null || body.length() == 0) {
return null;
}
if (bean.getName().equals(String.class.getName())) {
return (T) body;
} else {
return JSONObject.parseObject(body, bean);
}
} catch (IOException | JSONException e) {
logger.error(e.getMessage(), e);
return null;
} finally {
try {
response.close();
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}