背景:通过过滤器做埋点数据。
过滤器代码:
package com.xx.xxxx.client.filter;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import com.alibaba.fastjson.JSON;
import com.xxxx.bean.constants.PayMethodConstants;
import com.xxxx.jcpay.common.util.DateUtils;
import com.xx.xxxx.common.request.BodyReaderHttpServletRequestWrapper;
import com.xx.xxxx.common.request.ReadSerlvetBody;
import com.xx.xxxx.dal.model.TcOrderPaymentRecord;
import com.xx.xxxx.integration.service.PaymentRecordService;
import com.xx.xxxx.utils.CashierUtils;
import lombok.extern.slf4j.Slf4j;
/**
* 类职责:过滤器 支付前,交易号、支付方式、xx会员id、支付验证类型、落库时间参数记录
*
* Title: PaymentRecordFilter.java
* Description:
* Copyright:
* Company:
*
* Author:Cent
* CreateTime:2018年10月19日上午9:31:08
*/
@Slf4j
@Order(3)
@WebFilter(urlPatterns = {"/trade/*"}, filterName = "paymentRecordFilter")
public class PaymentRecordFilter implements Filter {
//根据servletPath 排除非用户支付节点的过滤
private static final HashSet excludedUrlSet = new HashSet(Arrays.asList("/trade/redirectBankUrl"));
private static final String BALANCE_PAYMENT_URI = "/trade/balancePayment";
private static final String BANKCARD_FORM_PAYMENT_URI = "/trade/bankcardFormPayment";
private static final String BANKCARD_PAYMENT_URI = "/trade/bankcardPayment";
private static final String LOCAL_PAYMENT_URI = "/trade/localPayment";
private static final String QUICK_PAYMENT_URI = "/trade/quickPayment";
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final String POST_FORM = "application/x-www-form-urlencoded";
private static final String POST_JSON = "application/json";
@Autowired
private PaymentRecordService paymentRecordService;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.debug("paymentRecordFilter init...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
HttpServletRequest httpServletRequest = ((HttpServletRequest) request);
String servletPath = httpServletRequest.getServletPath();
if (excludedUrlSet.contains(servletPath) == false) {
ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
Map requestBodyMap = new HashMap();
if(StringUtils.contains(httpServletRequest.getHeader("Content-Type"), POST_FORM)) {
requestBodyMap.put("tradeNo", requestWrapper.getParameter("tradeNo"));
requestBodyMap.put("bankCode", requestWrapper.getParameter("bankCode"));
} else {
String requestBody = ReadSerlvetBody.getBodyToString(requestWrapper);
requestBodyMap = JSON.parseObject(URLDecoder.decode(requestBody,"UTF-8")).getInnerMap();
}
String verifyType = "";
String payMethod;
switch (servletPath) {
case BALANCE_PAYMENT_URI:
payMethod = PayMethodConstants.PAYMETHOD_BALANCE;
verifyType = getVerifyType(requestBodyMap);
break;
case BANKCARD_FORM_PAYMENT_URI:
payMethod = getBankPayMethod(requestBodyMap,true);
break;
case BANKCARD_PAYMENT_URI:
payMethod = getBankPayMethod(requestBodyMap,false);
break;
case LOCAL_PAYMENT_URI:
payMethod = requestBodyMap.get("bankCode") == null ? null : String.valueOf(requestBodyMap.get("bankCode"));
break;
case QUICK_PAYMENT_URI:
payMethod = PayMethodConstants.PAYMETHOD_QUICK;
verifyType = getVerifyType(requestBodyMap);
break;
default:
payMethod = verifyType;
break;
}
TcOrderPaymentRecord tcOrderPaymentRecord = new TcOrderPaymentRecord();
Object tradeNo = requestBodyMap.get("tradeNo");
if (null != tradeNo && StringUtils.isNotBlank(String.valueOf(tradeNo))) {
tcOrderPaymentRecord.setTradeNo(String.valueOf(tradeNo));
} else {
log.warn("param: tradeNo is null !");
throw new Exception();
}
if (StringUtils.isNotBlank(payMethod)) {
tcOrderPaymentRecord.setPayMethod(payMethod);
}
if (StringUtils.isNotBlank(verifyType)) {
tcOrderPaymentRecord.setVerifyType(verifyType);
}
tcOrderPaymentRecord.setMemberId(CashierUtils.getMemberId());
tcOrderPaymentRecord.setCreateTime(
DateUtils.stringToDate(DateUtils.dateToString(new Date(), DATE_FORMAT), DATE_FORMAT));
paymentRecordService.addPaymentRecord(tcOrderPaymentRecord);
chain.doFilter(requestWrapper, response);
} else {
chain.doFilter(request, response);
}
} catch (Exception e) {
log.warn("增加支付记录失败!",e);
chain.doFilter(request, response);
}
}
private String getBankPayMethod(Map requestBodyMap, boolean isFormSubmit) {
String payMethod = "";
if (requestBodyMap.get("bankCode") != null && StringUtils
.equalsIgnoreCase(String.valueOf(requestBodyMap.get("bankCode")), PayMethodConstants.MADA)) {
return PayMethodConstants.MADA;
} else if (isFormSubmit) {
payMethod = PayMethodConstants.THRIDDS_PAYMETHOD_BANKCARD;
} else {
payMethod = PayMethodConstants.PAYMETHOD_BANKCARD;
}
return payMethod;
}
/**
* 余额支付、一键支付认证类型
* @param httpServletRequest
* @return
*/
private String getVerifyType(Map requestBodyMap) {
Object mCode = requestBodyMap.get("mCode");
if (null != mCode && StringUtils.isNotBlank(String.valueOf(mCode))) {
return "3";
}
Object payPassword = requestBodyMap.get("payPassword");
if(null != payPassword && StringUtils.isNotBlank(String.valueOf(payPassword))) {
return "1";
}
Object smsCode = requestBodyMap.get("smsCode");
if(null != smsCode && StringUtils.isNotBlank(String.valueOf(smsCode))) {
return "2";
}
return "";
}
@Override
public void destroy() {
log.info("paymentRecordFilter destroy...");
}
}
BodyReaderHttpServletRequestWrapper中对request寄存 以及对流数据的getReader、getInputStream方法的重写
package com.xx.xxxx.common.request;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
* 类职责:
*
* Title: BodyReaderHttpServletRequestWrapper.java
* Description:
* Copyright:
* Company:
*
* Author:Cent
* CreateTime:2018年10月19日下午4:40:55
*/
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{
//寄存的request body内容的数组
private final byte[] body;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
body = ReadSerlvetBody.getBodyToString(request).getBytes(Charset.forName("UTF-8"));
}
@Override
public String getHeader(String name) {
// TODO Auto-generated method stub
return super.getHeader(name);
}
@Override
public Enumeration getHeaders(String name) {
// TODO Auto-generated method stub
return super.getHeaders(name);
}
@Override
public Enumeration getHeaderNames() {
// TODO Auto-generated method stub
return super.getHeaderNames();
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
//从 原始HttpServletRequest对象中的body获取数据
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
}
}
package com.xx.xxx.common.request;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import javax.servlet.ServletRequest;
/**
* 类职责:
*
* Title: ReadSerlvetBody.java
* Description:
* Copyright: xxxx
* Company: xxx
*
* Author:Cent
* CreateTime:2018年10月19日下午5:01:22
*/
public class ReadSerlvetBody {
/**
* 通过流读取request body中的内容
* @param request
* @return
*/
public static String getBodyToString(ServletRequest request) {
StringBuilder sBuilder = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = request.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
String line;
while ((line = reader.readLine()) != null) {
sBuilder.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
closeAll(inputStream,reader);
}
return sBuilder.toString();
}
/**
* 关闭流
* @param inputStream
* @param reader
*/
public static void closeAll(InputStream inputStream, BufferedReader reader) {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
参考:
https://blog.csdn.net/baidu_20959289/article/details/53380707