注入工具:
@Autowired
@Qualifier("lvtuActivityMessageProducer")
private LvtuMessageProducer lvtuActivityMessageProducer;
<bean id="lvtuActivityMessageProducer" class="com.lvtu.csa.jms.LvtuMessageProducer">
<property name="template" ref="lvtuActivityJmsTemplate" />
<property name="destination" value="ActiveMQ.LVTU_APP" />
</bean>
生产者:
package com.lvtu.csa.jms;
import com.google.common.collect.Maps;
import com.lvmama.com.lvtu.common.jms.LvtuMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.scheduling.annotation.Async;
import java.util.Map;
/**
* Created by Administrator on 2016/10/12.
*/
public class LvtuMessageProducer {
private static final Logger LOGGER = LoggerFactory.getLogger(LvtuMessageProducer.class);
private static Map<String, String[]> topicMap = Maps.newHashMap();
static {
String[] activeMqLvtuSso = new String[] { "ActiveMQ.LVTU_SSO.client_sso"};
String[] activeMqLvtuService = new String[] { "ActiveMQ.LVTU_APP.client_service"};
String[] activeMqLvtuPush = new String[] { "ActiveMQ.LVTU_PUSH.client_push"};
topicMap.put("ActiveMQ.LVTU_SSO", activeMqLvtuSso);
topicMap.put("ActiveMQ.LVTU_APP", activeMqLvtuService);
topicMap.put("ActiveMQ.LVTU_PUSH", activeMqLvtuPush);
}
private JmsTemplate template;
private String destination;
/**
* 向一个 Queue 组发送JMS,达到 Topic 效果
*
* <pre>
* 从 Memcached 获取 JMS 控制参数,对消息进行 复制,移动(升级)操作
* 控制参数格式:[queue name / group name]=[operation 1.copy 2. move]|[JMS event type]|[new q destination]
* 对于 group name 的情况,operation 只能为 1
* 例子:
* 1. 把order所有消息复制到 ActiveMQ.ORDER.monitor,ActiveMQ.ORDER.monitor2 {ActiveMQ.ORDER=1|*|ActiveMQ.ORDER.monitor,ActiveMQ.ORDER.monitor2}
* </pre>
*
* @param msg
*/
@Async
public void sendMsg(LvtuMessage msg) {
LOGGER.info("JMS发送的消息 => " + msg.toString());
// 获取队列列表
String[] queues = topicMap.get(destination);
for (String queue : queues) {
template.convertAndSend(queue, msg);
}
}
public void setTemplate(JmsTemplate template) {
this.template = template;
}
public void setDestination(String destination) {
this.destination = destination;
}
}
应用接口:
/**
* 专题活动-通用注册接口* */
@Override
@ResponseBody
@RequestMapping("/api.com.user.sso.usual.activity.register/1.0.0")
public RopResponse<UserActivityRegisterResponse> usualActivityRegister(UserActivityRegisterRequest request) {
// 校验参数合法性
RopResponse<UserActivityRegisterResponse> responseBody = validate4UsualActivityRegister(request);
if (responseBody != null) {
return responseBody;
}
// 手机号码
String mobile = request.getMobile();
// 若是专题需要短信验证码,则进行短信验证码校验
if(request.isCheckMsgAuthCode()) {
// 短信验证码
String msgAuthCode = request.getMsgAuthCode();
// 校验短信验证码
responseBody = validateUsualMsgAuthCode(mobile, msgAuthCode);
if (responseBody != null) {
return responseBody;
}
String basicKey = MemcachedConstants.USUAL_CACHEKEY_CONSTANTS.MYLVMM_LVTU_ACTIVITY_AUTH_CODE_MSG_KEY.getCacheKey();
// 校验成功后,删除验证码
stringRedisTemplate.delete(basicKey + mobile.trim());
} else {
logger.info("Mobile: " + mobile + " 不检查短信验证码,直接进行注册操作!");
}
// 发送MQ消息
sendMQMsg(request);
String lvsessionid = request.getLvsessionid();
String timestamp = request.getStamptime();
RedisPersistentUtils.getInstance("USUAL_ACTIVITY_REGISTER").set(DateUtil.getDateByStr(timestamp, "yyyy-MM-dd HH:mm:ss.S").getTime() + lvsessionid, lvsessionid, 2*60*60);
return RopResponse.success(new UserActivityRegisterResponse());
}
private void sendMQMsg(UserActivityRegisterRequest request) {
LvtuMessage lvtuMessage = LvtuMessageFactory.newRegisterMsg(-1L);
lvtuMessage.setEventType("USUAL_ACTIVITY_REGISTER");
String data = null;
try {
data = madeData(request);
} catch (IOException e) {
logger.info(e);
return;
}
lvtuMessage.setAddition(data);
lvtuActivityMessageProducer.sendMsg(lvtuMessage);
}
消费者监听配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="byName">
<!-- consumer begin -->
<bean id="lvtuSSOConsumer" class="com.lvtu.csa.jms.LvtuMessageConsumer">
<property name="destName" value="ActiveMQ.LVTU_SSO.${lvtu_jms_node}" />
<property name="processerList">
<list>
<ref bean="lvtuDefaultAccessProcesser"/>
<ref bean="lvtuLoginProcesser" />
<ref bean="lvtuRegisterProcesser" />
</list>
</property>
</bean>
<bean id="lvtuActivityMessageConsumer" class="com.lvtu.csa.jms.LvtuMessageConsumer">
<property name="destName" value= "ActiveMQ.LVTU_APP.${lvtu_activity_jms_node}"/>
<property name="processerList">
<list>
<ref bean="usualActivityRegisterMessageProcesser" />
</list>
</property>
</bean>
<!-- consumer end -->
<!-- listener container begin -->
<bean id="lvtuLoginListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="lvtuJmsConnectionFactory" />
<property name="destination" ref="LVTU_SSO_TOPIC" />
<property name="messageListener" ref="lvtuLoginListener" />
<property name="taskExecutor" ref="clientSsoMsgConsumerThreadPool"/>
<!--
<property name="concurrentConsumers" value="5" />
<property name="maxConcurrentConsumers" value="20" />
-->
</bean>
<bean id="lvtuActivityListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="lvtuActivityJmsConnectionFactory" />
<property name="destination" ref="LVTU_ACTIVITY_TOPIC" />
<property name="messageListener" ref="lvtuActivityMessageListener" />
</bean>
<!-- listener container end -->
<!-- listener begin -->
<bean id="lvtuLoginListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="lvtuSSOConsumer" />
<property name="defaultListenerMethod" value="receive" />
</bean>
<bean id="lvtuActivityMessageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="lvtuActivityMessageConsumer" />
<property name="defaultListenerMethod" value="receive" />
</bean>
<!-- listener end -->
<!-- processer begin -->
<bean id="lvtuLoginProcesser" class="com.lvtu.csa.usso.mq.processer.LvtuLoginProcesser" />
<bean id="lvtuRegisterProcesser" class="com.lvtu.csa.usso.mq.processer.LvtuRegisterProcesser" />
<bean id="lvtuDefaultAccessProcesser" class="com.lvtu.csa.usso.mq.processer.LvtuDefaultAccessProcesser" />
<bean id="usualActivityRegisterMessageProcesser" class="com.lvtu.csa.usso.mq.processer.UsualActivityRegisterMessageProcesser"/>
<!-- processer end -->
<!-- 线程池 -->
<bean id="clientSsoMsgConsumerThreadPool" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心线程数 -->
<property name="corePoolSize" value="20" />
<!-- 最大线程数 -->
<property name="maxPoolSize" value="30" />
<!-- 队列最大长度 >=mainExecutor.maxSize -->
<property name="queueCapacity" value="2000" />
<!-- 线程池维护线程所允许的空闲时间 -->
<property name="keepAliveSeconds" value="300" />
<!-- 线程池对拒绝任务(无线程可用)的处理策略 -->
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
</property>
</bean>
</beans>
lvtu_activity_jms_server=tcp://localhost:61616?wireFormat.maxInactivityDuration=0
lvtu_activity_jms_node=client_service
jms_server=tcp://localhost:61616?wireFormat.maxInactivityDuration=0
jms_node=sso
#lvtu_jms_server=tcp://jms.lvmama.com:61616?wireFormat.maxInactivityDuration=0
lvtu_jms_server=tcp://localhost:61616?wireFormat.maxInactivityDuration=0
lvtu_jms_node=client_sso
#主站->无线接口Resource队列
lvtu_resource_jms_node=client_api
对应消费类:
package com.lvtu.csa.usso.mq.processer;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import com.lvmama.com.lvtu.common.jms.LvtuMessage;
import com.lvmama.comm.pet.po.user.UserUser;
import com.lvmama.comm.pet.service.mark.MarkCouponService;
import com.lvmama.comm.pet.service.mobile.MobileClientService;
import com.lvmama.comm.pet.service.sms.SmsRemoteService;
import com.lvmama.comm.pet.service.user.UserUserProxy;
import com.lvmama.comm.pet.vo.favor.CouponCheckParam;
import com.lvmama.comm.utils.UserUserUtil;
import com.lvtu.csa.context.model.user.request.UserMsgAuthCodeRequest;
import com.lvtu.csa.framework.utils.DateUtil;
import com.lvtu.csa.jms.LvtuMessageProcesser;
import com.lvtu.csa.usso.service.sso.UserMsgAuthCodeServiceImpl;
import com.lvtu.csa.usso.utils.RedisPersistentUtils;
import com.lvtu.service.api.rop.service.sso.FavourableActivityUserInfo;
public class UsualActivityRegisterMessageProcesser implements LvtuMessageProcesser {
private static final Logger logger = Logger.getLogger(UsualActivityRegisterMessageProcesser.class);
/** 错误信息存储到redis的目录 */
private static final String ERROR_MSG_DIR = "USUAL_ACTIVITY";
@Autowired
private MobileClientService mobileClientService;
@Autowired
private SmsRemoteService smsRemoteService;
@Autowired
private UserUserProxy userProxy;
@Autowired
private MarkCouponService markCouponService;
@Autowired
private UserMsgAuthCodeServiceImpl userMsgAuthCodeService;
@Override
public void process(LvtuMessage message) {
// 仅处理USUAL_ACTIVITY_REGISTER消息(专题活动注册消息)
if (!"USUAL_ACTIVITY_REGISTER".equals(message.getEventType())) {
return;
}
String data = message.getAddition();
FavourableActivityUserInfo userInfo = null;
try {
userInfo = parseData(data);
// 注册
UserUser user = register(userInfo);
userInfo.setUserId(user.getId());
userInfo.setUserNo(user.getUserNo());
userInfo.setRealPassword(user.getRealPass());
// 生成优惠券,并绑定到用户
generateCodeAndBindUser(user, userInfo);
// 发短信
sendMobileMsg(userInfo);
} catch (Exception e) {
logger.error(e);
// 异常的处理结果记录KEY key:COM:LVTU:USUAL_ACTIVITY:ERROR_KEYS
String errorKeys = RedisPersistentUtils.getInstance(ERROR_MSG_DIR).get("ERROR_KEYS");
String uuid = UUID.randomUUID().toString();
Map<String, Object> errResult = new HashMap<String, Object>();
if(null != userInfo) {
errResult.put("mobile", userInfo.getMobile());
errResult.put("userId", userInfo.getUserId());
}
errResult.put("errMsg", e.getMessage());
// 将错误信息记录到Redis中
RedisPersistentUtils.getInstance(ERROR_MSG_DIR).set(uuid, JSONObject.fromObject(errResult).toString());
// 将记录错误的KEY拼接起来
if (StringUtils.isBlank(errorKeys)) {
errorKeys = "COM:LVTU:" + ERROR_MSG_DIR + ":" + uuid;
} else {
errorKeys = errorKeys + ",COM:LVTU:" + ERROR_MSG_DIR + ":" + uuid;
}
// 将所有key作为数据存入到redis,并将此数据对应的key暴露出去
RedisPersistentUtils.getInstance(ERROR_MSG_DIR).set("ERROR_KEYS", errorKeys);
}
}
/**
* 发提醒短信
* @param userInfo
*/
@SuppressWarnings("unchecked")
private void sendMobileMsg(FavourableActivityUserInfo userInfo) {
// 解析短信相关参数信息Map<短信类型, 短信参数信息>
Map<String, Object> mobileMsgInfos = parseMobileMsgInfo(userInfo);
// 发送短信请求实体
UserMsgAuthCodeRequest request = new UserMsgAuthCodeRequest();
request.setStamptime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.S"));
request.setMobile(userInfo.getMobile());
request.setLvsessionid(UUID.randomUUID().toString());
// 若是用户为刚注册的,则发注册提醒短信
if(userInfo.isNewRegister()) {
// 注册短信相关参数
Map<String, Object> mobileMsgInfo = (Map<String, Object>) mobileMsgInfos.get("needRegistMobileMsg");
// 短信模板
request.setTemplateId((String)mobileMsgInfo.get("templateId"));
// 短信参数KEY
request.setMsgKeys((String[])mobileMsgInfo.get("msgKeys"));
// 短信参数值
request.setMsgValues((String[])mobileMsgInfo.get("msgValues"));
// 调用普通短信发送接口(专题使用,发送普通提醒短信)
userMsgAuthCodeService.sendActivityMsg(request);
} else {
// 不需要注册的相关短信参数
Map<String, Object> mobileMsgInfo = (Map<String, Object>) mobileMsgInfos.get("notNeedRegistMobileMsg");
// 短信模板
request.setTemplateId((String)mobileMsgInfo.get("templateId"));
// 短信参数KEY
request.setMsgKeys((String[])mobileMsgInfo.get("msgKeys"));
// 短信参数值
request.setMsgValues((String[])mobileMsgInfo.get("msgValues"));
// 调用普通短信发送接口(专题使用,发送普通提醒短信)
userMsgAuthCodeService.sendActivityMsg(request);
}
// 其他短信(此列表中的短信默认都全部发送)(保留逻辑,当前此结果为空,即不会执行此段逻辑)
List<Map<String, Object>> otherMsgInfoList = (List<Map<String, Object>>) mobileMsgInfos.get("otherMobileMsg");
for (int i = 0; i < otherMsgInfoList.size(); i++) {
Map<String, Object> mobileMsgInfo = otherMsgInfoList.get(i);
request.setStamptime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss.S"));
request.setTemplateId((String)mobileMsgInfo.get("templateId"));
request.setMsgKeys((String[])mobileMsgInfo.get("msgKeys"));
request.setMsgValues((String[])mobileMsgInfo.get("msgValues"));
userMsgAuthCodeService.sendActivityMsg(request);
}
}
/**
* 解析短信内容
* @param userInfo
* @return
*/
private Map<String, Object> parseMobileMsgInfo(FavourableActivityUserInfo userInfo) {
Map<String, Object> result = new HashMap<String, Object>();
// 短信模板
String[] templateIds = userInfo.getTemplateIds();
// 对应短信模板中的参数个数
Integer[] templateParamNums = userInfo.getTemplateParamNum();
// 短信参数KEY
String[] msgKeys = userInfo.getMsgKeys();
// 短信参数值
String[] msgValues = userInfo.getMsgValues();
// 第一个模板为新用户注册成功的短信模板(必输)
String needRegistTemplateId = templateIds[0];
Map<String, Object> msgInfoMap = new HashMap<String, Object>();
msgInfoMap.put("templateId", needRegistTemplateId);
// 根据短信模板对应的参数个数,从【短信参数KEY】和【短信参数值】中获取参数信息
Integer tempTemplateParamNum = templateParamNums[0];
// 定义与参数数量等长的数组
String[] tempMsgKeys = new String[tempTemplateParamNum];
String[] tempMsgValues = new String[tempTemplateParamNum];
// 遍历【短信参数KEY】和【短信参数值】获取对应的属性
for (int i = 0; i < tempTemplateParamNum; i++) {
tempMsgKeys[i] = msgKeys[i];
tempMsgValues[i] = msgValues[i];
}
msgInfoMap.put("msgKeys", tempMsgKeys);
msgInfoMap.put("msgValues", tempMsgValues);
result.put("needRegistMobileMsg", msgInfoMap);
// 第二个模板为非注册用户的短信模板(必输)
String notNeedRegistTemplateId = templateIds[1];
msgInfoMap = new HashMap<String, Object>();
msgInfoMap.put("templateId", notNeedRegistTemplateId);
// 第二个模板对应的参数个数
tempTemplateParamNum = templateParamNums[1];
// 定义与参数数量等长的数组
tempMsgKeys = new String[tempTemplateParamNum];
tempMsgValues = new String[tempTemplateParamNum];
// 遍历【短信参数KEY】和【短信参数值】从第一个模板的参数数量值起,两个模板中参数个数的和作为结束
for (int i = templateParamNums[0]; i < templateParamNums[0] + tempTemplateParamNum; i++) {
tempMsgKeys[i-templateParamNums[0]] = msgKeys[i];
tempMsgValues[i-templateParamNums[0]] = msgValues[i];
}
msgInfoMap.put("msgKeys", tempMsgKeys);
msgInfoMap.put("msgValues", tempMsgValues);
result.put("notNeedRegistMobileMsg", msgInfoMap);
// 其他短信模板(保留逻辑)
List<Map<String, Object>> otherMsgInfoList = new ArrayList<Map<String, Object>>();
// 模板对应参数开始取值位置
int startIndex = templateParamNums[0] + templateParamNums[1];
// 模板对应参数结束取值位置
int endIndex = templateParamNums[0] + templateParamNums[1];
// 模板从第三个开始取(前2个有特殊含义)
for (int i = 2; i < templateIds.length; i++) {
// 短信模板
String templateId = templateIds[i];
// 对应短信模板的参数个数
Integer templateParamNum = templateParamNums[i];
// 重置 模板对应参数取值下标位置
endIndex += templateParamNum;
// 定义与参数数量等长的数组
tempMsgKeys = new String[tempTemplateParamNum];
tempMsgValues = new String[tempTemplateParamNum];
// 遍历【短信参数KEY】和【短信参数值】,取对应的短信参数
for (int j = startIndex; j < endIndex; j++) {
tempMsgKeys[j-startIndex] = msgKeys[j];
tempMsgValues[j-startIndex] = msgValues[j];
}
msgInfoMap = new HashMap<String, Object>();
msgInfoMap.put("templateId", templateId);
msgInfoMap.put("msgKeys", tempMsgKeys);
msgInfoMap.put("msgValues", tempMsgValues);
otherMsgInfoList.add(msgInfoMap);
// 重置 模板对应参数开始取值位置
startIndex += templateParamNum;
}
result.put("otherMobileMsg", otherMsgInfoList);
return result;
}
/**
* 生成优惠券,并绑定到用户
* @param user
* @param userInfo
*/
private void generateCodeAndBindUser(UserUser user, FavourableActivityUserInfo userInfo) {
// 优惠券批次号
String couponIds = userInfo.getCouponIds();
if (StringUtils.isBlank(couponIds)) {
return;
}
// 根据逗号拆分优惠券批次号
String[] couponIdStrs = couponIds.trim().split(",");
// 统计相同批次号的个数
Map<Long, Integer> param = new HashMap<Long, Integer>();
for (String strCouponId : couponIdStrs) {
long couponId = Long.valueOf(strCouponId);
Integer value = param.get(couponId);
if(value == null) {
param.put(couponId, 1);
} else {
value = value + 1;
param.put(couponId, value);
}
}
// 标记优惠券是否有发送失败
boolean flag = false;
Iterator<Long> it = param.keySet().iterator();
while (it.hasNext()) {
Long couponId = it.next();
CouponCheckParam checkParam = new CouponCheckParam();
checkParam.setUserId(user.getId());
checkParam.setCouponId(couponId);
checkParam.setPlatform("MOBILE");
checkParam.setGenerateNo(Long.parseLong(String.valueOf(param.get(couponId))));
checkParam.setDeviceNo(userInfo.getUdid());
// 调用主站接口,完成优惠券的生成绑定操作
Map<String, String> result = markCouponService.generateCodeAndBindUser(checkParam);
if(result != null && !result.isEmpty()) {
flag = true;
logger.error("Coupon to fail, CouponId:" + couponId + " UserId:" + userInfo.getUserId() + " UserNo:" + user.getUserNo() + " Mobile:" + userInfo.getMobile());
}
}
// 若是发送优惠券存在失败,则将异常抛出去,统一最外层处理
if(flag) {
throw new RuntimeException("批量发送优惠券失败,或部分失败!!" + " UserId:" + userInfo.getUserId() + " UserNo:" + user.getUserNo() + " Mobile:" + userInfo.getMobile());
}
}
private UserUser register(FavourableActivityUserInfo userInfo) {
// 用户信息
UserUser user = null;
// 手机号
String mobile = userInfo.getMobile();
if (userProxy.isUserRegistrable(UserUserProxy.USER_IDENTITY_TYPE.MOBILE, mobile)) {
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("registerIp", userInfo.getIp());
parameters.put("mobileNumber", mobile);
parameters.put("channel", userInfo.getSecondChannel());
// 产生默认用户信息
user = userProxy.generateUsers(parameters);
// 将手机号码设置为已验证
user.setIsMobileChecked("Y");
// html代码 &解析 ;
String password = StringEscapeUtils.unescapeHtml(userInfo.getRealPassword());
// 设置明文密码
user.setRealPass(password);
// 设置加密密码
try {
user.setUserPassword(UserUserUtil.encodePassword(password));
} catch (NoSuchAlgorithmException e) {
logger.error(e.getMessage());
throw new RuntimeException("用户注册失败:" + e.getMessage());
}
// 注册用户
user = userProxy.register(user);
logger.info("注册成功:mobile: "+ mobile + " userId:" + user.getId() + " userNo:" + user.getUserNo());
userInfo.setNewRegister(true);
// 记录用户注册日志
saveMobilePeristanceLog(userInfo);
} else {
logger.info("账号已注册");
user = userProxy.getUsersByMobOrNameOrEmailOrCard(mobile);
userInfo.setNewRegister(false);
}
return user;
}
/**
* 记录用户注册日志
* @author wxliyong
* @date 2015-6-1 下午6:15:46
*/
@SuppressWarnings("deprecation")
private void saveMobilePeristanceLog(FavourableActivityUserInfo userInfo) {
Long appVersion = 0L;
if (!StringUtils.isEmpty(userInfo.getLvversion())) {
appVersion = Long.valueOf(userInfo.getLvversion().replaceAll("[.]", ""));
}
// 记录注册日志
mobileClientService.insertMobilePersistanceLog(userInfo.getFirstChannel(), userInfo.getSecondChannel(), userInfo.getUdid(), appVersion, userInfo.getUserId(), com.lvmama.comm.vo.Constant.SSO_EVENT.REGISTER.name(),userInfo.getOsVersion(), userInfo.getUserAgent());
}
private FavourableActivityUserInfo parseData(String data) throws Exception {
try {
return (FavourableActivityUserInfo) deserialize(data);
} catch (Exception e) {
logger.error(e.getMessage());
throw e;
}
}
/**
* 将序列化字符串反序列化
* @author wxliyong
* @throws IOException
* @date 2015-4-3 下午4:21:20
*/
private Object deserialize(String value) throws Exception {
ByteArrayInputStream byteArrayInputStream = null;
ObjectInputStream objectInputStream = null;
try {
String redStr = java.net.URLDecoder.decode(value, "UTF-8");
byteArrayInputStream = new ByteArrayInputStream(redStr.getBytes("ISO-8859-1"));
objectInputStream = new ObjectInputStream(byteArrayInputStream);
return objectInputStream.readObject();
} catch (Exception e) {
logger.error(e);
throw e;
} finally {
if(null != objectInputStream) {
objectInputStream.close();
}
if(null != byteArrayInputStream) {
byteArrayInputStream.close();
}
}
}
}