add client ip info
This commit is contained in:
parent
e5f5e6ca75
commit
4351c0ef03
@ -1,216 +1,216 @@
|
|||||||
package top.baogutang.admin.schedule;
|
//package top.baogutang.admin.schedule;
|
||||||
|
//
|
||||||
import cn.hutool.core.text.CharSequenceUtil;
|
//import cn.hutool.core.text.CharSequenceUtil;
|
||||||
import cn.hutool.core.util.CharsetUtil;
|
//import cn.hutool.core.util.CharsetUtil;
|
||||||
import cn.hutool.core.util.URLUtil;
|
//import cn.hutool.core.util.URLUtil;
|
||||||
import cn.hutool.http.Header;
|
//import cn.hutool.http.Header;
|
||||||
import cn.hutool.http.HttpRequest;
|
//import cn.hutool.http.HttpRequest;
|
||||||
import cn.hutool.http.HttpResponse;
|
//import cn.hutool.http.HttpResponse;
|
||||||
import com.alibaba.fastjson.JSON;
|
//import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
//import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
//import com.alibaba.fastjson.JSONObject;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
//import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
//import com.xxl.job.core.handler.IJobHandler;
|
||||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
//import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
//import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
//import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
//import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
//import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
//import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
//import org.springframework.stereotype.Component;
|
||||||
import top.baogutang.admin.domain.IphoneProductDto;
|
//import top.baogutang.admin.domain.IphoneProductDto;
|
||||||
import top.baogutang.admin.utils.DingTalkMsgPushUtils;
|
//import top.baogutang.admin.utils.DingTalkMsgPushUtils;
|
||||||
import top.baogutang.admin.utils.IphoneProductParserUtils;
|
//import top.baogutang.admin.utils.IphoneProductParserUtils;
|
||||||
|
//
|
||||||
import javax.annotation.Resource;
|
//import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
//import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
//import java.util.HashMap;
|
||||||
import java.util.List;
|
//import java.util.List;
|
||||||
import java.util.Map;
|
//import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
//import java.util.stream.Collectors;
|
||||||
|
//
|
||||||
/**
|
///**
|
||||||
* @description: 苹果库存监控
|
// * @description: 苹果库存监控
|
||||||
* @author: nikooh
|
// * @author: nikooh
|
||||||
* @date: 2023/10/13 : 15:12
|
// * @date: 2023/10/13 : 15:12
|
||||||
*/
|
// */
|
||||||
@Slf4j
|
//@Slf4j
|
||||||
@Component
|
//@Component
|
||||||
@RefreshScope
|
//@RefreshScope
|
||||||
public class AppleInventoryScheduleHandler extends IJobHandler {
|
//public class AppleInventoryScheduleHandler extends IJobHandler {
|
||||||
|
//
|
||||||
@Value("${baogutang.apple.country_code:cn}")
|
// @Value("${baogutang.apple.country_code:cn}")
|
||||||
private String countryCode;
|
// private String countryCode;
|
||||||
|
//
|
||||||
@Value("${baogutang.apple.device_code:17-pro}")
|
// @Value("${baogutang.apple.device_code:17-pro}")
|
||||||
private String deviceCode;
|
// private String deviceCode;
|
||||||
|
//
|
||||||
@Value("${baogutang.apple.location:'上海 上海 闵行区'}")
|
// @Value("${baogutang.apple.location:'上海 上海 闵行区'}")
|
||||||
private String location;
|
// private String location;
|
||||||
|
//
|
||||||
@Value("${baogutang.apple.switch:true}")
|
// @Value("${baogutang.apple.switch:true}")
|
||||||
private Boolean appleInventoryMonitorSwitch;
|
// private Boolean appleInventoryMonitorSwitch;
|
||||||
|
//
|
||||||
// @Value("${baogutang.apple.storeList}")
|
// // @Value("${baogutang.apple.storeList}")
|
||||||
private List<String> storeList = new ArrayList<>();
|
// private List<String> storeList = new ArrayList<>();
|
||||||
|
//
|
||||||
@Resource
|
// @Resource
|
||||||
private IphoneProductParserUtils iphoneProductParserUtils;
|
// private IphoneProductParserUtils iphoneProductParserUtils;
|
||||||
|
//
|
||||||
@Resource
|
// @Resource
|
||||||
private DingTalkMsgPushUtils dingTalkMsgPushUtils;
|
// private DingTalkMsgPushUtils dingTalkMsgPushUtils;
|
||||||
|
//
|
||||||
@Scheduled(cron = "0 0/1 * * * ? ")
|
// @Scheduled(cron = "0 0/1 * * * ? ")
|
||||||
public void appleInventoryMonitor() {
|
// public void appleInventoryMonitor() {
|
||||||
if (!Boolean.TRUE.equals(appleInventoryMonitorSwitch)) {
|
// if (!Boolean.TRUE.equals(appleInventoryMonitorSwitch)) {
|
||||||
log.info(">>>>>>>>>>apple inventory monitor switch closed!<<<<<<<<<<");
|
// log.info(">>>>>>>>>>apple inventory monitor switch closed!<<<<<<<<<<");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
// 获取设备信息
|
// // 获取设备信息
|
||||||
List<IphoneProductDto> products = iphoneProductParserUtils.getProducts(deviceCode, countryCode);
|
// List<IphoneProductDto> products = iphoneProductParserUtils.getProducts(deviceCode, countryCode);
|
||||||
//监视机型型号
|
// //监视机型型号
|
||||||
products.forEach(product -> {
|
// products.forEach(product -> {
|
||||||
this.doMonitor(product);
|
// this.doMonitor(product);
|
||||||
try {
|
// try {
|
||||||
Thread.sleep(2000);
|
// Thread.sleep(2000);
|
||||||
} catch (InterruptedException e) {
|
// } catch (InterruptedException e) {
|
||||||
log.error(">>>>>>>>>>apple inventory monitor error:{}<<<<<<<<<<", e.getMessage(), e);
|
// log.error(">>>>>>>>>>apple inventory monitor error:{}<<<<<<<<<<", e.getMessage(), e);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private void doMonitor(IphoneProductDto product) {
|
// private void doMonitor(IphoneProductDto product) {
|
||||||
|
//
|
||||||
|
//
|
||||||
Map<String, Object> queryMap = new HashMap<>(5);
|
// Map<String, Object> queryMap = new HashMap<>(5);
|
||||||
queryMap.put("pl", "true");
|
// queryMap.put("pl", "true");
|
||||||
queryMap.put("mts.0", "regular");
|
// queryMap.put("mts.0", "regular");
|
||||||
queryMap.put("parts.0", product.getModel());
|
// queryMap.put("parts.0", product.getModel());
|
||||||
queryMap.put("location", location);
|
// queryMap.put("location", location);
|
||||||
|
//
|
||||||
String baseUrl = String.format("https://www.apple.com.%s", countryCode);
|
// String baseUrl = String.format("https://www.apple.com.%s", countryCode);
|
||||||
Map<String, List<String>> headers = buildHeaders(baseUrl, deviceCode, product.getModel());
|
// Map<String, List<String>> headers = buildHeaders(baseUrl, deviceCode, product.getModel());
|
||||||
String url = baseUrl + "/shop/fulfillment-messages?" + URLUtil.buildQuery(queryMap, CharsetUtil.CHARSET_UTF_8);
|
// String url = baseUrl + "/shop/fulfillment-messages?" + URLUtil.buildQuery(queryMap, CharsetUtil.CHARSET_UTF_8);
|
||||||
try {
|
// try {
|
||||||
HttpResponse httpResponse = HttpRequest.get(url)
|
// HttpResponse httpResponse = HttpRequest.get(url)
|
||||||
.header(headers)
|
// .header(headers)
|
||||||
.execute();
|
// .execute();
|
||||||
if (!httpResponse.isOk()) {
|
// if (!httpResponse.isOk()) {
|
||||||
log.warn(">>>>>>>>>>请求可能过于频繁,请稍后再试~<<<<<<<<<<");
|
// log.warn(">>>>>>>>>>请求可能过于频繁,请稍后再试~<<<<<<<<<<");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
JSONObject responseJsonObject = JSON.parseObject(httpResponse.body());
|
// JSONObject responseJsonObject = JSON.parseObject(httpResponse.body());
|
||||||
JSONObject pickupMessage = responseJsonObject.getJSONObject("body").getJSONObject("content").getJSONObject("pickupMessage");
|
// JSONObject pickupMessage = responseJsonObject.getJSONObject("body").getJSONObject("content").getJSONObject("pickupMessage");
|
||||||
JSONArray stores = pickupMessage.getJSONArray("stores");
|
// JSONArray stores = pickupMessage.getJSONArray("stores");
|
||||||
if (stores == null) {
|
// if (stores == null) {
|
||||||
// log.info(pickupMessage.toString());
|
//// log.info(pickupMessage.toString());
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
if (stores.isEmpty()) {
|
// if (stores.isEmpty()) {
|
||||||
log.info("您所在的 {} 附近没有Apple直营店,请检查您的地址是否正确", location);
|
// log.info("您所在的 {} 附近没有Apple直营店,请检查您的地址是否正确", location);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
StringBuilder pushContentBuilder = new StringBuilder();
|
// StringBuilder pushContentBuilder = new StringBuilder();
|
||||||
List<String> availableStoreNameList = stores.stream()
|
// List<String> availableStoreNameList = stores.stream()
|
||||||
.filter(store -> filterStore((JSONObject) store))
|
// .filter(store -> filterStore((JSONObject) store))
|
||||||
.filter(k -> judgingStoreInventory((JSONObject) k, product.getModel()))
|
// .filter(k -> judgingStoreInventory((JSONObject) k, product.getModel()))
|
||||||
.map(store -> ((JSONObject) store).getString("storeName")
|
// .map(store -> ((JSONObject) store).getString("storeName")
|
||||||
.trim())
|
// .trim())
|
||||||
.collect(Collectors.toList());
|
// .collect(Collectors.toList());
|
||||||
if (CollectionUtils.isEmpty(availableStoreNameList)) {
|
// if (CollectionUtils.isEmpty(availableStoreNameList)) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
JSONObject storeJson = (JSONObject) stores.get(0);
|
// JSONObject storeJson = (JSONObject) stores.get(0);
|
||||||
JSONObject partsAvailability = storeJson.getJSONObject("partsAvailability");
|
// JSONObject partsAvailability = storeJson.getJSONObject("partsAvailability");
|
||||||
String deviceName = partsAvailability.getJSONObject(product.getModel()).getJSONObject("messageTypes").getJSONObject("regular").getString("storePickupProductTitle");
|
// String deviceName = partsAvailability.getJSONObject(product.getModel()).getJSONObject("messageTypes").getJSONObject("regular").getString("storePickupProductTitle");
|
||||||
pushContentBuilder.append("**")
|
// pushContentBuilder.append("**")
|
||||||
.append(deviceName)
|
// .append(deviceName)
|
||||||
.append("**")
|
// .append("**")
|
||||||
.append("今天可取货:")
|
// .append("今天可取货:")
|
||||||
.append("<br />");
|
// .append("<br />");
|
||||||
availableStoreNameList.forEach(availableStoreName ->
|
// availableStoreNameList.forEach(availableStoreName ->
|
||||||
pushContentBuilder.append("**")
|
// pushContentBuilder.append("**")
|
||||||
.append(availableStoreName)
|
// .append(availableStoreName)
|
||||||
.append("** <br />"));
|
// .append("** <br />"));
|
||||||
dingTalkMsgPushUtils.robotMarkdownMsgPush("苹果商店监控", "前往购买", "https://www.apple.com/" + countryCode + "/shop/buy-iphone/iphone-" + deviceCode, pushContentBuilder.toString());
|
// dingTalkMsgPushUtils.robotMarkdownMsgPush("苹果商店监控", "前往购买", "https://www.apple.com/" + countryCode + "/shop/buy-iphone/iphone-" + deviceCode, pushContentBuilder.toString());
|
||||||
} catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
log.error("AppleMonitor error", e);
|
// log.error("AppleMonitor error", e);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* build request headers
|
// * build request headers
|
||||||
*
|
// *
|
||||||
* @param baseUrl base country url
|
// * @param baseUrl base country url
|
||||||
* @param productCode product code
|
// * @param productCode product code
|
||||||
* @return headers
|
// * @return headers
|
||||||
*/
|
// */
|
||||||
private Map<String, List<String>> buildHeaders(String baseUrl, String deviceCode, String productCode) {
|
// private Map<String, List<String>> buildHeaders(String baseUrl, String deviceCode, String productCode) {
|
||||||
|
//
|
||||||
ArrayList<String> referer = new ArrayList<>();
|
// ArrayList<String> referer = new ArrayList<>();
|
||||||
referer.add(baseUrl + "/shop/buy-iphone/" + deviceCode + "/" + productCode);
|
// referer.add(baseUrl + "/shop/buy-iphone/" + deviceCode + "/" + productCode);
|
||||||
|
//
|
||||||
Map<String, List<String>> headers = new HashMap<>(10);
|
// Map<String, List<String>> headers = new HashMap<>(10);
|
||||||
headers.put(Header.REFERER.getValue(), referer);
|
// headers.put(Header.REFERER.getValue(), referer);
|
||||||
|
//
|
||||||
return headers;
|
// return headers;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private boolean filterStore(JSONObject storeInfo) {
|
// private boolean filterStore(JSONObject storeInfo) {
|
||||||
if (CollectionUtils.isEmpty(storeList)) {
|
// if (CollectionUtils.isEmpty(storeList)) {
|
||||||
return Boolean.TRUE;
|
// return Boolean.TRUE;
|
||||||
}
|
// }
|
||||||
String storeName = storeInfo.getString("storeName");
|
// String storeName = storeInfo.getString("storeName");
|
||||||
return storeList.stream()
|
// return storeList.stream()
|
||||||
.anyMatch(k -> storeName.contains(k) || k.contains(storeName));
|
// .anyMatch(k -> storeName.contains(k) || k.contains(storeName));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* check store inventory
|
// * check store inventory
|
||||||
*
|
// *
|
||||||
* @param storeJson store json
|
// * @param storeJson store json
|
||||||
* @param productCode product code
|
// * @param productCode product code
|
||||||
* @return boolean
|
// * @return boolean
|
||||||
*/
|
// */
|
||||||
private boolean judgingStoreInventory(JSONObject storeJson, String productCode) {
|
// private boolean judgingStoreInventory(JSONObject storeJson, String productCode) {
|
||||||
JSONObject partsAvailability = storeJson.getJSONObject("partsAvailability");
|
// JSONObject partsAvailability = storeJson.getJSONObject("partsAvailability");
|
||||||
String status = partsAvailability.getJSONObject(productCode).getString("pickupDisplay");
|
// String status = partsAvailability.getJSONObject(productCode).getString("pickupDisplay");
|
||||||
return "available".equals(status);
|
// return "available".equals(status);
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/**
|
// /**
|
||||||
* build pickup information
|
// * build pickup information
|
||||||
*
|
// *
|
||||||
* @param retailStore retailStore
|
// * @param retailStore retailStore
|
||||||
* @return pickup message
|
// * @return pickup message
|
||||||
*/
|
// */
|
||||||
private String buildPickupInformation(JSONObject retailStore) {
|
// private String buildPickupInformation(JSONObject retailStore) {
|
||||||
String distanceWithUnit = retailStore.getString("distanceWithUnit");
|
// String distanceWithUnit = retailStore.getString("distanceWithUnit");
|
||||||
String twoLineAddress = retailStore.getJSONObject("address").getString("twoLineAddress");
|
// String twoLineAddress = retailStore.getJSONObject("address").getString("twoLineAddress");
|
||||||
String daytimePhone = retailStore.getJSONObject("address").getString("daytimePhone");
|
// String daytimePhone = retailStore.getJSONObject("address").getString("daytimePhone");
|
||||||
String messageTemplate = "\n取货地址:{},电话:{},距离{}:{}";
|
// String messageTemplate = "\n取货地址:{},电话:{},距离{}:{}";
|
||||||
return CharSequenceUtil.format(messageTemplate, twoLineAddress.replace("\n", " "), daytimePhone, location, distanceWithUnit);
|
// return CharSequenceUtil.format(messageTemplate, twoLineAddress.replace("\n", " "), daytimePhone, location, distanceWithUnit);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Override
|
// @Override
|
||||||
@XxlJob("appleInventoryScheduleHandler")
|
// @XxlJob("appleInventoryScheduleHandler")
|
||||||
public ReturnT<String> execute(String params) throws Exception {
|
// public ReturnT<String> execute(String params) throws Exception {
|
||||||
if (!Boolean.TRUE.equals(appleInventoryMonitorSwitch)) {
|
// if (!Boolean.TRUE.equals(appleInventoryMonitorSwitch)) {
|
||||||
log.info(">>>>>>>>>>apple inventory monitor switch closed!<<<<<<<<<<");
|
// log.info(">>>>>>>>>>apple inventory monitor switch closed!<<<<<<<<<<");
|
||||||
return ReturnT.SUCCESS;
|
// return ReturnT.SUCCESS;
|
||||||
}
|
// }
|
||||||
// 获取设备信息
|
// // 获取设备信息
|
||||||
List<IphoneProductDto> products = iphoneProductParserUtils.getProducts(deviceCode, countryCode);
|
// List<IphoneProductDto> products = iphoneProductParserUtils.getProducts(deviceCode, countryCode);
|
||||||
//监视机型型号
|
// //监视机型型号
|
||||||
products.forEach(product -> {
|
// products.forEach(product -> {
|
||||||
this.doMonitor(product);
|
// this.doMonitor(product);
|
||||||
try {
|
// try {
|
||||||
Thread.sleep(2000);
|
// Thread.sleep(2000);
|
||||||
} catch (InterruptedException e) {
|
// } catch (InterruptedException e) {
|
||||||
log.error(">>>>>>>>>>apple inventory monitor error:{}<<<<<<<<<<", e.getMessage(), e);
|
// log.error(">>>>>>>>>>apple inventory monitor error:{}<<<<<<<<<<", e.getMessage(), e);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
return ReturnT.SUCCESS;
|
// return ReturnT.SUCCESS;
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
@ -14,6 +14,10 @@ import top.baogutang.common.domain.Results;
|
|||||||
import top.baogutang.common.utils.JacksonUtil;
|
import top.baogutang.common.utils.JacksonUtil;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import static top.baogutang.common.config.MdcRequestIdFilter.REQUEST_ID_KEY;
|
||||||
|
import static top.baogutang.common.config.MdcRequestIdFilter.CLIENT_IP_KEY;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description:
|
* @description:
|
||||||
@ -39,23 +43,36 @@ public class LogAspect {
|
|||||||
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
|
||||||
assert sra != null;
|
assert sra != null;
|
||||||
HttpServletRequest request = sra.getRequest();
|
HttpServletRequest request = sra.getRequest();
|
||||||
String requestId = MDC.get("X-Request-Id");
|
String requestId = MDC.get(REQUEST_ID_KEY);
|
||||||
|
String clientIp = MDC.get(CLIENT_IP_KEY);
|
||||||
long startMills = System.currentTimeMillis();
|
long startMills = System.currentTimeMillis();
|
||||||
long cost = 0;
|
long cost = 0;
|
||||||
try {
|
try {
|
||||||
result = pjp.proceed();
|
result = pjp.proceed();
|
||||||
cost = System.currentTimeMillis() - startMills;
|
cost = System.currentTimeMillis() - startMills;
|
||||||
log.info("请求结束!本次请求耗时:{},url: {}, method: {}, params: {},user:{}, token: {}, 响应结果:{}",
|
log.info("请求结束! client ip:{},本次请求耗时:{},url: {}, method: {}, params: {},user:{}, token: {}, 响应结果:{}",
|
||||||
cost, request.getRequestURL().toString(),
|
clientIp,
|
||||||
request.getMethod(), pjp.getArgs(), JacksonUtil.toJson(request.getAttribute("user")), request.getHeader("authorization"),
|
cost,
|
||||||
|
request.getRequestURL().toString(),
|
||||||
|
request.getMethod(),
|
||||||
|
pjp.getArgs(),
|
||||||
|
JacksonUtil.toJson(request.getAttribute("user")),
|
||||||
|
request.getHeader("authorization"),
|
||||||
JacksonUtil.toJson(result));
|
JacksonUtil.toJson(result));
|
||||||
if (result instanceof Results) {
|
if (result instanceof Results) {
|
||||||
Results r = (Results) result;
|
Results<?> r = (Results<?>) result;
|
||||||
r.setRid(requestId);
|
r.setRid(requestId);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("请求异常!!!本次请求耗时:{},error:{},url: {}, method: {}, params: {},user:{}, token: {}", cost, e, request.getRequestURL().toString(),
|
log.error("请求异常!!! client ip:{},本次请求耗时:{},error:{},url: {}, method: {}, params: {},user:{}, token: {}",
|
||||||
request.getMethod(), pjp.getArgs(), JacksonUtil.toJson(request.getAttribute("user")), request.getHeader("token"));
|
clientIp,
|
||||||
|
cost,
|
||||||
|
e.getMessage(),
|
||||||
|
request.getRequestURL().toString(),
|
||||||
|
request.getMethod(),
|
||||||
|
pjp.getArgs(),
|
||||||
|
JacksonUtil.toJson(request.getAttribute("user")),
|
||||||
|
request.getHeader("token"));
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@ -23,22 +23,92 @@ import java.util.UUID;
|
|||||||
@Order(1)
|
@Order(1)
|
||||||
public class MdcRequestIdFilter extends OncePerRequestFilter {
|
public class MdcRequestIdFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
private static final String REQUEST_ID_KEY = "X-Request-Id";
|
public static final String REQUEST_ID_KEY = "X-Request-Id";
|
||||||
|
public static final String CLIENT_IP_KEY = "clientIp";
|
||||||
|
|
||||||
|
// 静态资源后缀列表
|
||||||
|
private static final String[] STATIC_RESOURCES = {
|
||||||
|
".css", ".js", ".jpg", ".jpeg", ".png", ".gif", ".ico", ".svg", ".woff", ".woff2", ".ttf", ".eot", ".map", ".gz", ".rar", ".zip", ".7z", ".pdf",
|
||||||
|
".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".txt", ".mp3", ".mp4", ".avi", ".wmv", ".flv", ".swf", ".exe", ".dll", ".ico", ".psd", ".ai",
|
||||||
|
".eps", ".svg", ".ttf", ".woff", ".woff2", ".eot", ".otf", ".otc", ".ttc", ".ttf", ".woff", ".woff2", ".eot", ".otf", "json"
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
// 判断是否为静态资源请求
|
||||||
|
String uri = request.getRequestURI();
|
||||||
|
if (isStaticResource(uri)) {
|
||||||
|
// 静态资源请求直接放行,不处理
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 获取真实客户端IP
|
||||||
|
String clientIp = getClientIp(request);
|
||||||
|
MDC.put(CLIENT_IP_KEY, clientIp);
|
||||||
String traceId = request.getHeader(REQUEST_ID_KEY);
|
String traceId = request.getHeader(REQUEST_ID_KEY);
|
||||||
if (traceId == null) {
|
if (traceId == null) {
|
||||||
traceId = UUID.randomUUID().toString().replace("-", "");
|
traceId = UUID.randomUUID().toString().replace("-", "");
|
||||||
log.info("requestId为空,自动生成 {}", traceId);
|
log.info("requestId为空,自动生成 {}, client ip: {}", traceId, clientIp);
|
||||||
request.setAttribute(REQUEST_ID_KEY, traceId);
|
request.setAttribute(REQUEST_ID_KEY, traceId);
|
||||||
}
|
}
|
||||||
MDC.put(REQUEST_ID_KEY, traceId);
|
MDC.put(REQUEST_ID_KEY, traceId);
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
} finally {
|
} finally {
|
||||||
MDC.remove(REQUEST_ID_KEY);
|
MDC.remove(REQUEST_ID_KEY);
|
||||||
|
MDC.remove(CLIENT_IP_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为静态资源请求
|
||||||
|
*/
|
||||||
|
private boolean isStaticResource(String uri) {
|
||||||
|
if (uri == null || uri.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String lowerUri = uri.toLowerCase();
|
||||||
|
for (String suffix : STATIC_RESOURCES) {
|
||||||
|
if (lowerUri.endsWith(suffix)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取客户端真实IP地址
|
||||||
|
* 优先从代理请求头中获取,如果没有则使用remoteAddr
|
||||||
|
*/
|
||||||
|
private String getClientIp(HttpServletRequest request) {
|
||||||
|
String ip = request.getHeader("X-Forwarded-For");
|
||||||
|
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
// X-Forwarded-For可能包含多个IP,取第一个
|
||||||
|
if (ip.indexOf(",") > 0) {
|
||||||
|
ip = ip.substring(0, ip.indexOf(","));
|
||||||
|
}
|
||||||
|
return ip.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = request.getHeader("X-Real-IP");
|
||||||
|
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
return ip.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = request.getHeader("Proxy-Client-IP");
|
||||||
|
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
return ip.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
|
||||||
|
return ip.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果所有代理头都没有,使用remoteAddr
|
||||||
|
return request.getRemoteAddr();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user