如何实现基于http的json格式接口

import java.text.ParseException;
import java.text.SimpleDateFormat;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
.....

/**
 * 线下报文通用服务类,
 * <p>Description: 负责报文的通用服务,包括:输入输出报文(初始化报文和检测接收到的报文);检测报文签名 </p>
 * @date 2017年1月6日
 */
public class OfflinePacketsService {

	protected static final Logger logger = Logger.getLogger(OfflinePacketsService.class);
	
	/**
	 * 解析加密请求报文并验证报文头参数
	 * @param requestJson
	 * @return EncryptRequestPackets
	 * @throws BussinessExceptionNeedCatch 
	 */
	public static EncryptRequestPackets parseEncryptRequestPacketAndValidHead(String requestJson) throws BussinessExceptionNeedCatch {
		
		EncryptRequestPackets encryptRequestPackets = JSON.toJavaObject(JSON.parseObject(requestJson), EncryptRequestPackets.class);

		if (null == encryptRequestPackets || null == encryptRequestPackets.getHead() ) {
			throw new BussinessExceptionNeedCatch(ErrorCode.PARA_SP_CODE_XML_IS_NULL,
					GenerateMonitorDataFactory.buildErrorMonitorData(WarnBussinessTypeEnum.P_OTHER_SERVICE, null));
		}
		
		validRequestParameterHead(encryptRequestPackets.getHead());
		
		return encryptRequestPackets;
	}
	
	/** 验证请求报文头参数  **/
	private static void validRequestParameterHead(PacketsHead requestHead) throws BussinessExceptionNeedCatch {		

		if (requestHead instanceof RequestPacketsHead) {
			RequestPacketsHead head = (RequestPacketsHead) requestHead;
			if (StringUtils.isEmpty(head.getSpCode())) {
				throw new BussinessExceptionNeedCatch(ErrorCode.PARA_SP_CODE_XML_IS_NULL,
						GenerateMonitorDataFactory.buildErrorMonitorData(WarnBussinessTypeEnum.P_OTHER_SERVICE, null));
			}
			
			if (StringUtils.isEmpty(head.getBussinessCode()) || null == resolveBussinessType(head.getBussinessCode())) {
				throw new BussinessExceptionNeedCatch(ErrorCode.SYS_UNKNOW_BUSSINESS_CODE,
						GenerateMonitorDataFactory.buildErrorMonitorData(WarnBussinessTypeEnum.P_OTHER_SERVICE, null));
			}

			if (StringUtils.isEmpty(head.getSigned())) {
				throw new BussinessExceptionNeedCatch(ErrorCode.SYS_SIGNED_ERROR,
						GenerateMonitorDataFactory.buildErrorMonitorData(WarnBussinessTypeEnum.P_OTHER_SERVICE, null));
			}
			
			if (StringUtils.isEmpty(head.getVersion())) {
				throw new BussinessExceptionNeedCatch(ErrorCode.RESULT_SYSTEM_VERSION_ERROR,
						GenerateMonitorDataFactory.buildErrorMonitorData(WarnBussinessTypeEnum.P_OTHER_SERVICE, null));
			}
			
			if (StringUtils.isEmpty(head.getTimeStamp())) {
				throw new BussinessExceptionNeedCatch(ErrorCode.SYS_TIMESTAMP_IS_NULL,
						GenerateMonitorDataFactory.buildErrorMonitorData(WarnBussinessTypeEnum.P_OTHER_SERVICE, null));
			}
			
		} else {
			throw new BussinessExceptionNeedCatch(ErrorCode.PARA_FORMAT_MISS,
					GenerateMonitorDataFactory.buildErrorMonitorData(WarnBussinessTypeEnum.P_OTHER_SERVICE, null));			
		}		
	}

	/** 解析并检验请求报文 **/
	public static RequestPackets parseRequestPackets(RequestPacketsHead requestHead, String jsonString, 
			ScInterfaceDetailVo scInterfaceDetailVo) throws BussinessExceptionNeedCatch {
		
		String decryptBody = OfflinePacketsService.decryptBody(jsonString, scInterfaceDetailVo.getSecretKey());
		if (null == decryptBody) {
			throw new BussinessExceptionNeedCatch(ErrorCode.SYS_SECRET_KEY_ERROR,
					GenerateMonitorDataFactory.buildErrorMonitorData(
							WarnBussinessTypeEnum.OTM_SALE_REFUND_SETTLEMENT,
							"解密失败,body[" + jsonString + "]"));
		}
		
		BussinessEnum bussinessEnum = null;
		try {
			bussinessEnum = BussinessEnum.parseBussinessCodeToEnum(requestHead.getBussinessCode());
		} catch (ComponentExceptionNeedConvert e) {
			throw new BussinessExceptionNeedCatch(e.getErrorCode(),
					GenerateMonitorDataFactory.buildBussinessMonitorData(WarnBussinessTypeEnum.BASE_PACKAET_PARSED,
							requestHead.getSpCode(), null, requestHead.toString(), e.getMessage()));
		}
		
		RequestPacketsBody reqBody = null;
		switch (bussinessEnum) {
		case SALE_REFUND_SETTLEMENT:
			reqBody = JSON.toJavaObject(JSON.parseObject(decryptBody), RequestSaleAggregatePacketsBody.class);
			break;
		case USED_RATE_REPORT:
			reqBody = JSON.toJavaObject(JSON.parseObject(decryptBody), RequestUsedRateAggregatePacketsBody.class);
			break;
		case USED_DAY_REPORT:
			reqBody = JSON.toJavaObject(JSON.parseObject(decryptBody), RequestUsedDayAggregatePacketsBody.class);
			break;
		case OFFLINE_EXCHANGE_TICKET:
			reqBody = JSON.toJavaObject(JSON.parseObject(decryptBody), RequestOfflineExchangeTicketBody.class);
			break;
		case OFFLINE_UPDATE_APPLY_ORDER:
			reqBody = JSON.toJavaObject(JSON.parseObject(decryptBody), RequestOfflineUpdateApplyOrderBody.class);	
			break;
		case QUERY_APPLY_ORDER:
			reqBody = JSON.toJavaObject(JSON.parseObject(decryptBody), RequestQueryApplyOrderBody.class);
			break;
		case OFFLINE_UPDATE_GOODS:
			reqBody = JSON.toJavaObject(JSON.parseObject(decryptBody), RequestOfflineUpdateGoodsBody.class);
			break;
		default:
			throw new BussinessExceptionNeedCatch(ErrorCode.SYS_UNKNOW_BUSSINESS_CODE,
					GenerateMonitorDataFactory.buildBussinessMonitorData(WarnBussinessTypeEnum.BASE_PACKAET_PARSED,
							requestHead.getSpCode(), null, requestHead.toString(), "解析请求参数体失败"));
		}
		RequestPackets requestPackets = new RequestPackets();
		requestPackets.setHead(requestHead);
		requestPackets.setBody(reqBody);
		logger.debug("解密收到的request:" + requestPackets.toJSON());
		return requestPackets;
	}
	
	/** 
	 * 方法用途: 组装消息体消息头<br>
	 * 实现步骤: <br>
	 * @param requestPackets
	 * @param responseBody
	 * @param statucCode
	 * @param responsePacket   
	 * @throws ComponentExceptionNeedConvert 
	 */
	public static ResponsePackets generateReturnPackets(RequestPackets requestPackets, ResponsePacketsBody responseBody,
			IErrorCodeInterface statucCode) throws BussinessExceptionNeedCatch {
		ResponsePackets responsePacket = new ResponsePackets();
		ResponsePacketsHead responseHead = new ResponsePacketsHead();
		String spCode = null;
		String reqBodyJson = null;
		try {

			responseHead.setStatusCode(statucCode.getCode());
			responseHead.setMessage(statucCode.getMessage());
			
			reqBodyJson = requestPackets.toJSON();
			
			RequestPacketsHead requestHead = (RequestPacketsHead)requestPackets.getHead();
			responseHead.setVersion(requestHead.getVersion());		
			responseHead.setTimeStamp(requestHead.getTimeStamp());
			spCode = requestHead.getSpCode();
			
			responsePacket.setHead(responseHead);
			responsePacket.setBody(responseBody);

			responseHead.setSigned(OfflinePacketsService.generateSigned(responsePacket));
		} catch (ComponentExceptionNeedConvert e) {
			throw new BussinessExceptionNeedCatch(e.getErrorCode(),
					GenerateMonitorDataFactory.buildBussinessMonitorData(
							WarnBussinessTypeEnum.BASE_PACKAET_PARSED, spCode, null, reqBodyJson,
							e.getMessage()));
		} catch (Exception e) {
			throw new BussinessExceptionNeedCatch(ErrorCode.PARA_ERROR,
					GenerateMonitorDataFactory.buildBussinessMonitorData(
							WarnBussinessTypeEnum.BASE_PACKAET_PARSED, spCode, null, reqBodyJson,
							e.getMessage()));
		}
		return responsePacket;
	}	

    /**
     * 生成加密的报文<br>
     * 根据 respons报文做判断,如果该报文异常,则创建携带错误信息的new response
     * @param requestPackets
     * @param responsePacket
     * @param resultEx
     * @param scInterfaceDetailVo
     * @return
     * @throws BussinessExceptionNeedCatch
     */
	public static String generateEncryptResponsePackets(RequestPackets requestPackets, ResponsePackets responsePacket, 
			IErrorCodeInterface statucCode, String spCode, ScInterfaceDetailVo scInterfaceDetailVo ) throws BussinessExceptionNeedCatch {
		String strBodyJson = null;
		if (null == responsePacket || null == responsePacket.getHead() 
				|| StringUtils.isEmpty(((ResponsePacketsHead)responsePacket.getHead()).getStatusCode())){
			RequestPacketsHead requestHead = (RequestPacketsHead)requestPackets.getHead();
			
			if (responsePacket == null) responsePacket = new ResponsePackets();
			
			ResponsePacketsHead responseHead = new ResponsePacketsHead();
			responseHead.setStatusCode(statucCode.getCode());
			responseHead.setMessage(statucCode.getMessage());
			responseHead.setVersion(requestHead.getVersion());		
			responseHead.setTimeStamp(requestHead.getTimeStamp());
						
			responsePacket.setHead(responseHead);
			responsePacket.setBody(null);
			try {
				responseHead.setSigned(generateSigned(responsePacket));
			} catch (ComponentExceptionNeedConvert e) {
				throw new BussinessExceptionNeedCatch(e.getErrorCode(),
						GenerateMonitorDataFactory.buildBussinessMonitorData(
								WarnBussinessTypeEnum.BASE_PACKAET_PARSED, requestPackets.getHead().getSpCode(), null, "签名错误",
								e.getMessage()));
			}
		}

		logger.debug("待加密的 responsePacket:" + responsePacket.toJSON());
		
		//如果未取得sp,则无法加密,只能放弃加密
		if(scInterfaceDetailVo!=null ){
			EncryptResponsePackets encryptResponsePackets = new EncryptResponsePackets();  //加密报文返回
			encryptResponsePackets.setHead((ResponsePacketsHead) responsePacket.getHead());
			
			String secretKey = (scInterfaceDetailVo!=null ? scInterfaceDetailVo.getSecretKey():null);
			String encryptBody = encryptBody(strBodyJson, secretKey  );
			
			encryptResponsePackets.setBody(encryptBody);
			return encryptResponsePackets.toJSON();
		} else {
			//无法签名
			throw new BussinessExceptionNeedCatch(ErrorCode.PARA_SP_CODE_IS_ERROR,
					GenerateMonitorDataFactory.buildBussinessMonitorData(
							WarnBussinessTypeEnum.BASE_PACKAET_PARSED, spCode, null, null,
							"找不到业务运营商(" + spCode  + ")"));	
		}
	}

	/** 
	 * 生成报文签名 
	 * @return
	 * @throws ComponentExceptionNeedConvert
	 */
	public static String generateSigned(JsonFormatPackets packets) throws ComponentExceptionNeedConvert {
		if (null == packets) {
			throw new ComponentExceptionNeedConvert(ErrorCode.PARA_FORMAT_MISS, "Request format error! packets is null:"
					+ packets);
		}
		if (packets instanceof RequestPackets) {
			RequestPackets reqPackets =(RequestPackets)packets;
			RequestPacketsHead curHead = (RequestPacketsHead) reqPackets.getHead();	
			String strBody = reqPackets.getBody() == null ? "" : reqPackets.getBody().toJSON();
			return Base64.encode(Md5.encode(curHead.getVersion() + curHead.getTimeStamp() + curHead.getSpCode()
					+ curHead.getBussinessCode() + strBody.length()));
		} else if (packets instanceof ResponsePackets) {
			ResponsePackets respPackets =(ResponsePackets)packets;
			ResponsePacketsHead curHead = (ResponsePacketsHead) respPackets.getHead();
			String strBody = respPackets.getBody() == null ? "" : respPackets.getBody().toJSON();
			return Base64.encode(Md5.encode(curHead.getVersion() + curHead.getTimeStamp() + curHead.getStatusCode()
					+ strBody.length()));
		} else {
			throw new ComponentExceptionNeedConvert(ErrorCode.PARA_FORMAT_MISS, "Packets format error! packets:"
					+ packets);
		}
	}

	/**
	 * 验证签名
	 * @param packets 待验证的报文
	 * @throws ComponentExceptionNeedConvert
	 */
	public static void validateSinged(JsonFormatPackets packets) throws ComponentExceptionNeedConvert {

		String sign = generateSigned(packets);
		String packetsSign ;

		if (packets instanceof RequestPackets) {
			RequestPackets reqPackets =(RequestPackets)packets;
			RequestPacketsHead curHead = (RequestPacketsHead) reqPackets.getHead();	
			packetsSign = curHead.getSigned();
		} else if (packets instanceof ResponsePackets) {
			ResponsePackets respPackets =(ResponsePackets)packets;
			ResponsePacketsHead curHead = (ResponsePacketsHead) respPackets.getHead();
			packetsSign = curHead.getSigned();
		} else {
			throw new ComponentExceptionNeedConvert(ErrorCode.PARA_FORMAT_MISS, "Packets format error! packets:"
					+ packets);
		}
		
		if (!sign.equals(packetsSign)) {
			throw new ComponentExceptionNeedConvert(ErrorCode.SYS_SIGNED_ERROR, "request sign is: "
					+ packetsSign + ",  but body make sign is :  " + sign);
		}
	}

	/**
	 * 解密报文
	 * @param encodeBody
	 * @param secretKey
	 * @return
	 */
	public static String decryptBody(String encodeBody, String secretKey) {
		return DesSecret.decrypt(Base64.decode(encodeBody), secretKey);
	}

	/** 加密报文 **/
	public static String encryptBody(String body, String secretKey) {
		return Base64.encode(DesSecret.encrypt(body, secretKey));
	}
	
	private static BussinessEnum resolveBussinessType(String bussinessCode) {
		BussinessEnum bussinessTypeCode = null;
		try{
			if (null != bussinessCode && null != BussinessEnum.valueOf(bussinessCode) ){
				bussinessTypeCode =  BussinessEnum.valueOf(bussinessCode);
			}
		}catch(IllegalArgumentException e1){
			logger.error("can't get bussnisee type! BussinessEnum=" + bussinessCode);
		}
		return bussinessTypeCode;
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值