接手的旧项目中有一段定位网段的代码,逻辑是 先匹配自定义网段->再匹配内置网段->最后是未知网段,使用责任链模式后类图如下:
责任连的顶级处理类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);
}
}
使用:
//这里改成责任链调用 Handler.Builder builder = new Handler.Builder(); builder.addHandler(new CustomNetSegHandler()) .addHandler(new InnerAbcNetSegHandler()) .addHandler(new UnknownNetSegHandler()); result = builder.build().doHandler(result, originBigIntIp, ip, this); log.debug("--定位到的网段:--" + result);