Authored by ken.hu

resource

... ... @@ -18,13 +18,6 @@
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.yohoufo.fore</groupId>
<artifactId>yohoufo-fore-dal</artifactId>
... ...
package com.yohoufo.resource.service.impl.cache;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.IntegerCodec;
import com.yoho.core.cache.LocalCache;
import com.yoho.core.cache.LocalCacheCallback;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.core.rest.client.hystrix.AsyncFuture;
import com.yoho.product.model.ShopsBo;
import com.yoho.product.request.BatchBaseRequest;
import com.yoho.service.model.resource.request.RecommendReqVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Created by oneway.wang on 2017/7/14.
*/
@Component
public class FocusCacheService {
private static final Logger LOGGER = LoggerFactory.getLogger(FocusCacheService.class);
private LocalCache localCache = new LocalCache();
@Autowired
private ServiceCaller serviceCaller;
private static final String REC_POS = "100047";
//存储JSON格式,存在转义问题,修改为String
@PostConstruct
private void init() {
localCache.init("focus Cache", ExpireTime.RESOURCES_LOCAL_CACHE, TimeUnit.HOURS, new LocalCacheCallback() {
@Override
public Object load(String key, Object oldValue) throws Exception {
RecommendReqVO recommendReqVO = new RecommendReqVO();
recommendReqVO.setUid(0);
recommendReqVO.setChannelId(Integer.parseInt(key));
recommendReqVO.setRec_pos(REC_POS);
JSONObject result = null;
result = serviceCaller.call("bigdata.getFocusShop", recommendReqVO, JSONObject.class);
if (result != null && result.getIntValue("code") == 200) {
return result;
}
return null;
}
});
}
public JSONObject getData(int cid){
JSONObject result = (JSONObject) localCache.get(String.valueOf(cid));
return result;
}
}
... ...
package com.yohoufo.resource.service.impl.resource;
import java.io.Serializable;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yoho.core.common.utils.URIBuilder;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.product.model.ShopActivityInfoBo;
import com.yoho.product.request.ShopsFocusRequest;
import com.yoho.service.model.resource.request.RecommendReqVO;
import com.yoho.service.model.resource.resource.FocusParsedResource;
import com.yohoufo.common.redis.NoSyncGracefulRedisTemplate;
import com.yohoufo.resource.helper.MakeUrlService;
import com.yohoufo.resource.service.IResourceParse;
import com.yohoufo.resource.service.Resource;
import com.yohoufo.resource.service.impl.cache.ExpireTime;
import com.yohoufo.resource.service.impl.cache.FocusCacheService;
import com.yohoufo.resource.util.JSONConvert;
import com.yohoufo.resource.util.ResourcesKeyBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.yohoufo.resource.helper.MakeUrlService;
import com.yohoufo.resource.service.IResourceParse;
import com.yohoufo.resource.service.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Created by wangwei on 2016/11/8.
* 处理焦点图数据
*/
@Service
public class FocusResourceParse implements IResourceParse{
public class FocusResourceParse implements IResourceParse {
@javax.annotation.Resource
private MakeUrlService makeUrlService;
private static final Logger logger = LoggerFactory.getLogger(FocusResourceParse.class);
private static final String REC_POS = "100047";
public static final String TEMPLATE_NAME="focus";
@javax.annotation.Resource(name="NoSyncGracefulRedisTemplate")
private NoSyncGracefulRedisTemplate resourcesRedisCache;
@Autowired
private MakeUrlService makeUrlService;
private ServiceCaller serviceCaller;
@Autowired
private FocusCacheService focusCacheService;
Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public Serializable parse(Resource resource) {
try {
return parseData(resource);
} catch (Exception e) {
logger.warn("Parse focus resource fail, resource code [{}] exception: {}", resource.getCode(), e);
return resource.getData();
public FocusParsedResource parse(Resource resource) {
int uid = resource.getUid()==null?0:resource.getUid();
String udid = resource.getUdid();
String clientType = resource.getClientType();
int channel;
if(resource.getGender()==null||resource.getGender().equals("1,3")){
channel = 1;
}else {
channel = 2;
}
FocusParsedResource parsedResource = new FocusParsedResource();
if(getRecommendSize(resource.getData().getJSONObject("data"))>0){
parsedResource.setOriginalTemplateId(resource.getOriginalId());
}
parsedResource.setTemplateId(resource.getId().toString());
parsedResource.setFocusType(resource.getData().getString("focus_type"));
parsedResource.setTemplateIntro(resource.getData().getString("template_intro"));
parsedResource.setData(parseData(resource.getData().getJSONObject("data"), resource.getClientType(),channel,uid,udid,clientType));
String isNewFocus = StringUtils.isEmpty(resource.getData().getString("isNewFocus"))?"":resource.getData().getString("isNewFocus");
parsedResource.setTemplateName(isNewFocus.equals("1")?"newFocus":"focus");
return parsedResource;
}
private List<FocusParsedResource.Data> parseData(JSONObject data, String clientTpe,int channel,int uid,String udid,String clientType) {
if (data == null) {
return Collections.emptyList();
}
List<FocusParsedResource.Data> parsedResourceDataList = new ArrayList<>();
JSONArray dataArray = JSONConvert.transform2JSONArray(data);
int recommendSize = getRecommendSize(data);
if(recommendSize>0) {
JSONArray shopArray = buildShopInfo(getRecommendShopIds(channel, uid, udid),channel);
for (Object obj : dataArray) {
if (obj instanceof JSONObject) {
JSONObject val = (JSONObject) obj;
FocusParsedResource.Data tmp = new FocusParsedResource.Data();
if (val.getInteger("isFocusRec") != null && val.getIntValue("isFocusRec") == 1 && shopArray.size() > 0) {
JSONObject shopInfo = (JSONObject) shopArray.get(0);
String src = shopInfo.getString("focusUrl");
String url;
//如果不能获取链接,参数拼接
if(StringUtils.isEmpty(shopInfo.getString("url"))){
url = makeShopUrl(shopInfo.getInteger("shopsId"), clientType, shopInfo.getString("shopName"), shopInfo.getString("shopTemplateType"), shopInfo.getString("isRedShop"));
}else{
url = shopInfo.getString("url");
}
private JSONObject parseData(Resource resource) {
if(StringUtils.isEmpty(src)||StringUtils.isEmpty(url)){
tmp.setSrc(val.getString("src"));
tmp.setUrl(makeUrlService.makeUrl(val.getJSONObject("url"), clientTpe));
tmp.setTitle(val.getString("alt"));
if (val.containsKey("bgColor")) {
tmp.setBgColor(val.getString("bgColor"));
}
}else{
//推荐店铺增加标识用于大数据统计
tmp.setIsFocusRec("1");
tmp.setSrc(src + "?imageView2/{mode}/w/{width}/h/{height}");
tmp.setUrl(url);
}
JSONObject returnJSON=new JSONObject();
//加入最基础的东西
returnJSON.put("template_id",resource.getId().toString());
returnJSON.put("template_name",this.TEMPLATE_NAME);
returnJSON.put("template_intro",resource.getData().getString("template_intro"));
logger.info("shopInfo:url={},src={}", url, shopInfo.getString("focusUrl"));
shopArray.remove(shopInfo);
} else {
tmp.setSrc(val.getString("src"));
tmp.setUrl(makeUrlService.makeUrl(val.getJSONObject("url"), clientTpe));
tmp.setTitle(val.getString("alt"));
if (val.containsKey("bgColor")) {
tmp.setBgColor(val.getString("bgColor"));
}
}
parsedResourceDataList.add(tmp);
}
}
}else{
for(Object obj : dataArray){
if (obj instanceof JSONObject) {
JSONObject val = (JSONObject) obj;
FocusParsedResource.Data tmp = new FocusParsedResource.Data();
tmp.setSrc(val.getString("src"));
tmp.setUrl(makeUrlService.makeUrl(val.getJSONObject("url"), clientTpe));
// 处理 data(充分利用原数据库中数据转成的JSONObject,只是遍历之后把URLObject替换成解析之后的数据)
JSONObject data = resource.getData().getJSONObject("data");
for (String index: data.keySet()) {
makeUrl(data.getJSONObject(index), resource.getClientType());
tmp.setTitle(val.getString("alt"));
if (val.containsKey("bgColor")) {
tmp.setBgColor(val.getString("bgColor"));
}
parsedResourceDataList.add(tmp);
}
}
}
returnJSON.put("data",data);
return returnJSON;
return parsedResourceDataList;
}
private void makeUrl(JSONObject jsonElement, String clientType) {
JSONObject jsonUrl = jsonElement.getJSONObject("url");
String strUrl = makeUrlService.makeUrl(jsonUrl, clientType);
jsonElement.put("url", strUrl);
private int getRecommendSize(JSONObject data) {
JSONArray dataArray = JSONConvert.transform2JSONArray(data);
int recommendSize = 0;
for(Object obj : dataArray){
if (obj instanceof JSONObject) {
JSONObject val = (JSONObject) obj;
//FocusParsedResource.Data tmp = new FocusParsedResource.Data();
if(val.getInteger("isFocusRec")!=null&&val.getIntValue("isFocusRec")==1){
recommendSize++;
}
}
}
return recommendSize;
}
private List<Integer> getRecommendShopIds(int cId,Integer uid,String udid){
if(uid==null){
uid = 0;
}
RecommendReqVO recommendReqVO = new RecommendReqVO();
recommendReqVO.setUid(uid);
recommendReqVO.setChannelId(cId);
recommendReqVO.setRec_pos(REC_POS);
recommendReqVO.setUdid(udid);
JSONObject result = null;
try{
logger.info("getFromBigData,uid={},cId={}",uid,cId);
//查询缓存
result = resourcesRedisCache.get(ResourcesKeyBuilder.generateFocusRecKey(REC_POS,uid,cId,udid),JSONObject.class);
if(result==null){
result = serviceCaller.call("bigdata.getFocusShop", recommendReqVO, JSONObject.class);
if (result == null || result.getIntValue("code") == 505) {
//大数据调用失败
result = getBackupCache(cId);
}else if (result != null && result.getIntValue("code") == 200) {
// 大数据调用成功,刷新一、二级缓存
resourcesRedisCache.setEx(ResourcesKeyBuilder.generateFocusRecKey(REC_POS,uid,cId,udid),result, ExpireTime.FOCUS_CACHE);
getBackupCache(cId);
}
}
}catch(Exception e){
//查询二级缓存
result = getBackupCache(cId);
}
return getArrayFromJSON(result);
}
//二级缓存
private JSONObject getBackupCache(int cid){
JSONObject result = focusCacheService.getData(cid);
logger.info("invoke backupCache,cid={},result={}",cid,result);
return result;
}
private List<Integer> getArrayFromJSON(JSONObject result){
List<Integer> shopRecommendArray = new ArrayList<>();
JSONArray jsonArray = new JSONArray();
jsonArray = JSON.parseArray(result.getString("data"));
//组织返回
shopRecommendArray = JSON.parseObject(jsonArray.toString(), List.class);
return shopRecommendArray;
}
//根据店铺id获取店铺url
private String makeShopUrl(Integer shopId,String clientType,String shopName,String shopTemplateType,String isRedShop){
URIBuilder uriBuilder = new URIBuilder("https://m.yohobuy.com");
JSONObject jsonUrl = new JSONObject();
// http://m.yohobuy.com?openby:yohobuy=
// {\"action\":\"go.shop\",\"params\":{\"shop_id\":\"%zd\", \"shop_template_type\":\"%@\", \"shop_name\":\"%@\", \"is_red_shop\":\"%zd\"}
uriBuilder.addParameter("shop_id",String.valueOf(shopId));
uriBuilder.addParameter("shop_name",shopName);
uriBuilder.addParameter("shop_template_type",shopTemplateType);
uriBuilder.addParameter("is_red_shop",isRedShop);
jsonUrl.put("action",makeUrlService.SHOP_ACTION);
String url = uriBuilder.build();
jsonUrl.put("url",url);
return makeUrlService.makeUrl(jsonUrl, clientType,"");
}
//查询店铺信息
private JSONArray buildShopInfo( List<Integer> shopIdList,int channel) {
JSONArray shopArray = resourcesRedisCache.get(ResourcesKeyBuilder.generateFocusShopInfoKey(shopIdList),JSONArray.class);
if(shopArray==null||shopArray.size()==0){
Integer appType = 0;//默认yoho app
ShopsFocusRequest shopRequest = new ShopsFocusRequest();
shopRequest.setShopIdList(shopIdList);
shopRequest.setChannel(channel);
shopRequest.setAppType(appType);//默认yoho app
ShopActivityInfoBo[] shopList = serviceCaller.asyncCall("product.queryShopFocusIntroList", shopRequest, ShopActivityInfoBo[].class).get(3);
shopArray = new JSONArray();
for(ShopActivityInfoBo shopsBo:shopList){
JSONObject jsonObject = new JSONObject();
jsonObject.put("isRedShop",shopsBo.getIsRedShop());
jsonObject.put("shopTemplateType",shopsBo.getShopTemplateType());
jsonObject.put("shopsId",shopsBo.getShopsId());
jsonObject.put("shopName",shopsBo.getShopName());
jsonObject.put("focusUrl",shopsBo.getFocusUrl());
//6.5添加的链接地址
jsonObject.put("url",shopsBo.getUrl());
shopArray.add(jsonObject);
}
resourcesRedisCache.setEx(ResourcesKeyBuilder.generateFocusShopInfoKey(shopIdList),shopArray,ExpireTime.FOCUS_CACHE);
}
return shopArray;
}
}
... ...
... ... @@ -44,6 +44,9 @@ public class HotSeriesResourceParse implements IResourceParse{
returnJSON.put("template_name",this.TEMPLATE_NAME);
returnJSON.put("template_intro",resource.getData().getString("template_intro"));
JSONObject moreUrl = resource.getData().getJSONObject("more_url");
returnJSON.put("more_url", makeMoreUrl(moreUrl,resource.getClientType()));
// 处理 data(充分利用原数据库中数据转成的JSONObject,只是遍历之后把URLObject替换成解析之后的数据)
JSONObject data = resource.getData().getJSONObject("data");
for (String index: data.keySet()) {
... ... @@ -58,4 +61,9 @@ public class HotSeriesResourceParse implements IResourceParse{
String strUrl = makeUrlService.makeUrl(jsonUrl, clientType);
jsonElement.put("url", strUrl);
}
private String makeMoreUrl(JSONObject jsonUrl, String clientType) {
String strUrl = makeUrlService.makeUrl(jsonUrl, clientType,"");
return strUrl;
}
}
... ...