接手的舊項目中有一段定位網段的代碼,邏輯是 先比對自定義網段->再比對内置網段->最後是未知網段,使用責任鍊模式後類圖如下:
責任連的頂級處理類handler:
/**
* @author dxy
* @descrition 網段定位處理器
*/
public abstract class Handler<T> {
protected Handler next;
public void next(Handler next) {
this.next = next;
}
/**
* 鈎子方法1 不帶标記的
* @param result
* @param originBigIntIp
* @param ip
* @param intranetIpNetworkSegmentService
*/
public abstract IntranetIpNetworkSegment doHandler(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService);
/**
*
* @param result
* @param originBigIntIp
* @param ip
* @param state
* @param intranetIpNetworkSegmentService
* @return
*/
public abstract IntranetIpNetworkSegment doHandlerWithFlag(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state);
public static class Builder<T> {
private Handler<T> head;
private Handler<T> tail;
public Builder<T> addHandler(Handler handler) {
if (this.head == null) {
this.head = this.tail = handler;
return this;
}
this.tail.next(handler);
this.tail = handler;
return this;
}
public Handler<T> build() {
return this.head;
}
}
}
自定義網段處理:
/**
* @author dxy
* @descrition 自定義網段比對處理器
*/
public class CustomNetSegHandler extends Handler {
@Override
public IntranetIpNetworkSegment doHandler(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService) {
result = getIntranetIpNetworkSegment(result, originBigIntIp, intranetIpNetworkSegmentService, null);
//這裡已經定位到網端 不向下傳遞
if (result != null) {
return result;
} else {
//這裡交給下個個責任鍊
return next.doHandler(result, originBigIntIp, ip, intranetIpNetworkSegmentService);
}
}
@Override
public IntranetIpNetworkSegment doHandlerWithFlag(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
result = getIntranetIpNetworkSegment(result, originBigIntIp, intranetIpNetworkSegmentService, state);
//這裡已經定位到網端 不向下傳遞
if (result != null) {
return result;
} else {
//這裡交給下個個責任鍊
return next.doHandlerWithFlag(result, originBigIntIp, ip, intranetIpNetworkSegmentService, state);
}
}
/**
* 共用的定位網段方法
*
* @param result
* @param originBigIntIp
* @param intranetIpNetworkSegmentService
* @param state
* @return
*/
private IntranetIpNetworkSegment getIntranetIpNetworkSegment(IntranetIpNetworkSegment result, BigInteger originBigIntIp, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
// 現有的自定義網段,轉化為兩個端點的set
LinkedHashSet<IntranetIpNetworkSegmentServiceImpl.BigIntNetSeg> allCustomNetSegs = intranetIpNetworkSegmentService.getAllIpSet(Arrays.asList(CUSTOM_INTRANET_NETWORK_SEGMENT_ID));
//周遊netSeg
for (IntranetIpNetworkSegmentServiceImpl.BigIntNetSeg netSeg : allCustomNetSegs) {
//參數ip在網段範圍内
if (intranetIpNetworkSegmentService.isInNetSeg(originBigIntIp, netSeg)) {
result = intranetIpNetworkSegmentService.findById(netSeg.getNetSegId());
}
}
return result;
}
}
内置網段處理:
/**
* @author dxy
* @descrition 内置網段處理
*/
public class InnerAbcNetSegHandler extends Handler {
@Override
public IntranetIpNetworkSegment doHandler(IntranetIpNetworkSegment result, BigInteger originBigIntIp,String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService) {
//這裡說明自定義網段 沒有比對到 比對abc
result = getIntranetIpNetworkSegment(result, originBigIntIp, intranetIpNetworkSegmentService, null);
//這裡已經定位到網端 不向下傳遞
if (result != null) {
return result;
} else {
//這裡交給下個個責任鍊
return next.doHandler(result, originBigIntIp, ip, intranetIpNetworkSegmentService);
}
}
@Override
public IntranetIpNetworkSegment doHandlerWithFlag(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
result = getIntranetIpNetworkSegment(result, originBigIntIp, intranetIpNetworkSegmentService, state);
//這裡已經定位到網端 不向下傳遞
if (result != null) {
return result;
} else {
//這裡交給下個個責任鍊
return next.doHandlerWithFlag(result, originBigIntIp, ip, intranetIpNetworkSegmentService, state);
}
}
private IntranetIpNetworkSegment getIntranetIpNetworkSegment(IntranetIpNetworkSegment result, BigInteger originBigIntIp, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService,State state) {
if (result == null) {
LinkedHashSet<IntranetIpNetworkSegmentServiceImpl.BigIntNetSeg> innerNetSegs = intranetIpNetworkSegmentService.getAllIpSet(Arrays.asList(A_INTRANET_NETWORK_SEGMENT_ID, B_INTRANET_NETWORK_SEGMENT_ID, C_INTRANET_NETWORK_SEGMENT_ID));
//周遊netSeg
for (IntranetIpNetworkSegmentServiceImpl.BigIntNetSeg netSeg : innerNetSegs) {
//參數ip在網段範圍内
if (intranetIpNetworkSegmentService.isInNetSeg(originBigIntIp, netSeg)) {
result = intranetIpNetworkSegmentService.findById(netSeg.getNetSegId());
}
}
}
return result;
}
}
未知網段處理:
/**
* @author dxy
* @descrition 未知網段處理
*/
public class UnknownNetSegHandler extends Handler {
@Override
public IntranetIpNetworkSegment doHandler(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService) {
return getIntranetIpNetworkSegment(result, ip, intranetIpNetworkSegmentService, null);
}
private IntranetIpNetworkSegment getIntranetIpNetworkSegment(IntranetIpNetworkSegment result, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
//這裡說明自定義網段 abc 都沒有比對到 放未知 并建立網段
if (result == null) {
if (ValidateUtil.isIpv6(ip)) {
int defaultMaskBit = 64;
result = new IntranetIpNetworkSegment();
String ipv6Network = ip + Ipv4Util.IP_MASK_SPLIT_MARK + defaultMaskBit;
IPv6Network network = IPv6Network.fromString(ipv6Network);
String netSegBeginIp = network.getFirst().toLongString();
String netSegEndIp = network.getLast().toLongString();
//檢查是否和目前網段重複 & 合法(前面小于後面)
boolean isRight = checkNetSegCorrect(netSegBeginIp, netSegEndIp);
Assert.isTrue(isRight, "輸入的網段不合法!");
if (intranetIpNetworkSegmentService.checkDuplicateIp(netSegBeginIp, netSegEndIp)) {
//沒問題,建立64位子網字首
result.setSecurityDomainId(ProjectConstant.UNKNOWN_SEC_DOM_ID);
result.setNetworkSegmentName(ipv6Network);
result.setNetworkSegmentStartIp(netSegBeginIp);
result.setNetworkSegmentStopIp(netSegEndIp);
} else {
//如果重複了
result.setSecurityDomainId(ProjectConstant.UNKNOWN_SEC_DOM_ID);
result.setNetworkSegmentName(ip + Ipv4Util.IP_MASK_SPLIT_MARK + 128);
result.setNetworkSegmentStartIp(ip);
result.setNetworkSegmentStopIp(ip);
}
} else {//ipv4的情況下
int defaultMaskBit = 24;
// 如果沒有比對到,在未知安全域下建立網段,并傳回ID,關聯起來
String netSegBeginIp = Ipv4Util.getBeginIpStr(ip, defaultMaskBit);
String netSegEndIp = Ipv4Util.getEndIpStr(ip, defaultMaskBit);
result = new IntranetIpNetworkSegment();
//檢查是否和目前網段重複 & 合法
boolean isRight = checkNetSegCorrect(netSegBeginIp, netSegEndIp);
Assert.isTrue(isRight, "輸入的網段不合法!");
if (intranetIpNetworkSegmentService.checkDuplicateIp(netSegBeginIp, netSegEndIp)) {
//沒問題,建立24位掩碼網段
result.setSecurityDomainId(ProjectConstant.UNKNOWN_SEC_DOM_ID);
result.setNetworkSegmentName(ip + Ipv4Util.IP_MASK_SPLIT_MARK + defaultMaskBit);
result.setNetworkSegmentStartIp(netSegBeginIp);
result.setNetworkSegmentStopIp(netSegEndIp);
} else {
//如果重複了
result.setSecurityDomainId(ProjectConstant.UNKNOWN_SEC_DOM_ID);
result.setNetworkSegmentName(ip + Ipv4Util.IP_MASK_SPLIT_MARK + 32);
result.setNetworkSegmentStartIp(ip);
result.setNetworkSegmentStopIp(ip);
}
}
if (state != null) {
result.setDataSourceFlag(state);
}
intranetIpNetworkSegmentService.save(result);
}
return result;
}
@Override
public IntranetIpNetworkSegment doHandlerWithFlag(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
return getIntranetIpNetworkSegment(result, ip, intranetIpNetworkSegmentService, state);
}
}
使用: