医保移动支付和接口对接开发
1 · 医保移动支付开发注意事项。
2 · HTTP 基础知识: 回顾 HTTP 请求的基本结构和工作原理,包括请求方法、请求头、请求体等。
3 · 数据格式处理: 探讨如何正确处理不同数据格式(如 JSON、XML)的请求和响应。
4 · 错误处理策略: 研究异常情况下的最佳实践,包括重试策略、超时处理和错误状态码处理。
5 · 性能优化: 提供性能优化技巧,减少请求延迟和提高吞吐量。
6 · 第三方服务认证: 学习如何进行认证和授权,以确保只有授权的请求可以访问第三方服务。(服务接口提供方)
7 · 安全性: 讲解如何保护 HTTP 请求和响应,防止潜在的安全漏洞。(服务接口提供方)
8 · 日志和监控: 了解如何记录请求和响应信息,以及如何设置监控来追踪系统的健康状况
1医保移动支付开发注意事项:
1.1微信医保移动支付关注文档:
https://docs.qq.com/doc/DV1J6ZVB6eHZ3amxK
1.2用户授权接入文档见链接:
用户授权接入文档(医保信息授权)(payAuthNo版本) https://docs.qq.com/doc/DV3JYRG1xelhKTWdz
1.3对接移动医疗平台接口文档见链接:
对接移动医疗平台接口文档_国家局v4.0 https://docs.qq.com/doc/DV3lxV3hSbXFudVBE
2 · HTTP基础知识: 回顾 HTTP1.1 请求的基本结构和工作原理,包括请求方法、请求头、请求体等。
2.1 请求例子:
curl --location --request POST ‘https://hlwyy.songjianghealth.com/zsyy/insuranceWx/refundInsurance?refund_key=8e6458f38c2ca66215c94a42c517ddfd’
–header ‘Content-Type: application/json’
–data-raw ’ {
“appRefdSn”: “ORD310100202309221504550007718”,
“appRefdTime”: “20230529210946”,
“cashRefdAmt”: “1.00”,
“ecToken”: “”,
“expContent”: “”,
“fundRefdAmt”: “0”,
“outTradeNo”: “0”,
“payAuthNo”: “ORD310100202309221504550007718”,
“payOrdId”: “ORD310100202309221504550007718”,
“payWay”: “01”,
“psnAcctRefdAmt”: “1.00”,
“refdType”: “HI”,
“totlRefdAmt”: “15.54”
}’
2.2 请求客户端 httpClient
https://hc.apache.org/httpcomponents-client-4.5.x/current/tutorial/html/connmgmt.html
package cn.google.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.*;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
HttpClient工具类
@author
@date 2023-09-18 17:12
/
@Slf4j
public class HttpClientUtil {
/*
private static CloseableHttpClient httpClient = null;
private static final Object SYNC_LOCK = new Object();
private static final String DEFAULT_CHARSET = “UTF-8”;
private static void config(HttpRequestBase httpRequestBase) {
//配置请求的超时时间
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(TIMEOUT)
.setConnectTimeout(TIMEOUT)
.setSocketTimeout(TIMEOUT)
.build();
httpRequestBase.setConfig(requestConfig);
}
/**
/**
HttpClient配置SSL绕过https证书(因为我的网站是有https证书的,所以在访问https网站时,会自动读取我的证书,
和目标网站不符,会报错),所以这里需要绕过https证书
*/
private static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContext.getInstance(“SSLv3”);
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
sslContext.init(null, new TrustManager[] {trustManager}, null);
return sslContext;
}
private static void setPostParams(HttpPost httpPost, Map
List nameValuePairs = new ArrayList<>();
params.forEach((key, value) -> nameValuePairs.add(new BasicNameValuePair(key, value.toString())));
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, DEFAULT_CHARSET));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
/**
/**
}
2.3 请求客户端restTemplate.
package cn.ucmed.zsyy.common.config.restTemplate;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.*;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
@author ucmed
@since 2022/1/4 16:13
*/
@Slf4j
@Configuration
public class RestTemplateConfig {
@Value(“
h
t
t
p
.
c
o
n
n
e
c
t
i
o
n
.
m
a
x
"
)
p
r
i
v
a
t
e
i
n
t
c
o
n
n
e
c
t
i
o
n
M
a
x
;
@
V
a
l
u
e
(
"
{http.connection.max}") private int connectionMax; @Value("
http.connection.max")privateintconnectionMax;@Value("{http.connection.route.max}”)
private int connectionRouteMax;
@Value(“
h
t
t
p
.
c
o
n
n
e
c
t
.
t
i
m
e
o
u
t
"
)
p
r
i
v
a
t
e
i
n
t
c
o
n
n
e
c
t
T
i
m
e
o
u
t
;
@
V
a
l
u
e
(
"
{http.connect.timeout}") private int connectTimeout; @Value("
http.connect.timeout")privateintconnectTimeout;@Value("{http.socket.timeout}”)
private int socketTimeout;
@Value(“${http.request.timeout}”)
private int requestTimeout;
@Bean
public RestTemplate getRestTemplate() {
RestTemplate restTemplate = new RestTemplate(httpComponentsClientHttpRequestFactory());
List
3 · 接口数据格式处理: 探讨如何正确处理不同数据格式(如 JSON、XML)的请求和响应。
3.1 利用excel表格生成javaBean代码
代码及文档: 使用文档拷贝,入参 出参处理。 代码注释包含 属性描述 说明备注 是否必填等
3.2 出入参数业务异常统一处理.
String xmlReturnStr = centerHospitalHttpService.postRequestHis(ShanghaiSongCenterHospitalHttpService.HIS_URL,
xmlString);
HisBaseBeanResult hisResult = new HisBaseBeanResult<>();
//异常统一处理
hisResult.builderBeanData(xmlReturnStr, ClinicDetailHisResult.class);
3.3 禁止未知异常,推荐返回his接口的业务his异常信息
String xmlString = objToxml(xmlBody);
log.warn(“xmlString ::{}”, xmlString);
String xmlReturnStr = centerHospitalHttpService.postRequestHis(ShanghaiSongCenterHospitalHttpService.HIS_URL,
xmlString);
HisBaseBeanResult hisResult = new HisBaseBeanResult<>();
hisResult.builderBeanData(xmlReturnStr, ClinicDetailHisResult.class);
ClinicDetailHisResult items = hisResult.getBeanData();
4 · 熔断错误处理策略: 研究异常情况下的最佳实践,包括重试策略、超时处理和错误状态码处理。
4.1 什么是接口熔断.(容错)
系统A调⽤B,⽽B调⽤C,这时如果C出现故障,则此时调⽤B的⼤量线程资源阻塞,慢慢的B的线程数量持续增加直到CPU耗尽到100%,整体微服务不可⽤,这时就需要对不可⽤的服务进⾏隔离.
系统所依赖的服务的稳定性对系统的影响⾮常⼤,⽽且还有很多不确定因素引起雪崩,如⽹络连接中断,服务宕机等
https://blog.csdn.net/ywtech/article/details/132626613
4.2如何熔断的原理
4.3熔断保护-社区生态有哪些方案
Sentinel 与 Hystrix、Resilience4j
4.4 熔断保护系统实践.( 熔断 降级 并发限流,重试)
5 性能优化: 提供性能优化技巧,减少请求延迟和提高吞吐量。
5.1 禁止使用 new RestTemplate()
5.2 推荐使用连接连接池 forest http 客户端
6 · 第三方服务认证: 学习如何进行认证和授权,以确保只有授权的请求可以访问第三方服务。(服务接口提供方)
7 · 安全性: 讲解如何保护 HTTP 请求和响应,防止潜在的安全漏洞。(服务接口提供方)
8 · 日志和监控: 了解如何记录请求和响应信息,以及如何设置监控来追踪系统的健康状况
Skywalking