@@ -0,0 +1,20 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
import com.fasterxml.jackson.annotation.JsonProperty; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
/** 发票公共响应*/ | |||
@Setter | |||
@Getter | |||
public class BillCommonResponse extends AbstractIasResponse { | |||
/** 返回状态 true:成功;false:失败;*/ | |||
@JsonProperty(value = "Success") | |||
private String success; | |||
/** 返回描述*/ | |||
@JsonProperty(value = "Message") | |||
private String message; | |||
} |
@@ -0,0 +1,61 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.common.entity.BaseEntity; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
/** 发票开票记录 发票数据*/ | |||
@Setter | |||
@Getter | |||
public class BillInvoicesModel extends BaseEntity { | |||
/** 开票流水号 */ | |||
private String serialNo; | |||
/** 外部订单号 */ | |||
private String outOrderNo; | |||
/** 发票类型名称 */ | |||
private String invoiceTypeName; | |||
/** 商品名称 */ | |||
private String goodsName; | |||
/** 税率 */ | |||
private Double taxRate; | |||
/** 发票抬头 */ | |||
private String buyerName; | |||
/** 购方税号 */ | |||
private String buyerTaxNo; | |||
/** 含税价 */ | |||
private Double totalAmount; | |||
/** 商品价(不含税) */ | |||
private Double goodsAmount; | |||
/** 税额 */ | |||
private Double taxAmount; | |||
/** 发票代码 */ | |||
private String invoiceCode; | |||
/** 发票号码 */ | |||
private String invoiceNo; | |||
/** 开票日期 */ | |||
private String invoiceDate; | |||
/** 发票开具时间 yyyy-MM-dd HH:mm:ss格式 */ | |||
private String invoiceOpenTime; | |||
/** 发票板式文件下载链路 */ | |||
private String fileUrl; | |||
/** 状态 1:正常;-1:已红冲; */ | |||
private Integer status; | |||
/** 备注 */ | |||
private String remarks; | |||
} |
@@ -10,6 +10,7 @@ import javax.validation.constraints.NotBlank; | |||
import javax.validation.constraints.NotEmpty; | |||
import java.util.List; | |||
/** ETC产品合并开票请求*/ | |||
@Getter | |||
@Setter | |||
public class BillMergeInvoicingRequest extends AbstractIasRequest<BillMergeInvoicingResponse> { |
@@ -1,6 +1,10 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
public class BillMergeInvoicingResponse extends AbstractIasResponse { | |||
/** ETC产品合并开票响应*/ | |||
@Setter | |||
@Getter | |||
public class BillMergeInvoicingResponse extends BillCommonResponse { | |||
} |
@@ -8,16 +8,13 @@ import lombok.Setter; | |||
import javax.validation.constraints.NotBlank; | |||
/** 发票订单补推请求*/ | |||
@Getter | |||
@Setter | |||
public class BillOrderPushLogRequest extends AbstractIasRequest<BillOrderPushLogResponse> { | |||
protected BillOrderPushLogRequest() { | |||
super(IasServiceCmd.BILLORDERPUSH); | |||
} | |||
/** 推送ID*/ | |||
@JsonProperty(value = "Id") | |||
@NotBlank(message = "推送ID不能为空") | |||
private String id; | |||
/** 订单号*/ | |||
@JsonProperty(value = "OrderNo") | |||
@NotBlank(message = "订单号不能为空") | |||
@@ -66,11 +63,4 @@ public class BillOrderPushLogRequest extends AbstractIasRequest<BillOrderPushLog | |||
@JsonProperty(value = "InvoiceAmount") | |||
@NotBlank(message = "发票金额不能为空") | |||
private Integer invoiceAmount; | |||
@JsonProperty(value = "UserId") | |||
private String userId; | |||
@JsonProperty(value = "UserName") | |||
private String userName; | |||
@JsonProperty(value = "LoginSource") | |||
private String loginSource; | |||
} |
@@ -1,6 +1,18 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
import com.fasterxml.jackson.annotation.JsonProperty; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
public class BillOrderPushLogResponse extends AbstractIasResponse { | |||
/** 发票订单补推响应*/ | |||
@Setter | |||
@Getter | |||
public class BillOrderPushLogResponse extends BillCommonResponse { | |||
/** 返回码*/ | |||
@JsonProperty(value = "Rc") | |||
private Integer rc; | |||
/** 返回信息*/ | |||
@JsonProperty(value = "Rmsg") | |||
private String rmsg; | |||
} |
@@ -8,7 +8,7 @@ import lombok.Setter; | |||
import javax.validation.constraints.NotBlank; | |||
import javax.validation.constraints.NotNull; | |||
/** 发票抬头删除请求*/ | |||
@Getter | |||
@Setter | |||
public class BillRaiseDeleteRequest extends AbstractIasRequest<BillRaiseDeleteResponse> { | |||
@@ -24,9 +24,4 @@ public class BillRaiseDeleteRequest extends AbstractIasRequest<BillRaiseDeleteRe | |||
@JsonProperty(value = "UserMobile") | |||
@NotBlank(message = "手机号不能为空") | |||
private String userMobile; | |||
@JsonProperty(value = "OpenId") | |||
private String openId; | |||
@JsonProperty(value = "LoginSource") | |||
private String loginSource; | |||
} |
@@ -1,6 +1,4 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
public class BillRaiseDeleteResponse extends AbstractIasResponse { | |||
/** 发票抬头删除响应*/ | |||
public class BillRaiseDeleteResponse extends BillCommonResponse { | |||
} |
@@ -8,6 +8,7 @@ import lombok.Setter; | |||
import javax.validation.constraints.NotBlank; | |||
/** 发票抬头添加请求*/ | |||
@Getter | |||
@Setter | |||
public class BillRaiseInsertRequest extends AbstractIasRequest<BillRaiseInsertResponse> { | |||
@@ -64,9 +65,4 @@ public class BillRaiseInsertRequest extends AbstractIasRequest<BillRaiseInsertRe | |||
*/ | |||
@JsonProperty(value = "BankAccount") | |||
private String bankAccount; | |||
@JsonProperty(value = "OpenId") | |||
private String openId; | |||
@JsonProperty(value = "LoginSource") | |||
private String loginSource; | |||
} |
@@ -1,13 +1,13 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
import com.fasterxml.jackson.annotation.JsonProperty; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
/** 发票抬头添加响应*/ | |||
@Getter | |||
@Setter | |||
public class BillRaiseInsertResponse extends AbstractIasResponse { | |||
public class BillRaiseInsertResponse extends BillCommonResponse { | |||
/** 发票抬头ID*/ | |||
@JsonProperty(value = "Id") | |||
private String id; |
@@ -8,6 +8,7 @@ import lombok.Setter; | |||
import javax.validation.constraints.NotBlank; | |||
/* 发票抬头修改请求*/ | |||
@Getter | |||
@Setter | |||
public class BillRaiseUpdateRequest extends AbstractIasRequest<BillRaiseUpdateResponse> { | |||
@@ -64,9 +65,4 @@ public class BillRaiseUpdateRequest extends AbstractIasRequest<BillRaiseUpdateRe | |||
*/ | |||
@JsonProperty(value = "BankAccount") | |||
private String bankAccount; | |||
@JsonProperty(value = "OpenId") | |||
private String openId; | |||
@JsonProperty(value = "LoginSource") | |||
private String loginSource; | |||
} |
@@ -1,6 +1,10 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
public class BillRaiseUpdateResponse extends AbstractIasResponse { | |||
/** 发票抬头修改响应*/ | |||
@Setter | |||
@Getter | |||
public class BillRaiseUpdateResponse extends BillCommonResponse { | |||
} |
@@ -9,6 +9,7 @@ import lombok.Setter; | |||
import javax.validation.constraints.NotBlank; | |||
import javax.validation.constraints.NotNull; | |||
/** 发票开票记录请求*/ | |||
@Getter | |||
@Setter | |||
public class BillRecordRequest extends AbstractIasRequest<BillRecordResponse> { | |||
@@ -37,12 +38,4 @@ public class BillRecordRequest extends AbstractIasRequest<BillRecordResponse> { | |||
@JsonProperty(value = "UserMobile") | |||
@NotBlank(message = "手机号不能为空") | |||
private String userMobile; | |||
/** 操作来源*/ | |||
@JsonProperty(value = "OperationSource") | |||
private String operationSource; | |||
/** 操作用户ID*/ | |||
@JsonProperty(value = "OperationUserId") | |||
private String operationUserId; | |||
@JsonProperty(value = "OpenId") | |||
private String openId; | |||
} |
@@ -1,6 +1,16 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
import com.fasterxml.jackson.annotation.JsonProperty; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
public class BillRecordResponse extends AbstractIasResponse { | |||
import java.util.List; | |||
/** 发票开票记录响应*/ | |||
@Setter | |||
@Getter | |||
public class BillRecordResponse extends BillCommonResponse { | |||
/** 发票列表*/ | |||
@JsonProperty(value = "Invoices") | |||
List<BillInvoicesModel> invoices; | |||
} |
@@ -8,26 +8,20 @@ import lombok.Setter; | |||
import javax.validation.constraints.NotBlank; | |||
/** 发票红冲请求*/ | |||
@Getter | |||
@Setter | |||
public class BillReversalRequest extends AbstractIasRequest<BillReversalResponse> { | |||
protected BillReversalRequest() { | |||
super(IasServiceCmd.BILLREVERSAL); | |||
} | |||
/*** | |||
*开票流水号 | |||
*/ | |||
/** 开票流水号*/ | |||
@JsonProperty(value = "SerialNo") | |||
@NotBlank | |||
private String serialNo; | |||
/*** | |||
*开票流水号 | |||
*/ | |||
/** 红冲原因*/ | |||
@JsonProperty(value = "ReversalReason") | |||
@NotBlank | |||
private String reversalReason; | |||
@JsonProperty(value = "OpenId") | |||
private String openId; | |||
@JsonProperty(value = "LoginSource") | |||
private String loginSource; | |||
} |
@@ -1,6 +1,10 @@ | |||
package cn.com.taiji.core.model.comm.protocol.ias.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
import lombok.Getter; | |||
import lombok.Setter; | |||
public class BillReversalResponse extends AbstractIasResponse { | |||
/*发票红冲响应*/ | |||
@Setter | |||
@Getter | |||
public class BillReversalResponse extends BillCommonResponse { | |||
} |
@@ -0,0 +1,13 @@ | |||
package cn.com.taiji.ias.manager; | |||
import cn.com.taiji.core.manager.comm.AbstractCommServiceHandler; | |||
import cn.com.taiji.core.model.comm.protocol.SignServiceCommand; | |||
import cn.com.taiji.core.model.comm.protocol.ias.IasServiceType; | |||
public abstract class AbstractIasServiceHandler<C extends SignServiceCommand> | |||
extends AbstractCommServiceHandler<IasServiceType> { | |||
protected AbstractIasServiceHandler(IasServiceType serviceType) { | |||
super(serviceType); | |||
} | |||
} |
@@ -0,0 +1,20 @@ | |||
package cn.com.taiji.ias.manager.bill; | |||
import cn.com.taiji.core.model.comm.protocol.ias.bill.*; | |||
public interface BillBusinessManager { | |||
BillRaiseInsertResponse billRaiseInsert(BillRaiseInsertRequest req) throws Exception; | |||
BillRaiseDeleteResponse billRaiseDelete(BillRaiseDeleteRequest req) throws Exception; | |||
BillRaiseUpdateResponse billRaiseUpdate(BillRaiseUpdateRequest req) throws Exception; | |||
BillRecordResponse billRecord(BillRecordRequest req) throws Exception; | |||
BillReversalResponse billReversal(BillReversalRequest req) throws Exception; | |||
BillMergeInvoicingResponse billMergeInvoicing(BillMergeInvoicingRequest req) throws Exception; | |||
BillOrderPushLogResponse billOrderPush(BillOrderPushLogRequest req) throws Exception; | |||
} |
@@ -0,0 +1,107 @@ | |||
package cn.com.taiji.ias.manager.bill; | |||
import cn.com.taiji.common.manager.AbstractManager; | |||
import cn.com.taiji.common.pub.json.JsonTools; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasRequest; | |||
import cn.com.taiji.core.model.comm.protocol.ias.AbstractIasResponse; | |||
import cn.com.taiji.core.model.comm.protocol.ias.bill.*; | |||
import cn.com.taiji.core.model.comm.protocol.valid.GlyServiceError; | |||
import cn.com.taiji.ias.manager.bill.model.HtlRequestMethod; | |||
import cn.com.taiji.ias.manager.bill.model.InterfaceRequest; | |||
import cn.com.taiji.ias.manager.bill.model.InterfaceResponse; | |||
import cn.com.taiji.ias.tools.HttpClientUtil; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.beans.factory.annotation.Value; | |||
import org.springframework.stereotype.Service; | |||
import org.springframework.util.StringUtils; | |||
import java.io.IOException; | |||
@Service | |||
public class BillBusinessManagerImpl extends AbstractManager implements BillBusinessManager { | |||
Logger logger = LoggerFactory.getLogger(BillBusinessManagerImpl.class); | |||
@Autowired | |||
private HltService hltService; | |||
@Value("${hlt.url}") | |||
private String billUrl; | |||
@Value("${orderNotice.url}") | |||
private String orderNoticeUrl; | |||
/** 发票抬头添加*/ | |||
@Override | |||
public BillRaiseInsertResponse billRaiseInsert(BillRaiseInsertRequest request) throws Exception { | |||
return processBillRequest(HtlRequestMethod.BILLRAISEINSERT.getUri(), request, BillRaiseInsertResponse.class); | |||
} | |||
/** 发票抬头删除*/ | |||
@Override | |||
public BillRaiseDeleteResponse billRaiseDelete(BillRaiseDeleteRequest request) throws Exception { | |||
return processBillRequest(HtlRequestMethod.BILLRAISEDELETE.getUri(), request, BillRaiseDeleteResponse.class); | |||
} | |||
/** 发票抬头修改*/ | |||
@Override | |||
public BillRaiseUpdateResponse billRaiseUpdate(BillRaiseUpdateRequest req) throws Exception { | |||
return processBillRequest(HtlRequestMethod.BILLRAISEUPDATE.getUri(), req, BillRaiseUpdateResponse.class); | |||
} | |||
/** 发票开票记录*/ | |||
@Override | |||
public BillRecordResponse billRecord(BillRecordRequest req) throws Exception { | |||
return processBillRequest(HtlRequestMethod.BILLRECORD.getUri(), req, BillRecordResponse.class); | |||
} | |||
/** 发票红冲*/ | |||
@Override | |||
public BillReversalResponse billReversal(BillReversalRequest req) throws Exception { | |||
return processBillRequest(HtlRequestMethod.BILLREVERSAL.getUri(), req, BillReversalResponse.class); | |||
} | |||
/** ETC产品合并开票*/ | |||
@Override | |||
public BillMergeInvoicingResponse billMergeInvoicing(BillMergeInvoicingRequest req) throws Exception { | |||
return processBillRequest(HtlRequestMethod.BILLMERGEINVOICING.getUri(), req, BillMergeInvoicingResponse.class); | |||
} | |||
/** 发票订单补推*/ | |||
@Override | |||
public BillOrderPushLogResponse billOrderPush(BillOrderPushLogRequest req) throws Exception { | |||
logger.info("请求发票订单请求参数:{}", req); | |||
String response = HttpClientUtil.doPost(orderNoticeUrl, req.toJson(), null); | |||
logger.info("请求发票订单响应参数:{}", response); | |||
if (StringUtils.hasText(response)) { | |||
try { | |||
return JsonTools.json2Object(response, BillOrderPushLogResponse.class); | |||
} catch (IOException e) { | |||
logger.error("发票订单补推响应异常:{}", e.getMessage(), e); | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:发票订单补推响应异常!"); | |||
} | |||
} else { | |||
logger.error("发票订单补推响应异常"); | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:发票订单补推响应异常!"); | |||
} | |||
} | |||
/** 统一处理请求*/ | |||
private <T extends AbstractIasRequest<?>, R extends AbstractIasResponse> R processBillRequest(String requestUri, T request, Class<R> responseClass) throws Exception { | |||
logger.info("请求汇联通开始,请求参数:{}", request); | |||
InterfaceRequest interfaceRequest = new InterfaceRequest(); | |||
interfaceRequest.setBizContent(request.toJson()); | |||
InterfaceResponse response = hltService.postHlt(billUrl + requestUri, interfaceRequest); | |||
logger.info("请求汇联通结束,响应参数:{}", response); | |||
if (response.getStatusCode() == 200) { | |||
try { | |||
return JsonTools.json2Object(response.getBizContent(), responseClass); | |||
} catch (IOException e) { | |||
logger.error("汇联通响应异常:{}", e.getMessage(), e); | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:汇联通接口返回值格式错误!"); | |||
} | |||
} else { | |||
logger.error("汇联通响应异常:{}", response.getErrorMsg()); | |||
throw GlyServiceError.BUSINESS_VALIDATE_ERR.toHandleException("接口错误:汇联通响应异常!" + response.getErrorMsg()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
package cn.com.taiji.ias.manager.bill; | |||
import cn.com.taiji.common.manager.net.http.ServiceHandleException; | |||
import cn.com.taiji.common.model.file.FileProtocolSystemError; | |||
import cn.com.taiji.core.model.comm.protocol.AbstractSignTypeRequest; | |||
import cn.com.taiji.core.model.comm.protocol.AbstractSignTypeResponse; | |||
import cn.com.taiji.core.model.comm.protocol.SignJsonRequest; | |||
import cn.com.taiji.core.model.comm.protocol.ias.IasServiceCmd; | |||
import cn.com.taiji.core.model.comm.protocol.ias.IasServiceType; | |||
import cn.com.taiji.core.model.comm.protocol.ias.bill.*; | |||
import cn.com.taiji.ias.manager.AbstractIasServiceHandler; | |||
import com.zgglyun.common.model.AbstractHttpRequestInfo; | |||
import lombok.SneakyThrows; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.stereotype.Service; | |||
@Service | |||
public class BillServiceHandler extends AbstractIasServiceHandler<IasServiceCmd> { | |||
public BillServiceHandler() { | |||
super(IasServiceType.BILL); | |||
} | |||
@Autowired | |||
private BillBusinessManager billBusinessManager; | |||
@SneakyThrows | |||
@Override | |||
protected <T extends AbstractSignTypeRequest<?>> AbstractSignTypeResponse handleInternal(T request, SignJsonRequest jsonReq, AbstractHttpRequestInfo reqInfo) throws ServiceHandleException { | |||
IasServiceCmd cmd = IasServiceCmd.fromIfCode(jsonReq.getIfCode()); | |||
switch (cmd) { | |||
case BILLRAISEINSERT: | |||
return billBusinessManager.billRaiseInsert((BillRaiseInsertRequest) request); | |||
case BILLRAISEDELETE: | |||
return billBusinessManager.billRaiseDelete((BillRaiseDeleteRequest) request); | |||
case BILLRAISEUPDATE: | |||
return billBusinessManager.billRaiseUpdate((BillRaiseUpdateRequest) request); | |||
case BILLRECORD: | |||
return billBusinessManager.billRecord((BillRecordRequest) request); | |||
case BILLREVERSAL: | |||
return billBusinessManager.billReversal((BillReversalRequest) request); | |||
case BILLMERGEINVOICING: | |||
return billBusinessManager.billMergeInvoicing((BillMergeInvoicingRequest) request); | |||
case BILLORDERPUSH: | |||
return billBusinessManager.billOrderPush((BillOrderPushLogRequest) request); | |||
default: | |||
throw FileProtocolSystemError.NOT_SUPPORT.toHandleException(jsonReq.getIfCode()); | |||
} | |||
} | |||
} |
@@ -0,0 +1,17 @@ | |||
package cn.com.taiji.ias.manager.bill; | |||
import cn.com.taiji.ias.manager.bill.model.InterfaceRequest; | |||
import cn.com.taiji.ias.manager.bill.model.InterfaceResponse; | |||
import javax.servlet.http.HttpServletRequest; | |||
public interface HltService { | |||
/** | |||
* 请求到汇联通 | |||
* @param url url | |||
* @param interfaceRequest 入参 | |||
* @return {@link InterfaceResponse} | |||
* @throws Exception \ | |||
*/ | |||
InterfaceResponse postHlt(String url, InterfaceRequest interfaceRequest) throws Exception; | |||
} |
@@ -0,0 +1,55 @@ | |||
package cn.com.taiji.ias.manager.bill; | |||
import cn.com.taiji.common.pub.json.JsonTools; | |||
import cn.com.taiji.ias.manager.bill.model.HltRequest; | |||
import cn.com.taiji.ias.manager.bill.model.HltResponse; | |||
import cn.com.taiji.ias.manager.bill.model.InterfaceRequest; | |||
import cn.com.taiji.ias.manager.bill.model.InterfaceResponse; | |||
import cn.com.taiji.ias.tools.HttpClientUtil; | |||
import cn.com.taiji.ias.tools.NumberConvert; | |||
import cn.com.taiji.ias.tools.hlt.DesUtil; | |||
import org.springframework.beans.factory.annotation.Value; | |||
import org.springframework.stereotype.Service; | |||
import java.nio.charset.StandardCharsets; | |||
import java.time.LocalDateTime; | |||
import java.time.format.DateTimeFormatter; | |||
@Service | |||
public class HltServiceImpl implements HltService { | |||
@Value("${hlt.accessCode}") | |||
private String accessCode; | |||
@Value("${hlt.appId}") | |||
private String appId; | |||
@Value("${hlt.signCode}") | |||
private String signCode; | |||
@Override | |||
public InterfaceResponse postHlt(String url, InterfaceRequest interfaceRequest) throws Exception { | |||
final String requestId = appId + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS")) + (int) ((Math.random() * 9 + 1) * Math.pow(10, 5)); | |||
// 构建请求体 data进行des加密 | |||
HltRequest hltRequest = | |||
new HltRequest.Builder() | |||
.setRequestId(requestId) | |||
.setAccessCode(accessCode) | |||
.setMethod("POST") | |||
.setData(DesUtil.encode(interfaceRequest.getBizContent(), StandardCharsets.UTF_8, signCode)) | |||
.setSign(signCode).build(); | |||
HltResponse response; | |||
try { | |||
// 发送请求 | |||
String res = HttpClientUtil.doPost(url, hltRequest.toJson(), null); | |||
response = JsonTools.json2Object(res, HltResponse.class); | |||
// 对返回的数据进行解密 | |||
response.setData(DesUtil.decode(signCode, response.getData())); | |||
} catch (Exception e) { | |||
throw new Exception(e.getMessage()); | |||
} | |||
// 封装返回数据 | |||
InterfaceResponse interfaceResponse = new InterfaceResponse(); | |||
interfaceResponse.setErrorMsg(response.getRespMessage()); | |||
interfaceResponse.setBizContent(response.toJson()); | |||
interfaceResponse.setStatusCode(NumberConvert.toInt(response.getRespCode())); | |||
return interfaceResponse; | |||
} | |||
} |
@@ -0,0 +1,100 @@ | |||
package cn.com.taiji.ias.manager.bill.model; | |||
import cn.com.taiji.common.model.BaseModel; | |||
import cn.com.taiji.ias.tools.constant.HttpConstants; | |||
import cn.com.taiji.ias.tools.hlt.MD5SignUtil; | |||
/** | |||
* @projectName HltRequest | |||
* @description 汇联通请求体 | |||
*/ | |||
public class HltRequest extends BaseModel { | |||
/** | |||
* 接入码 | |||
*/ | |||
private String accessCode; | |||
/** | |||
* 请求id,每次传入的请求id不允许相同,长度不能超过50位 | |||
*/ | |||
private String requestId; | |||
/** | |||
* 请求业务接口名称 | |||
*/ | |||
private String method; | |||
/** | |||
* 业务数据,用signCode进行DES加密 | |||
*/ | |||
private String data; | |||
/** | |||
* 数据签名 | |||
*/ | |||
private String sign; | |||
private HltRequest(Builder builder) { | |||
this.accessCode = builder.accessCode; | |||
this.requestId = builder.requestId; | |||
this.method = builder.method; | |||
this.data = builder.data; | |||
this.sign = builder.sign; | |||
} | |||
public String getAccessCode() { | |||
return accessCode; | |||
} | |||
public String getRequestId() { | |||
return requestId; | |||
} | |||
public String getMethod() { | |||
return method; | |||
} | |||
public String getData() { | |||
return data; | |||
} | |||
public String getSign() { | |||
return sign; | |||
} | |||
public static class Builder { | |||
private String accessCode; | |||
private String requestId; | |||
private String method; | |||
private String data; | |||
private String sign; | |||
public Builder setAccessCode(String accessCode) { | |||
this.accessCode = accessCode; | |||
return this; | |||
} | |||
public Builder setRequestId(String requestId) { | |||
this.requestId = requestId; | |||
return this; | |||
} | |||
public Builder setMethod(String method) { | |||
this.method = method; | |||
return this; | |||
} | |||
public Builder setData(String data) { | |||
this.data = data; | |||
return this; | |||
} | |||
public Builder setSign(String signCode) { | |||
String str = (accessCode + signCode) + (requestId + signCode) + (method + signCode) + (data + signCode); | |||
MD5SignUtil.MD5Encode(str, HttpConstants.UTF_8, true); | |||
this.sign = MD5SignUtil.MD5Encode(str, HttpConstants.UTF_8, true); | |||
return this; | |||
} | |||
public HltRequest build() { | |||
return new HltRequest(this); | |||
} | |||
} | |||
} |
@@ -0,0 +1,70 @@ | |||
package cn.com.taiji.ias.manager.bill.model; | |||
import cn.com.taiji.common.model.BaseModel; | |||
/** | |||
* @projectName HltResponse | |||
* @description 汇联通返回实体 | |||
*/ | |||
public class HltResponse extends BaseModel { | |||
/** | |||
* 返回码,0000为成功 | |||
*/ | |||
private String respCode; | |||
/** | |||
* 返回信息 | |||
*/ | |||
private String respMessage; | |||
/** | |||
* 返回请求时的requestId | |||
*/ | |||
private String responseId; | |||
/** | |||
* 返回业务数据,用signCode进行DES加密 | |||
*/ | |||
private String data; | |||
/** | |||
* 返回数据签名 | |||
*/ | |||
private String sign; | |||
public String getRespCode() { | |||
return respCode; | |||
} | |||
public void setRespCode(String respCode) { | |||
this.respCode = respCode; | |||
} | |||
public String getRespMessage() { | |||
return respMessage; | |||
} | |||
public void setRespMessage(String respMessage) { | |||
this.respMessage = respMessage; | |||
} | |||
public String getResponseId() { | |||
return responseId; | |||
} | |||
public void setResponseId(String responseId) { | |||
this.responseId = responseId; | |||
} | |||
public String getData() { | |||
return data; | |||
} | |||
public void setData(String data) { | |||
this.data = data; | |||
} | |||
public String getSign() { | |||
return sign; | |||
} | |||
public void setSign(String sign) { | |||
this.sign = sign; | |||
} | |||
} |
@@ -0,0 +1,62 @@ | |||
package cn.com.taiji.ias.manager.bill.model; | |||
public enum HtlRequestMethod { | |||
BILLRAISEINSERT("发票抬头添加","qtzlinvoice/addInvoiceTitle",1), | |||
BILLRAISEDELETE("发票抬头删除","qtzlinvoice/deleteInvoiceTitle",2), | |||
BILLRAISEUPDATE("发票抬头修改","qtzlinvoice/editInvoiceTitle",3), | |||
BILLRECORD("发票开票记录","qtzlinvoice/queryInvoice",4), | |||
BILLREVERSAL("发票红冲","qtzlinvoice/invocieReversal",5), | |||
BILLMERGEINVOICING("ETC产品合并开票","qtzlinvoice/batchOpenEtcProductInvoice",6), | |||
BILLORDERPUSH("发票订单补推","",7), | |||
; | |||
private String value; | |||
private String uri; | |||
private int code; | |||
HtlRequestMethod(String value, String uri, int code) { | |||
this.value = value; | |||
this.uri = uri; | |||
this.code = code; | |||
} | |||
public static HtlRequestMethod getByCode(int code) { | |||
for (HtlRequestMethod method : HtlRequestMethod.values()) { | |||
if (method.getCode() == code) { | |||
return method; | |||
} | |||
} | |||
return null; | |||
} | |||
public static HtlRequestMethod getByValue(String value) { | |||
for (HtlRequestMethod method : HtlRequestMethod.values()) { | |||
if (method.getValue().equals(value)) { | |||
return method; | |||
} | |||
} | |||
return null; | |||
} | |||
public String getValue() { | |||
return value; | |||
} | |||
public void setValue(String value) { | |||
this.value = value; | |||
} | |||
public String getUri() { | |||
return uri; | |||
} | |||
public void setUri(String uri) { | |||
this.uri = uri; | |||
} | |||
public int getCode() { | |||
return code; | |||
} | |||
public void setCode(int code) { | |||
this.code = code; | |||
} | |||
} |
@@ -0,0 +1,28 @@ | |||
package cn.com.taiji.ias.manager.bill.model; | |||
import cn.com.taiji.common.model.BaseModel; | |||
import com.fasterxml.jackson.annotation.JsonProperty; | |||
import org.hibernate.validator.constraints.NotBlank; | |||
import javax.xml.bind.annotation.XmlRootElement; | |||
/** | |||
* @ClassName InterfaceRequest | |||
* @Description 公共请求参数实体 | |||
*/ | |||
@XmlRootElement(name = "interfaceRequest") | |||
public class InterfaceRequest extends BaseModel { | |||
@NotBlank(message = "业务参数数据不能为空") | |||
@JsonProperty("bizContent") | |||
private String bizContent; | |||
public String getBizContent() { | |||
return bizContent; | |||
} | |||
public void setBizContent(String bizContent) { | |||
this.bizContent = bizContent; | |||
} | |||
} |
@@ -0,0 +1,87 @@ | |||
package cn.com.taiji.ias.manager.bill.model; | |||
import cn.com.taiji.common.model.BaseModel; | |||
import java.io.Serializable; | |||
/** | |||
* @ClassName InterfaceResponse | |||
* @Description 公共出参实体 | |||
*/ | |||
public class InterfaceResponse extends BaseModel implements Serializable { | |||
/** | |||
* 调用结果 | |||
*/ | |||
private int statusCode; | |||
/** | |||
* 调用信息 | |||
*/ | |||
private String errorMsg; | |||
/** | |||
* 数据 | |||
*/ | |||
private String bizContent; | |||
/** | |||
* 签名 | |||
*/ | |||
private String sign; | |||
/** | |||
* 请求时的reqId | |||
*/ | |||
private String reqId; | |||
public int getStatusCode() { | |||
return statusCode; | |||
} | |||
public void setStatusCode(int statusCode) { | |||
this.statusCode = statusCode; | |||
} | |||
public String getErrorMsg() { | |||
return errorMsg; | |||
} | |||
public void setErrorMsg(String errorMsg) { | |||
this.errorMsg = errorMsg; | |||
} | |||
public String getBizContent() { | |||
return bizContent; | |||
} | |||
public void setBizContent(String bizContent) { | |||
this.bizContent = bizContent; | |||
} | |||
public String getSign() { | |||
return sign; | |||
} | |||
public void setSign(String sign) { | |||
this.sign = sign; | |||
} | |||
public String getReqId() { | |||
return reqId; | |||
} | |||
public void setReqId(String reqId) { | |||
this.reqId = reqId; | |||
} | |||
@Override | |||
public String toString() { | |||
return "InterfaceResponse{" + | |||
"statusCode=" + statusCode + | |||
", errorMsg='" + errorMsg + '\'' + | |||
", bizContent='" + bizContent + '\'' + | |||
", sign='" + sign + '\'' + | |||
", reqId='" + reqId + '\'' + | |||
'}'; | |||
} | |||
} |
@@ -0,0 +1,349 @@ | |||
package cn.com.taiji.ias.tools; | |||
import java.math.BigDecimal; | |||
/** | |||
*/ | |||
public class NumberConvert { | |||
/** | |||
* <将obj转换为string,如果obj为null则返回defaultVal> | |||
* | |||
* @param obj 需要转换为string的对象 | |||
* @param defaultVal 默认值 | |||
* @return obj转换为string | |||
*/ | |||
public static String toString(Object obj, String defaultVal) { | |||
return (obj != null) ? obj.toString() : defaultVal; | |||
} | |||
/** | |||
* <将obj转换为string,默认为空> | |||
* | |||
* @param obj 需要转换为string的对象 | |||
* @return 将对象转换为string的字符串 | |||
*/ | |||
public static String toString(Object obj) { | |||
return toString(obj, ""); | |||
} | |||
/** | |||
* <将对象转换为int> | |||
* | |||
* @param obj 需要转换为int的对象 | |||
* @param defaultVal 默认值 | |||
* @return obj转换成的int值 | |||
*/ | |||
public static Integer toInt(Object obj, Integer defaultVal) { | |||
try { | |||
return (obj != null) ? Integer.parseInt(toString(obj)) : defaultVal; | |||
} catch (Exception e) { | |||
return defaultVal; | |||
} | |||
} | |||
/** | |||
* <将对象转换为int> | |||
* | |||
* @param obj 需要转换为int的对象 | |||
* @param defaultVal 默认值 | |||
* @return obj转换成的int值 | |||
*/ | |||
public static Integer toInt(String obj, Integer defaultVal) { | |||
try { | |||
return (obj != null) ? Integer.parseInt(obj) : defaultVal; | |||
} catch (Exception e) { | |||
return defaultVal; | |||
} | |||
} | |||
/** | |||
* <将对象转换为int> | |||
* | |||
* @param obj 需要转换为int的对象 | |||
* @return obj转换成的int值 | |||
*/ | |||
public static Integer toInt(Object obj) { | |||
return toInt(obj, 0); | |||
} | |||
/** | |||
* <将对象转换为int> | |||
* | |||
* @param obj 需要转换为int的对象 | |||
* @return obj转换成的int值 | |||
*/ | |||
public static Integer toInt(String obj) { | |||
return toInt(obj, 0); | |||
} | |||
/** | |||
* <将对象转换为Integer> | |||
* | |||
* @param obj 需要转换为Integer的对象 | |||
* @return obj转换成的Integer值 | |||
*/ | |||
public static Integer toInteger(Object obj) { | |||
return toInt(obj, null); | |||
} | |||
/** | |||
* <将对象转换为Integer> | |||
* | |||
* @param obj 需要转换为Integer的对象 | |||
* @return obj转换成的Integer值 | |||
*/ | |||
public static Integer toInteger(String obj) { | |||
return toInt(obj, null); | |||
} | |||
/** | |||
* <将对象转换为int> | |||
* | |||
* @param obj 需要转换为int的对象 | |||
* @param defaultVal 默认值 | |||
* @return obj转换成的int值 | |||
*/ | |||
public static Float toFloat(Object obj, float defaultVal) { | |||
try { | |||
return Float.parseFloat(toString(obj)); | |||
} catch (Exception e) { | |||
return defaultVal; | |||
} | |||
} | |||
/** | |||
* <将对象转换为int> | |||
* | |||
* @param obj 需要转换为int的对象 | |||
* @param defaultVal 默认值 | |||
* @return obj转换成的int值 | |||
*/ | |||
public static Float toFloat(String obj, float defaultVal) { | |||
try { | |||
return Float.parseFloat(obj); | |||
} catch (Exception e) { | |||
return defaultVal; | |||
} | |||
} | |||
/** | |||
* <将对象转换为Float> | |||
* | |||
* @param obj 需要转换为Float的对象 | |||
* @return obj转换成的Float值 | |||
*/ | |||
public static Float toFloat(Object obj) { | |||
return toFloat(obj, 0); | |||
} | |||
/** | |||
* <将对象转换为Float> | |||
* | |||
* @param obj 需要转换为Float的对象 | |||
* @return obj转换成的Float值 | |||
*/ | |||
public static Float toFloat(String obj) { | |||
return toFloat(obj, 0); | |||
} | |||
/** | |||
* <将obj转换为long> | |||
* | |||
* @param obj 需要转换的对象 | |||
* @param defaultVal 默认值 | |||
* @return 如果obj为空则返回默认,不为空则返回转换后的long结果 | |||
*/ | |||
public static Long toLong(Object obj, long defaultVal) { | |||
try { | |||
return Long.parseLong(toString(obj)); | |||
} catch (Exception e) { | |||
return defaultVal; | |||
} | |||
} | |||
/** | |||
* <将obj转换为long> | |||
* | |||
* @param obj 需要转换的对象 | |||
* @param defaultVal 默认值 | |||
* @return 如果obj为空则返回默认,不为空则返回转换后的long结果 | |||
*/ | |||
public static Long toLong(String obj, long defaultVal) { | |||
try { | |||
return Long.parseLong(obj); | |||
} catch (Exception e) { | |||
return defaultVal; | |||
} | |||
} | |||
/** | |||
* <将obj转换为long> | |||
* | |||
* @param obj 需要转换的对象 | |||
* @return 如果obj为空则返回默认的0l,不为空则返回转换后的long结果 | |||
*/ | |||
public static Long toLong(Object obj) { | |||
return toLong(obj, 0L); | |||
} | |||
/** | |||
* <将obj转换为long> | |||
* | |||
* @param obj 需要转换的对象 | |||
* @return 如果obj为空则返回默认的0l,不为空则返回转换后的long结果 | |||
*/ | |||
public static Long toLong(String obj) { | |||
return toLong(obj, 0L); | |||
} | |||
/** | |||
* 将object转换为double类型,如果出错则返回 defaultVal | |||
* | |||
* @param obj 需要转换的对象 | |||
* @param defaultVal 默认值 | |||
* @return 转换后的结果 | |||
*/ | |||
public static Double toDouble(Object obj, Double defaultVal) { | |||
try { | |||
return Double.parseDouble(obj.toString()); | |||
} catch (Exception e) { | |||
return defaultVal; | |||
} | |||
} | |||
/** | |||
* 将object转换为double类型,如果出错则返回 defaultVal | |||
* | |||
* @param obj 需要转换的对象 | |||
* @param defaultVal 默认值 | |||
* @return 转换后的结果 | |||
*/ | |||
public static Double toDouble(String obj, Double defaultVal) { | |||
try { | |||
return Double.parseDouble(obj); | |||
} catch (Exception e) { | |||
return defaultVal; | |||
} | |||
} | |||
/** | |||
* 将object转换为double类型,如果出错则返回 0d | |||
* | |||
* @param obj 需要转换的对象 | |||
* @return 转换后的结果 | |||
*/ | |||
public static double toDouble(Object obj) { | |||
return toDouble(obj, 0d); | |||
} | |||
/** | |||
* 将object转换为double类型,如果出错则返回 0d | |||
* | |||
* @param obj 需要转换的对象 | |||
* @return 转换后的结果 | |||
*/ | |||
public static double toDouble(String obj) { | |||
return toDouble(obj, 0d); | |||
} | |||
/** | |||
* 保留小数位数 | |||
* | |||
* @param val 初始值 | |||
* @param scale 保留位数 | |||
* @return | |||
*/ | |||
public static double toDouble(String val, int scale) { | |||
BigDecimal bg = new BigDecimal(toDouble(val, 0d)); | |||
return bg.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); | |||
} | |||
/** | |||
* 保留小数位数 | |||
* | |||
* @param val 初始值 | |||
* @param scale 保留位数 | |||
* @return | |||
*/ | |||
public static double toDouble(Double val, int scale) { | |||
BigDecimal bg = new BigDecimal(toDouble(val, 0d)); | |||
return bg.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); | |||
} | |||
/** | |||
* 加法 | |||
* | |||
* @param d1 数字1 | |||
* @param d2 数字2 | |||
* @return d1+d2 | |||
* @tips (1)为保证小数计算精度不丢失,转换成{@link BigDecimal}后计算再转换成对应的double</br> | |||
* (2)d1、d2是一切不合法的字符或者null都被默认成0 | |||
*/ | |||
public static double add(Double d1, Double d2) { | |||
return BigDecimal.valueOf(toDouble(d1, 0d)) | |||
.add(BigDecimal.valueOf(toDouble(d2, 0d))).doubleValue(); | |||
} | |||
/** | |||
* 减法 | |||
* | |||
* @param d1 数字1 | |||
* @param d2 数字2 | |||
* @return d1-d2 | |||
* @tips (1)为保证小数计算精度不丢失,转换成{@link BigDecimal}后计算再转换成对应的double</br> | |||
* (2)d1、d2是一切不合法的字符或者null都被默认成0 | |||
*/ | |||
public static double subtract(Double d1, Double d2) { | |||
return BigDecimal.valueOf(toDouble(d1, 0d)) | |||
.subtract(BigDecimal.valueOf(toDouble(d2, 0d))).doubleValue(); | |||
} | |||
/** | |||
* 乘法 | |||
* | |||
* @param d1 数字1 | |||
* @param d2 数字2 | |||
* @return d1*d2 | |||
* @tips (1)为保证小数计算精度不丢失,转换成{@link BigDecimal}后计算再转换成对应的double</br> | |||
* (2)d1、d2是一切不合法的字符或者null都被默认成0 | |||
*/ | |||
public static double multiply(Double d1, Double d2) { | |||
return BigDecimal.valueOf(toDouble(d1, 0d)) | |||
.multiply(BigDecimal.valueOf(toDouble(d2, 0d))).doubleValue(); | |||
} | |||
/** | |||
* 除法,默认保留两位小数 | |||
* | |||
* @param d1 数字1 | |||
* @param d2 数字2要求不能为0、不能为空、非法的字符,一切不合法的字符或者null都被默认成0 | |||
* @return d1/d2 | |||
* @tips (1)为保证小数计算精度不丢失,转换成{@link BigDecimal}后计算再转换成对应的double</br> | |||
* (2)d1、d2是一切不合法的字符或者null都被默认成0 | |||
*/ | |||
public static double divide(Double d1, Double d2) { | |||
return divide(d1, d2, 2); | |||
} | |||
/** | |||
* 除法 | |||
* | |||
* @param d1 数字1 | |||
* @param d2 数字2要求不能为0、不能为空、非法的字符,一切不合法的字符或者null都被默认成0 | |||
* @param scale 保留小数位数 | |||
* @return d1/d2 | |||
* @tips (1)为保证小数计算精度不丢失,转换成{@link BigDecimal}后计算再转换成对应的double</br> | |||
* (2)d1、d2是一切不合法的字符或者null都被默认成0 | |||
*/ | |||
public static double divide(Double d1, Double d2, int scale) { | |||
final double zero = 0d; | |||
BigDecimal denominator = BigDecimal.valueOf(toDouble(d2, zero)); | |||
if (zero == denominator.doubleValue()) { | |||
throw new IllegalArgumentException("除数不能为0"); | |||
} | |||
// 避免出出现小数无线循环,所以加上精度控制 | |||
return BigDecimal.valueOf(toDouble(d1, zero)) | |||
.divide(denominator, scale, BigDecimal.ROUND_HALF_EVEN).doubleValue(); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
package cn.com.taiji.ias.tools.constant; | |||
import java.net.HttpURLConnection; | |||
/** | |||
* @projectName HttpConstants | |||
* @date 2023/5/6 10:34 | |||
* @description http | |||
*/ | |||
public class HttpConstants { | |||
/*** 调用方法 */ | |||
public static final String POST = "POST"; | |||
public static final String GET = "GET"; | |||
/*** 默认超时时间 单位毫秒 */ | |||
public static final int CONNECTION_TIME_OUT = 10000; | |||
public static final int READ_TIME_OUT = 10000; | |||
/*** 字符集 */ | |||
public static final String UTF_8 = "UTF-8"; | |||
public static final String GBK = "GBK"; | |||
/*** 请求头信息 */ | |||
public static final String CHARSET = "Charset"; | |||
public static final String CONTENT_TYPE = "Content-Type"; | |||
public static final String USER_AGENT = "User-Agent"; | |||
/*** Content-Type 类型 */ | |||
public static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded"; | |||
public static final String APPLICATION_JSON = "application/json"; | |||
public static final String MULTIPART_FORM_DATA = "multipart/form-data"; | |||
public static final String APPLICATION_XML = "application/xml"; | |||
public static final String APPLICATION_PDF = "application/pdf"; | |||
public static final String APPLICATION_HTML = "text/html"; | |||
public static final String APPLICATION_PLAIN = "text/plain"; | |||
public static final String APPLICATION_IMAGE = "image/*"; | |||
public static final String APPLICATION_DOC = "application/msword"; | |||
public static final String APPLICATION_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; | |||
/*** HTTP状态码 */ | |||
public static final int HTTP_OK = HttpURLConnection.HTTP_OK; | |||
public static final int HTTP_CREATED = HttpURLConnection.HTTP_CREATED; | |||
public static final int HTTP_NO_CONTENT = HttpURLConnection.HTTP_NO_CONTENT; | |||
public static final int HTTP_BAD_REQUEST = HttpURLConnection.HTTP_BAD_REQUEST; | |||
public static final int HTTP_UNAUTHORIZED = HttpURLConnection.HTTP_UNAUTHORIZED; | |||
public static final int HTTP_FORBIDDEN = HttpURLConnection.HTTP_FORBIDDEN; | |||
public static final int HTTP_NOT_FOUND = HttpURLConnection.HTTP_NOT_FOUND; | |||
public static final int HTTP_CONFLICT = HttpURLConnection.HTTP_CONFLICT; | |||
public static final int HTTP_INTERNAL_ERROR = HttpURLConnection.HTTP_INTERNAL_ERROR; | |||
public static final int HTTP_NOT_IMPLEMENTED = HttpURLConnection.HTTP_NOT_IMPLEMENTED; | |||
/** | |||
* 该类不能被实例化 | |||
*/ | |||
private HttpConstants() { | |||
throw new IllegalStateException("Utility class"); | |||
} | |||
} |
@@ -0,0 +1,270 @@ | |||
package cn.com.taiji.ias.tools.hlt; | |||
import org.apache.commons.codec.binary.Base64; | |||
import javax.crypto.Cipher; | |||
import javax.crypto.SecretKey; | |||
import javax.crypto.SecretKeyFactory; | |||
import javax.crypto.spec.DESKeySpec; | |||
import javax.crypto.spec.DESedeKeySpec; | |||
import javax.crypto.spec.IvParameterSpec; | |||
import java.nio.charset.Charset; | |||
import java.security.Key; | |||
import java.security.SecureRandom; | |||
import java.security.spec.AlgorithmParameterSpec; | |||
public class DesUtil { | |||
public static final String ALGORITHM_DES = "DES/CBC/PKCS5Padding"; | |||
private static final char[] SIXTY_FOUR_CHARS = | |||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray(); | |||
private static final int[] REVERSE_MAPPING = new int[123]; | |||
/** | |||
* DES算法,加密 | |||
* | |||
* @param data 待加密字符串 | |||
* @param key 加密私钥,长度不能够小于8位 | |||
* @return 加密后的字节数组,一般结合Base64编码使用 | |||
* 异常 | |||
*/ | |||
public static byte[] encode(String key, String data) throws Exception { | |||
return encode(key, data.getBytes()); | |||
} | |||
/** | |||
* DES算法,加密 | |||
* | |||
* @param data 待加密字符串 | |||
* @param key 加密私钥,长度不能够小于8位 | |||
* @return 加密后的字节数组,一般结合Base64编码使用 | |||
* 异常 | |||
*/ | |||
public static byte[] encode(String key, byte[] data) throws Exception { | |||
try { | |||
DESKeySpec dks = new DESKeySpec(key.getBytes()); | |||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); | |||
// key的长度不能够小于8位字节 | |||
Key secretKey = keyFactory.generateSecret(dks); | |||
Cipher cipher = Cipher.getInstance(ALGORITHM_DES); | |||
IvParameterSpec iv = new IvParameterSpec(key.getBytes()); | |||
AlgorithmParameterSpec paramSpec = iv; | |||
cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec); | |||
byte[] bytes = cipher.doFinal(data); | |||
return bytes; | |||
// return byte2HexStr(bytes); | |||
// return byte2hex(new String(bytes)); | |||
// return new String(new BASE64Encoder().encode(bytes)); | |||
// return new String(bytes); | |||
} catch (Exception e) { | |||
throw new Exception(e); | |||
} | |||
} | |||
/** | |||
* DES算法,解密 | |||
* | |||
* @param data 待解密字符串 | |||
* @param key 解密私钥,长度不能够小于8位 | |||
* @return 解密后的字节数组 | |||
* @throws Exception 异常 | |||
*/ | |||
public static byte[] decode(String key, byte[] data) throws Exception { | |||
try { | |||
// SecureRandom sr = new SecureRandom(); | |||
DESKeySpec dks = new DESKeySpec(key.getBytes()); | |||
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); | |||
// key的长度不能够小于8位字节 | |||
Key secretKey = keyFactory.generateSecret(dks); | |||
Cipher cipher = Cipher.getInstance(ALGORITHM_DES); | |||
IvParameterSpec iv = new IvParameterSpec(key.getBytes()); | |||
AlgorithmParameterSpec paramSpec = iv; | |||
cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec); | |||
return cipher.doFinal(data); | |||
} catch (Exception e) { | |||
throw new Exception(e); | |||
} | |||
} | |||
/** | |||
* 获取编码后的值 | |||
* | |||
* @param key | |||
* @param data | |||
* @return | |||
* @throws Exception | |||
*/ | |||
public static String decode(String key, String data) { | |||
byte[] datas; | |||
String value = null; | |||
try { | |||
datas = decode(key, Base64.decodeBase64(data)); | |||
value = new String(datas); | |||
} catch (Exception e) { | |||
value = ""; | |||
} | |||
return value; | |||
} | |||
public static String byte2HexStr(byte[] b) { | |||
String hs = ""; | |||
String stmp = ""; | |||
for (int n = 0; n < b.length; n++) { | |||
stmp = (Integer.toHexString(b[n] & 0XFF)); | |||
if (stmp.length() == 1) | |||
hs = hs + "0" + stmp; | |||
else | |||
hs = hs + stmp; | |||
// if (n<b.length-1) hs=hs+":"; | |||
} | |||
return hs; | |||
} | |||
public static String triDesEncrypt(String input, String desKey, String desIv) { | |||
Cipher cipher = null; | |||
try { | |||
SecureRandom sr = new SecureRandom(); | |||
DESedeKeySpec dks = new DESedeKeySpec(desKey.getBytes("UTF-8")); | |||
SecretKeyFactory keyFactory = SecretKeyFactory | |||
.getInstance("DESede"); | |||
Key key = keyFactory.generateSecret(dks); | |||
IvParameterSpec iv = new IvParameterSpec(desIv.getBytes("UTF-8")); | |||
cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); | |||
cipher.init(1, key, iv, sr); | |||
byte[] array = cipher.doFinal(input.getBytes("UTF-8")); | |||
return Base64.encodeBase64String(array); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
return null; | |||
} | |||
public static String triDesDecrypt(String input, String desKey, String desIv) { | |||
Cipher cipher = null; | |||
try { | |||
SecureRandom sr = new SecureRandom(); | |||
DESedeKeySpec dks = new DESedeKeySpec(desKey.getBytes("UTF-8")); | |||
SecretKeyFactory keyFactory = SecretKeyFactory | |||
.getInstance("DESede"); | |||
SecretKey key = keyFactory.generateSecret(dks); | |||
IvParameterSpec iv = new IvParameterSpec(desIv.getBytes("UTF-8")); | |||
cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); | |||
cipher.init(2, key, iv, sr); | |||
byte[] decoded = Base64.decodeBase64(input); | |||
byte[] array = cipher.doFinal(decoded); | |||
return new String(array, "UTF-8"); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
return null; | |||
} | |||
public static void main(String[] args) throws Exception { | |||
//加密 | |||
String str = "123456"; | |||
System.out.println("encode==" + encode(str, Charset.forName("UTF-8"), "12345678")); | |||
//解密 | |||
// String desStr = "zcISRG4/VDEXOs/Szk22Zb0E4Bjr37ny6Q9RIGV37kfL/F7UEOheMniiAHt6xunrMRJohxzYEOf3 | |||
// \ny7bjEWw7Cdbq22ffE21MsPND4YypAAduWx+2COznq/c+da75y4Pi+yQGZ8N9WbDw6bqVmifFob9I\nO1frRb65PzBotD1pEAcya/2/xolXJQ | |||
// =="; | |||
// String desStr="7CCNZdOXmElGXierqpifnO5uS6Zz8Tdp8q00qS7OqPWha | |||
// /iUtoxnblilfMgN4qjyajkr23bLHZiRAFSbPpGwpfimBtDQ5QIguCFnxdZCXZElrfCI5dYw0ji2Imgteqmyt3U9AMInmJogIvWX8vbR2K87Y977pAFCNx/Xe7BjiKH1/lZWGvF4wySNKXl5qmlcxntLhaEVwHH4WxW2D++yijQAHAPuqPGFxvRJjpdyHhhAn8Uck9M/nqH+hT2/9AEDuxCFAjqFKF5CjAYeovIlvN4jopxfYYmwEnhAVqCD65YhuYPkuVbo7ZhSxb8IHoBmaqRuNjFTYRf3UKHAWBTwvZHfuYxHas5O9OIoCm/sEiQcq4SM/XMR1FzhXxlIl4DfUnIodZsNE3A9QfSXNyY40KNvumkGO5GJAIAgqwVDgUC03qQeXBTY2pDCF8ml5QMcw++z79JCJbJa6db0ySIe/CJUdKL4BRWKLE2sMPsXn1UhEDlpwf39fL9IWzZWscHg2qjL1QwkgVKJNfqRiST7sfmaYHor4z/n5JlExvRvBcAidy9aGaJ8FdxKcev2zSraQRkvFHQyA+Yf06ZmQJOAHOq156aHb8YRf7fOwx1bYwhMuCXy8sF9HOaa8s5l+zEyT1v51VmNoqSHAYsBErfdmYXOp+/6W+cY/KoDg0SKedDjG5Gsmi2LLoebN5UwRK/wh9RYKIUYj9S+aurGWUrsFJDINNoNRhmhrB06Ao1Gr+NwedQ8JR2uJaqHlB7oUoDetjifBBYJNVeHDQsmcsaJy1EP1qD8MbMS+PaS8chFxiKAJ1fX1lb+P7IlZtGvsq6zjEI5LLrs2y78yKJrPTA7PhVNpPoKQ7LtP4h9XcKT1DYopELuK6XIS35Gps2ZmS1pO4zXB/899gpRHd3Gj9VeKdYJFF+o/hwt2hQFVe1415Txh7X5QgxmJQ/93LkwlGoNjqD5+oq1JyNbe3qq4iFFOuOld8AiHxLu6EeWzjMW3uRovEY8H1MQ84nEn5Hls7HKHz8O7DQ55g7s8TTLhl0X0Md7MorWnBNMjHJjcwaMpmsgPVdYE/EhFbRjfw+8Ld3hYuk+HvmJouDgvlQvUTA+UYoaLm3NHJcyKTJiAiWYJPB+v7OEamUiPTKu4J6JSxMqmYG2vfi3DupxbvFabIsh01Wv6oS9nMV7rjZAHWX5imVcmiIIBI/D/0xyUjB4JN3v7pyhBGb2jSJwQ8strd9AD2xS+s38/miFqtliFalXzy2J2SAxZw5BX9UjpU/VgiANeGx43B4kRvXizcrQWZYs4utrG/MXhJ3v9xiLmnzKDt1SiuDp0UirLtUgy+nhkmPSDwAfhWUp3tOD0vbPCMOAqfUzPDHhw9OMOJIojcoCItoH8dxtZFC4kQ21ib9adtyz4BWZHbq71eqF9mDsnomTp4bpAyoQLHSH44Yg8PwSpUe9hhHbDXDMTKb4Cx8V+KBW8gYqxzX4rvIuY4Nl7HFCs9A3/CvGsFnxaLAYYl7pHC5Coy+7I1fi50UA60cFn2VVdDxxKAG3GqBDuRb1Po+1l64HTGmNrYi6zTUdMquEb/s8xPgiZW4ThSSyDVBr98e9M7KTkOntqsxheHyqvbNx3O/QcUcSBHXmxbtHMx7TYyaGs3l9bvvX8sD6dbfH44zspngMs9O07E6VHMONKVnHWIY8axSeuT2S3OFEI8IsO743vYfH4h9f9YAL8DitpGC+LveQWFU2G4n/AlzhuCouNU90o78aDJiVgQepyWi2ZYZizj21iZY/qdeU6TlVu7qyOfneIWez4UtM3PkLGqN6LN14mIm3XDch3KMI3hoAHynnGXagXLG34DZ3AxJsfyorJtQOv4Ucc5t+85jBDIrirUnOPbnJdQcpIuPOH2tb+toXJUCALijfDA+J+jpHbDZ2O8l129CTlusuQdkKGg1olNSczwcFsmfD42JZf6OsRyMc7LJ3UtMbuZcqj0ToEP7REzvDS29AdJ0ZEo2eff8ebc9Hw4zlwVIH"; | |||
// String desStr = "8pWASDb/nZ5TLkM4HJgA9eUgK2viTUSIKOrU2IRFVyTdHERw6tOJhjXoT/SfUuhGsJWaysZsEEFJ | |||
// +0xLXwkVQ4aBbCycgWNML2dQdCaCEE4LT5zyV6NyKM5J/6aOCq0ewGk4Uoz6TxbhyrhEzNexWFDqcbRTkL4BxLc7mODw0cWLFRm | |||
// /EBufJGwtCso4IgFH6hZf+iRILqW96noIQlZpiJy0VQ7 | |||
// /mJ5EXrM7hIMk8Y2BHnDMbnqXwh5NFbKltHUw2zonYjeBVi77Jaxw5whzgGkQu2pvEVnxXN3Vubi0ivXi2UijmBYX9VI | |||
// +dCIzpSqATERsuzB608xRIYuVlpqM2aatk+1hMotULg/mEKV99ZArB2cawWV4v2ZoMcHjHbzBhxOuz70xs | |||
// /vgiN3pBAWuvXpm3FzF4Icd9ovVnj+2Rl1MnVV1rEW9FG+gD1dxKan0kmGc/4YKDZiy17Erh7BuicBckuXqeCzybPIXkeX87JFDOC93rm1 | |||
// +AAD9AxjShd6TE4Y+RuwI33yfwmrU5DH5Ky4vX3TlxMdWL0YVTzWfOx5Sif0OZGsZdg4PKwrMgPP2GypHSXOJEJBWFciMl3/4phTdf | |||
// /xxBneUqlFkgM/ZUTqhTkbsVOTfWAlnRHrUzf0Cq6t0c/2fA5o2cMxalNsR36kAvYlp2PMuWuls+ApQW | |||
// +rpcTNWUbUyfqH39TSMWqicy32JFQwXvRGssRfiRP3s+3xyDZNQHlw7pCXwDRRM | |||
// /krsRPXu9EevZXOp04xxEaaTmaTfalN05wcU9rhXzAeqxogaL2ZPxN4m5HIyFBKzPa7sFYojNkFOnH8qDfSDx02 | |||
// /BjwliTNdySgj2oeiAn9wMlUVD2on5mud1TupSct/B+xcc/U/5NvtNDN1uu/LV8EKt6MxBvIh16kM56wBvV8CYqvzJMns+G | |||
// +Mv5l8Kkd3tr7sl8vlBwRwTysxRsbhB+LTfLH4Rxy7mk1s13mlxa7Kc9inebStqYiyXuDAY/dJTwwmQUfo7p97sdNOMKGCI0gJHPd4xjEwScMF | |||
// /P2kmb0n3nI+HOZzOzjlWr7slpqslYhJUYt51w+HNw=="; | |||
// String desStr = "5BOI0S42EfIZHm1uM/nJEsCbLM24pooVpNC1rQwerVlpGkI8e8Bp4cksnzQHEQfVQNuneeWsw2EnhZhLD3G | |||
// +FmyO5sVeboQg4otQnl9LhZynLgp0x9R9cdKorD1w0zctb5YOL907kcxgs4eAgjNrcXxGJXSCgiG4k0SVu6c/ZoVx+oy00OvwOtWMWa5dK | |||
// /qcc1x0XDIFCQDuwHoRES8XbVfMcpUDvdn7AyBq72tMxrIDLkorF35Uo4zNUqzfMaRZJ4Nk3Oq6TnQG2bTUAFaEDi8eQFJ3kPT6z0cBrYgBlo5w/X3VyKPLvhqSpxx0ava6bN3kWAQzE0vrh6yGWZqekQ37uE48siyhwppSs2JB2CKQeP/9h7oJWXAy0rMy8FBOEugb53adaL/mBRLthQYRtJxr0stprvv8bmB3Q240G6f3reF7449SOOzqtClH/MKSt6Sfui9AhEhCv2w7iq4bW0lt1Al3SmMJORYMbvGPCLon8jE4g7JpRraI64ZvB2OgBM2BuEkWj8TVbzCTg1Zb3L4/vq4bT0iyZbXQP/OnGsNmhW08pmroY37nczX/CMkqa53UN4HAnotgz09JB+gikhZFQEFHw91p3GxnYidLnHfRR86+63tdxB5YksU5YXfG6r9uf9o46dw/+eHk9NjvskYOtwarwSBeK4RnhtD+K2aE77Wud2FzKgs+rnITXP/VG37IePdZXHQH/mSn5xmyTCnzKfUcE1sYDujjjuGdYv6SzTiZNe6kzlXZ5KXOn78eQq5kytPZwiuQXQHknwtJ7dWxno4VjXj5eTb3cf2BSyN65JBbQhJD/AWpGh4p88XM4mu5j6x+cAm38C/j7EuLHmmfFvz1DT3k7fhXiTY4WRyPnNHm700s7OmHMSK5RgKgQyOpLcQUGDFHGmhQEJ7TYkuhxPMh0E5D88KjWGfX6qWAJGS/IHPSrCDibN9nckKRRqn0gclByLwIx8psqVGbGA=="; | |||
// String desStr = "Q2ZdFr+28hbqAQq8+vujyaKToWrNPFzukykE9HHoJHqLs8ftKWPgqbBn4J01Dr1rzwHp6ld4VTfb | |||
// \nJLyHim4H9zMmNjwmdJFVNmynJ6VTTf8od7WVOgTwXhjryRSXIGQukp25HVzDZUYPAP5TdxRZwP7S\nbWxKZ2J | |||
// /jAgfkYsHe66cn9474EqZRgRt3ZOv2tI9bZ4YSJqPKdeKYtlZmO/h419Z4xGJhszfJ9t5\nEBvv+lDXJev3pn2Fka76SoVFGkp | |||
// +0zSusdE5q5jmsPToxlRDZqGw9SFUUAk77BUZAIpalXBWqKFA\nz3UdksUwBK2/bg0M+QLNBBFQe3ss7hA1xi1ES2XchLgoneGb5+1qcWi | |||
// /IeKvTVNc+vUIHWzXs5ZH\nvBUJxlC/QytCFKOi8E9jDXgtawGtx1vG/Z46RczWaScTfP315Moa3Q17kYiMXmbVXQPQCz+VRUY6 | |||
// \nDS544b51LVUTDmIwGQe5LocEwI0u/0g5+A92sd9hKKMNONx+MLrptpV0y3PceLK9l0iHQp8zy13W\nfoCP3w3z7oLfenKA6At7BNmN4io | |||
// /pWA15/va4P9IRjsVQ3Lp6w33djk1prOr+YzCK6+0iigyn79Z\neRaOTanhomqhTX5cIb79HAxDSdT0DyFhCgkyIanDjz7yXJmI | |||
// +9IaXDpvXK7cysJUUt++uEtbY/xS\noWBuKHs1IG1pHtMWbozUwT7bEB3li5vTD3WrcUXkU8EWXfgxRKCgIuXat4nbyia41iZjlTVbCFRb | |||
// \nMwVEBdxBHK5rATTnV+oxZoRQS4gZhl4ZJ/yPk6yOAQ7tfCD2IZt6LYIQXmlqCldPEmzuQzidbiJo\nijk+J7qb8Nzd70PBm0hcpPY5oeWiv | |||
// /+TnXm/uWw9aBCmhPZPysA1ygUv/sswZ3aLY4UTTtPPjjHA\ny9SpDPKny+KKpEv2cA | |||
// /zVoOuCFyQ6t8keMVt7ceNS7VOO8k0dkZVcjWEZxmBb2z1tp9vjjpZrJgQ | |||
// \nSx3sT6CbhmX4iiZxMKU7jjoWHbawuxZEuRbB05QFhOF7uywDVfd9Dc4ehyko8E0pE+3y"; | |||
// String desStr = "yal34OpA5RhHoO9QlgpIeYhDVrR9uzYFeKNL6F3+NGcCoVQGjWtopxnRmH4 | |||
// +ZfGE1CMqrIL8c043e6izP8hq7YgydzJb8eZ5u2WCtZSnybgoBWg4FIlOvzuXRxJfn24STkrFHcSx9lyhox/BahzYtYITBPXHjVujlY3He9Bm | |||
// +e8="; | |||
// | |||
// System.out.println("decode=="+decode("fa154364", desStr, Charset.forName("UTF-8"))); | |||
} | |||
public static byte[] encode(String key, String data, Charset charset) | |||
throws Exception { | |||
return encode(key, data.getBytes(charset)); | |||
} | |||
public static String decode(String key, String data, Charset charset) { | |||
byte[] datas; | |||
String value = null; | |||
try { | |||
datas = decode(key, Base64.decodeBase64(data)); | |||
value = new String(datas, charset); | |||
} catch (Exception e) { | |||
value = ""; | |||
} | |||
return value; | |||
} | |||
/** | |||
* des加密,返回string类型,指定编码集 | |||
* | |||
* @param data | |||
* @param charset | |||
* @param key | |||
* @return | |||
* @throws Exception | |||
* @time 2018-11-6 16:08:27 | |||
* @author Lxm | |||
*/ | |||
public static String encode(String data, Charset charset, String key) | |||
throws Exception { | |||
byte[] bt = encode(key, data.getBytes(charset)); | |||
String encode = DesUtil.encode641(bt); | |||
return encode; | |||
} | |||
public static String encode641(byte[] input) { | |||
StringBuffer result = new StringBuffer(); | |||
int outputCharCount = 0; | |||
for (int i = 0; i < input.length; i += 3) { | |||
int remaining = Math.min(3, input.length - i); | |||
int oneBigNumber = | |||
(input[i] & 0xff) << 16 | (remaining <= 1 ? 0 : input[i + 1] & 0xff) << 8 | (remaining <= 2 ? 0 : | |||
input[i + 2] & 0xff); | |||
for (int j = 0; j < 4; j++) | |||
result.append(remaining + 1 > j ? SIXTY_FOUR_CHARS[0x3f & oneBigNumber >> 6 * (3 - j)] : '='); | |||
// if ((outputCharCount += 4) % 76 == 0) result.append('\n'); | |||
} | |||
return result.toString(); | |||
} | |||
} |
@@ -0,0 +1,71 @@ | |||
package cn.com.taiji.ias.tools.hlt; | |||
import java.security.MessageDigest; | |||
public class MD5SignUtil { | |||
/** | |||
* 16进制的字符数组 | |||
*/ | |||
private final static String[] hexDigits = {"0", "1", "2", "3", "4", "5", "6", "7", | |||
"8", "9", "a", "b", "c", "d", "e", "f"}; | |||
// source 需要加密的原字符串 | |||
// encoding 指定编码类型 | |||
// uppercase 是否转为大写字符串 true为大写 false为小写 | |||
public static String MD5Encode(String source, String encoding, boolean uppercase) { | |||
String result = null; | |||
try { | |||
result = source; | |||
// 获得MD5摘要对象 | |||
MessageDigest messageDigest = MessageDigest.getInstance("MD5"); | |||
// 使用指定的字节数组更新摘要信息 | |||
messageDigest.update(result.getBytes(encoding)); | |||
// messageDigest.digest()获得16位长度 | |||
result = byteArrayToHexString(messageDigest.digest()); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
return uppercase ? result.toUpperCase() : result; | |||
} | |||
/** | |||
* 转换字节数组为16进制字符串 | |||
* | |||
* @param bytes 字节数组 | |||
* @return | |||
*/ | |||
private static String byteArrayToHexString(byte[] bytes) { | |||
StringBuilder stringBuilder = new StringBuilder(); | |||
for (byte tem : bytes) { | |||
stringBuilder.append(byteToHexString(tem)); | |||
} | |||
return stringBuilder.toString(); | |||
} | |||
/** | |||
* 转换byte到16进制 | |||
* | |||
* @param b 要转换的byte | |||
* @return 16进制对应的字符 | |||
*/ | |||
private static String byteToHexString(byte b) { | |||
int n = b; | |||
if (n < 0) { | |||
n = 256 + n; | |||
} | |||
int d1 = n / 16; | |||
int d2 = n % 16; | |||
return hexDigits[d1] + hexDigits[d2]; | |||
} | |||
public static void main(String[] args) { | |||
String s = MD5Encode("bizContent={\\\"userName\\\":\\\"werqr\\\",\\\"userIdType\\\":105}&signType=NONE&version=2.0&encryptType=NONE×tamp=2022-06-21T14:12:48&filename=1", "UTF-8", false); | |||
System.out.println(s); | |||
} | |||
} |