移除过滤器

This commit is contained in:
xiafang
2020-11-26 18:38:05 +08:00
parent 5074156c24
commit b4f82e74cf
7 changed files with 103 additions and 236 deletions

View File

@@ -1,29 +0,0 @@
package com.enongm.dianji.payment.wechat.v3;
import java.util.ArrayList;
import java.util.List;
/**
* @author Dax
* @since 16:16
*/
public class DefaultPayFilterChain implements PayFilterChain {
private int pos = 0;
private final List<PayFilter> filters = new ArrayList<>();
@Override
public void register(PayFilter filter) {
filters.add(filter);
}
@Override
public void doChain(WechatRequestEntity<?> requestEntity) {
int size = filters.size();
if (pos < size) {
PayFilter payFilter = filters.get(pos++);
payFilter.doFilter(requestEntity, this);
}
}
}

View File

@@ -1,18 +0,0 @@
package com.enongm.dianji.payment.wechat.v3;
/**
* The interface Pay filter.
*
* @author Dax
* @since 15 :08
*/
public interface PayFilter {
/**
* Do filter.
* @param requestEntity the request entity
* @param chain the chain*/
<T> void doFilter(WechatRequestEntity<T> requestEntity, PayFilterChain chain);
}

View File

@@ -1,25 +0,0 @@
package com.enongm.dianji.payment.wechat.v3;
/**
* The interface Pay filter chain.
*
* @author Dax
* @since 16 :11
*/
public interface PayFilterChain {
/**
* Do chain.
*
* @param requestEntity the request entity
*/
void doChain(WechatRequestEntity<?> requestEntity);
/**
* Register.
*
* @param filter the filter
*/
void register(PayFilter filter);
}

View File

@@ -1,14 +1,21 @@
package com.enongm.dianji.payment.wechat.v3;
import com.enongm.dianji.payment.PayException;
import com.enongm.dianji.payment.wechat.WechatPayResponseErrorHandler;
import com.enongm.dianji.payment.wechat.enumeration.WechatPayV3Type;
import com.enongm.dianji.payment.wechat.v3.filter.HeaderFilter;
import com.enongm.dianji.payment.wechat.v3.filter.HttpRequestFilter;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.SneakyThrows;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.*;
import org.springframework.util.Assert;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Collections;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Consumer;
@@ -19,7 +26,7 @@ import java.util.function.Consumer;
* @since 11 :43
*/
public class WechatPayClient {
private final PayFilterChain payFilterChain;
private final SignatureProvider signatureProvider;
/**
* Instantiates a new Wechat pay service.
@@ -27,12 +34,7 @@ public class WechatPayClient {
* @param signatureProvider the signature provider
*/
public WechatPayClient(SignatureProvider signatureProvider) {
DefaultPayFilterChain defaultPayFilterChain = new DefaultPayFilterChain();
// 构造私钥签名
defaultPayFilterChain.register(new HeaderFilter(signatureProvider));
// 向微信支付服务器发起请求
defaultPayFilterChain.register(new HttpRequestFilter(signatureProvider));
this.payFilterChain = defaultPayFilterChain;
this.signatureProvider = signatureProvider;
}
@@ -45,7 +47,7 @@ public class WechatPayClient {
* @return the executor
*/
public <M> Executor<M> withType(WechatPayV3Type wechatPayV3Type, M m) {
return new Executor<>(wechatPayV3Type,m ,this.payFilterChain);
return new Executor<>(wechatPayV3Type, m, this.signatureProvider);
}
@@ -59,11 +61,8 @@ public class WechatPayClient {
* The V 3 pay type.
*/
private final WechatPayV3Type wechatPayV3Type;
/**
* The Pay filter chain.
*/
private final PayFilterChain payFilterChain;
private final RestOperations restOperations;
private final SignatureProvider signatureProvider;
private final M model;
/**
@@ -74,21 +73,25 @@ public class WechatPayClient {
/**
* The Response body consumer.
*/
private Consumer<ResponseEntity<ObjectNode>> responseBodyConsumer;
private Consumer<ResponseEntity<ObjectNode>> responseBodyConsumer;
/**
* Instantiates a new Executor.
*
* @param wechatPayV3Type the v 3 pay type
* @param model the model
* @param payFilterChain the pay filter chain
* @param wechatPayV3Type the v 3 pay type
* @param model the model
* @param signatureProvider the signature provider
*/
public Executor(WechatPayV3Type wechatPayV3Type,
M model,
PayFilterChain payFilterChain) {
SignatureProvider signatureProvider) {
this.wechatPayV3Type = wechatPayV3Type;
this.model = model;
this.payFilterChain = payFilterChain;
this.signatureProvider = signatureProvider;
RestTemplate restTemplate = new RestTemplate();
DefaultResponseErrorHandler errorHandler = new WechatPayResponseErrorHandler();
restTemplate.setErrorHandler(errorHandler);
this.restOperations = restTemplate;
}
/**
@@ -120,8 +123,83 @@ public class WechatPayClient {
@SneakyThrows
public void request() {
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model);
payFilterChain.doChain(WechatRequestEntity.of(requestEntity, this.responseBodyConsumer));
WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer);
this.doExecute(this.header(wechatRequestEntity));
}
/**
* 构造私钥签名.
*
* @param <T> the type parameter
* @param requestEntity the request entity
*/
private <T> WechatRequestEntity<T> header(WechatRequestEntity<T> requestEntity) {
UriComponents uri = UriComponentsBuilder.fromUri(requestEntity.getUrl()).build();
String canonicalUrl = uri.getPath();
String encodedQuery = uri.getQuery();
if (encodedQuery != null) {
canonicalUrl += "?" + encodedQuery;
}
// 签名
HttpMethod httpMethod = requestEntity.getMethod();
Assert.notNull(httpMethod, "httpMethod is required");
String body = requestEntity.hasBody() ? Objects.requireNonNull(requestEntity.getBody()).toString() : "";
String authorization = signatureProvider.requestSign(httpMethod.name(), canonicalUrl, body);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.addAll(requestEntity.getHeaders());
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
// 兼容图片上传,自定义优先级最高
if (Objects.isNull(httpHeaders.getContentType())) {
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
}
httpHeaders.add("Authorization", authorization);
httpHeaders.add("User-Agent", "X-Pay-Service");
return requestEntity.headers(httpHeaders);
}
private <T> void doExecute(WechatRequestEntity<T> requestEntity) {
ResponseEntity<ObjectNode> responseEntity = restOperations.exchange(requestEntity, ObjectNode.class);
HttpHeaders headers = responseEntity.getHeaders();
ObjectNode body = responseEntity.getBody();
if (Objects.isNull(body)) {
throw new IllegalStateException("cant obtain response body");
}
// 微信请求回调id
// String RequestId = response.header("Request-ID");
// 微信平台证书序列号 用来取微信平台证书
String wechatpaySerial = headers.getFirst("Wechatpay-Serial");
//获取应答签名
String wechatpaySignature = headers.getFirst("Wechatpay-Signature");
//构造验签名串
String wechatpayTimestamp = headers.getFirst("Wechatpay-Timestamp");
String wechatpayNonce = headers.getFirst("Wechatpay-Nonce");
// 验证微信服务器签名
if (signatureProvider.responseSignVerify(wechatpaySerial,
wechatpaySignature,
wechatpayTimestamp,
wechatpayNonce,
body.toString())) {
Consumer<ResponseEntity<ObjectNode>> responseConsumer = requestEntity.getResponseBodyConsumer();
if (Objects.nonNull(responseConsumer)) {
// 验证通过消费
responseConsumer.accept(responseEntity);
}
} else {
throw new PayException("wechat pay signature failed");
}
}
}
}

View File

@@ -1,63 +0,0 @@
package com.enongm.dianji.payment.wechat.v3.filter;
import com.enongm.dianji.payment.wechat.v3.PayFilter;
import com.enongm.dianji.payment.wechat.v3.PayFilterChain;
import com.enongm.dianji.payment.wechat.v3.SignatureProvider;
import com.enongm.dianji.payment.wechat.v3.WechatRequestEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Collections;
import java.util.Objects;
/**
* 微信支付 给请求添加必要的请求头.
* 3
*
* @author Dax
* @since 15 :12
*/
public class HeaderFilter implements PayFilter {
private final SignatureProvider signatureProvider;
public HeaderFilter(SignatureProvider signatureProvider) {
this.signatureProvider = signatureProvider;
}
@Override
public <T> void doFilter(WechatRequestEntity<T> requestEntity, PayFilterChain chain) {
UriComponents uri = UriComponentsBuilder.fromUri(requestEntity.getUrl()).build();
String canonicalUrl = uri.getPath();
String encodedQuery = uri.getQuery();
if (encodedQuery != null) {
canonicalUrl += "?" + encodedQuery;
}
// 签名
HttpMethod httpMethod = requestEntity.getMethod();
Assert.notNull(httpMethod, "httpMethod is required");
String body = requestEntity.hasBody() ? Objects.requireNonNull(requestEntity.getBody()).toString() : "";
String authorization = signatureProvider.requestSign(httpMethod.name(), canonicalUrl, body);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.addAll(requestEntity.getHeaders());
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
// 兼容图片上传,自定义优先级最高
if (Objects.isNull(httpHeaders.getContentType())) {
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
}
httpHeaders.add("Authorization", authorization);
httpHeaders.add("User-Agent", "X-Pay-Service");
chain.doChain(requestEntity.headers(httpHeaders));
}
}

View File

@@ -1,76 +0,0 @@
package com.enongm.dianji.payment.wechat.v3.filter;
import com.enongm.dianji.payment.PayException;
import com.enongm.dianji.payment.wechat.WechatPayResponseErrorHandler;
import com.enongm.dianji.payment.wechat.v3.PayFilter;
import com.enongm.dianji.payment.wechat.v3.PayFilterChain;
import com.enongm.dianji.payment.wechat.v3.SignatureProvider;
import com.enongm.dianji.payment.wechat.v3.WechatRequestEntity;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestOperations;
import org.springframework.web.client.RestTemplate;
import java.util.Objects;
import java.util.function.Consumer;
/**
* 微信支付用来请求微信支付服务器
*
* @author Dax
* @since 10:42
*/
@Slf4j
public class HttpRequestFilter implements PayFilter {
private final RestOperations restOperations;
private final SignatureProvider signatureProvider;
public HttpRequestFilter(SignatureProvider signatureProvider) {
this.signatureProvider = signatureProvider;
RestTemplate restTemplate = new RestTemplate();
DefaultResponseErrorHandler errorHandler = new WechatPayResponseErrorHandler();
restTemplate.setErrorHandler(errorHandler);
this.restOperations = restTemplate;
}
@Override
public <T> void doFilter(WechatRequestEntity<T> requestEntity, PayFilterChain chain) {
ResponseEntity<ObjectNode> responseEntity = restOperations.exchange(requestEntity, ObjectNode.class);
HttpHeaders headers = responseEntity.getHeaders();
ObjectNode body = responseEntity.getBody();
if (Objects.isNull(body)) {
throw new IllegalStateException("cant obtain response body");
}
// 微信请求回调id
// String RequestId = response.header("Request-ID");
// 微信平台证书序列号 用来取微信平台证书
String wechatpaySerial = headers.getFirst("Wechatpay-Serial");
//获取应答签名
String wechatpaySignature = headers.getFirst("Wechatpay-Signature");
//构造验签名串
String wechatpayTimestamp = headers.getFirst("Wechatpay-Timestamp");
String wechatpayNonce = headers.getFirst("Wechatpay-Nonce");
// 验证微信服务器签名
if (signatureProvider.responseSignVerify(wechatpaySerial,
wechatpaySignature,
wechatpayTimestamp,
wechatpayNonce,
body.toString())) {
Consumer<ResponseEntity<ObjectNode>> responseConsumer = requestEntity.getResponseBodyConsumer();
if (Objects.nonNull(responseConsumer)) {
// 验证通过消费
responseConsumer.accept(responseEntity);
}
} else {
throw new PayException("wechat pay signature failed");
}
}
}

View File

@@ -22,7 +22,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.3.4.RELEASE</spring-boot.version>
<spring-boot.version>2.1.14.RELEASE</spring-boot.version>
<aliy-pay-sdk.version>4.10.167.ALL</aliy-pay-sdk.version>
<oss-starter.version>1.0.0.RELEASE</oss-starter.version>
<lombok.verison>1.18.12</lombok.verison>