SignatureExec.java 3.01 KB
Newer Older
licc's avatar
licc committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
package cn.wisenergy.service.httpClient;

import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpExecutionAware;
import org.apache.http.client.methods.HttpRequestWrapper;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.execchain.ClientExecChain;

import java.io.IOException;

public class SignatureExec implements ClientExecChain {
  final ClientExecChain mainExec;
  final Credentials credentials;
  final Validator validator;

  SignatureExec(Credentials credentials, Validator validator, ClientExecChain mainExec) {
    this.credentials = credentials;
    this.validator = validator;
    this.mainExec = mainExec;
  }

  protected void convertToRepeatableResponseEntity(CloseableHttpResponse response)
      throws IOException {
    HttpEntity entity = response.getEntity();
    if (entity != null) {
      response.setEntity(new BufferedHttpEntity(entity));
    }
  }

  protected void convertToRepeatableRequestEntity(HttpRequestWrapper request) throws IOException {
    if (request instanceof HttpEntityEnclosingRequest) {
      HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
      if (entity != null) {
        ((HttpEntityEnclosingRequest) request).setEntity(new BufferedHttpEntity(entity));
      }
    }
  }

  @Override
  public CloseableHttpResponse execute(HttpRoute route, HttpRequestWrapper request,
                                       HttpClientContext context, HttpExecutionAware execAware) throws IOException, HttpException {
    if (request.getURI().getHost().endsWith(".mch.weixin.qq.com")) {
      return executeWithSignature(route, request, context, execAware);
    } else {
      return mainExec.execute(route, request, context, execAware);
    }
  }

  private CloseableHttpResponse executeWithSignature(HttpRoute route, HttpRequestWrapper request,
                                                     HttpClientContext context, HttpExecutionAware execAware) throws IOException, HttpException {
    // 上传类不需要消耗两次故不做转换
    if (!(request.getOriginal() instanceof WechatPayUploadHttpPost)) {
      convertToRepeatableRequestEntity(request);
    }
    // 添加认证信息
    request.addHeader("Authorization",
        credentials.getSchema() + " " + credentials.getToken(request));

    // 执行
    CloseableHttpResponse response = mainExec.execute(route, request, context, execAware);

    // 对成功应答验签
    StatusLine statusLine = response.getStatusLine();
    if (statusLine.getStatusCode() >= 200 && statusLine.getStatusCode() < 300) {
      convertToRepeatableResponseEntity(response);
      if (!validator.validate(response)) {
        throw new HttpException("应答的微信支付签名验证失败");
      }
    }
    return response;
  }
}