Filters in Coyote

不知道Filter是哪位牛人的创意,反正现在的编程框架中到处可见filter的身影,例如struts2、servlet等等。就连tomcat内部的实现,同样也少不了filter

接口:InputFilter OutputFilter

InputFilter OutputFilter都是继承自InputBuffer的接口,两个接口大同小异,下面以InputFilter为例,介绍主要的方法

  • public int doRead(ByteChunk chunk, Request unused):从chunk中读取数据,保存到filter内部。至于那个Request,很明显是作废了的
  • public void setRequest(Request request):设置request,这是因为某些filter需要request中额外的信息
  • public void setBuffer(InputBuffer buffer):设置下一个filter。因此coyote的filter和其他编程框架的类似,都是以pipeline的形式存在的,一个接一个

setup the filter

如何把这些filter装配起来呢?这一节涉及到的内容与 org.apache.coyote.http11.Http11Processor和InternalInputBuffer 有关

首先,在Http11Processor的prepareRequest()方法中,有关于装配filter的代码:

addInputFilter(inputFilters, encodingName);

而在这个方法中,又有如下代码:

if (encodingName.equals("identity")) {
            // Skip
        } else if (encodingName.equals("chunked")) {
            inputBuffer.addActiveFilter
                (inputFilters[Constants.CHUNKED_FILTER]);
            contentDelimitation = true;
        } else {
            for (int i = 2; i < inputFilters.length; i++) {
                if (inputFilters[i].getEncodingName()
                    .toString().equals(encodingName)) {
                    inputBuffer.addActiveFilter(inputFilters[i]);
                    return true;
                }
            }
            return false;
        }

 

核心代码还是在InternalInputBuffer 类的addActiveFilter方法中,这里才是真正“安装”filter

public void addActiveFilter(InputFilter filter) {

        if (lastActiveFilter == -1) {
            filter.setBuffer(inputStreamInputBuffer);
        } else {
            for (int i = 0; i <= lastActiveFilter; i++) {
                if (activeFilters[i] == filter)
                    return;
            }
            filter.setBuffer(activeFilters[lastActiveFilter]);
        }

        activeFilters[++lastActiveFilter] = filter;

        filter.setRequest(request);

    }

在上面的代码中,调用了刚才说到的filter.setBuffer方法,相当于把新加进来的fitler指向activeFilters的最后一个,可见activeFilters相当于一个堆栈,数组第一个元素相当于堆栈的底部

org.apache.coyote.http11.filters.ChunkedInputFilter

前面已经描述了filter是怎么组装起来的,现在以ChunkedInputFilter为例,主要分析一下InputBuffer.doRead这个很关键的接口方法。

这个filter的作用是解析http字节流中,被chunked了的报文内容(具体的可以参考http规范,据称是http1.1针对长连接的一种传输格式,也可参考我后来发的博客 http://blog.csdn.net/wangchengsi/archive/2009/03/22/4013821.aspx

filter.setBuffer方法的参数是InputBuffer,故filter要取得http字节流,必定只能通过InputBuffer唯一的一个方法doRead来实现。过程大致如下:

前一个filter通过调用ChunkedInputFilter.doRead方法,可以从中获得所需的数据,而在ChunkedInputFilter.doRead中,ChunkedInputFilter本身又会调用自己前面的那个filter的doRead方法,如此递归下去直到最开头的filter(也就是activeFilters数组的第一个元素)

为了更加清楚地说明整个filter链路的处理过程,假设某个InternalInputBuffer有如下的filter链:

socket  JIOEndpoint   filter1 <- filter2 <- ..... <- filterN

JIOEndpoint 把socket交给coyote后,经过若干工序,字节流放入 InternalInputBuffer 的 filter1中;然后,调用 InputBuffer的doRead (因为coyote中几乎所有类都是InputBuffer),该doRead调用层层递归,到达 filterN,然后再沿着filter链递归至 filter1,完成数据的“过滤”。最后生成的Request才交给最外围的容器

附带 InternalInputBuffer 的doRead,从这里开始递归调用 filter

public int doRead(ByteChunk chunk, Request req)
        throws IOException {

        if (lastActiveFilter == -1)
            return inputStreamInputBuffer.doRead(chunk, req);
        else
           return activeFilters[lastActiveFilter].doRead(chunk,req);

    }

Coyote Optimization Algorithm(COA)是一种模拟动物行为的优化算法,最早由塞尔柔夫·奈索帕洛斯(Serrouf Nacer Eddine)于2014年提出。COA受到了美洲土狼(coyote)的求生行为的启发,并模拟了其狩猎和社会行为。 COA的基本思想是将问题建模为群体中的个体通过相互合作来求解问题的过程。在COA中,将问题的解看作是“食物”,而个体则像土狼一样通过合作来获取食物。这个过程基于两个主要行为:探索和捕食。 在COA的初始阶段,个体会进行探索行为,类似于土狼在陌生领地中搜寻食物的过程。个体会根据其个体记忆和群体信息进行局部搜索,并尝试找到更好的解。在探索过程中,个体也会利用其他个体的信息来优化其搜索路径。 一旦个体找到了更好的解,它会通过捕食行为将其分享给其他个体。在这个过程中,个体会传递优秀解的信息和自身记忆,并与其他个体进行信息交流。通过这种社会行为,个体可以学习和优化自己的搜索策略。 COA的优点在于可以处理各种类型的优化问题,并且具有较强的全局搜索能力和收敛性。它在多个领域中得到了广泛的应用,如物流优化、图像处理、机器学习等。 总之,Coyote Optimization Algorithm是一种模拟土狼行为的优化算法,通过个体间的合作和信息交流来求解问题。它的独特设计使得它适用于各种优化问题,并具有全局搜索和迭代优化的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值