您现在的位置是:主页 > news > 新手做网站什么内容比较好/互动营销案例都有哪些
新手做网站什么内容比较好/互动营销案例都有哪些
admin2025/6/18 0:48:47【news】
简介新手做网站什么内容比较好,互动营销案例都有哪些,微信小程序怎么做网站,网页设计旅游网站1 请求获取与包装处理 本章节对http请求到服务端,从监听到处理展现给大家。在上文中有分析Connector在启动的时候会监听端口。继续以JIoEndpoint为例,在其Accptor类中: protected class Acceptor extends AbstractEndpoint.Acceptor {Overrid…
1 请求获取与包装处理
本章节对http请求到服务端,从监听到处理展现给大家。
在上文中有分析Connector在启动的时候会监听端口。继续以JIoEndpoint为例,在其Accptor类中:
protected class Acceptor extends AbstractEndpoint.Acceptor {@Overridepublic void run() {while (running) {……try {//当前连接数countUpOrAwaitConnection();Socket socket = null;try {//取出队列中的连接请求socket = serverSocketFactory.acceptSocket(serverSocket);} catch (IOException ioe) {countDownConnection();}if (running && !paused && setSocketOptions(socket)) {//处理请求if (!processSocket(socket)) {countDownConnection();closeSocket(socket);}} else {countDownConnection();// Close socket right awaycloseSocket(socket);}} ……}}
}
在上面的代码中,socket = serverSocketFactory.acceptSocket(serverSocket);与客户端建立连接,将连接的socket交给processSocket(socket)来处理。在processSocket中,对socket进行包装一下交给线程池来处理:
protected boolean processSocket(Socket socket) {try {SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());wrapper.setSecure(isSSLEnabled());//交给线程池处理连接getExecutor().execute(new SocketProcessor(wrapper));} ……return true;
}
线程池处理的任务SocketProccessor,通过代码分析:
protected class SocketProcessor implements Runnable {protected SocketWrapper<Socket> socket = null;protected SocketStatus status = null;@Overridepublic void run() {boolean launch = false;synchronized (socket) {SocketState state = SocketState.OPEN;try {serverSocketFactory.handshake(socket.getSocket());} ……if ((state != SocketState.CLOSED)) {//委派给Handler来处理if (status == null) {state = handler.process(socket, SocketStatus.OPEN_READ);} else {state = handler.process(socket,status);}}}}……
}
即在SocketProcessor中,将Socket交给handler处理,这个handler就是在Http11Protocol的构造方法中赋值的Http11ConnectionHandler,在该类的父类process方法中通过请求的状态,来创建Http11Processor处理器进行相应的处理,切到Http11Proccessor的父类AbstractHttp11Proccessor中。
public SocketState process(SocketWrapper socketWrapper) {RequestInfo rp = request.getRequestProcessor();rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);// Setting up the I/OsetSocketWrapper(socketWrapper);getInputBuffer().init(socketWrapper, endpoint);getOutputBuffer().init(socketWrapper, endpoint);while (!getErrorState().isError() && keepAlive && !comet && !isAsync() &&upgradeInbound == null &&httpUpgradeHandler == null && !endpoint.isPaused()) {……if (!getErrorState().isError()) {// Setting up filters, and parse some request headersrp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);try {//请求预处理prepareRequest();} ……}……if (!getErrorState().isError()) {try {rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);//交由适配器处理adapter.service(request, response);if(keepAlive && !getErrorState().isError() && (response.getErrorException() != null ||(!isAsync() &&statusDropsConnection(response.getStatus())))) {setErrorState(ErrorState.CLOSE_CLEAN, null);}setCometTimeouts(socketWrapper);} }}……
}
代码很长,删掉的部分比较多,在这个方法里面,可以看到Request和Response的生成,从Socket中获取请求数据,keep-alive处理,数据包装等等信息,最后交给了CoyoteAdapter的service方法
2 请求传递给Container
在CoyoteAdapter的service方法中,主要有2个任务:
- 第一个是org.apache.coyote.Request和org.apache.coyote.Response到继承自HttpServletRequest的org.apache.catalina.connector.Request和org.apache.catalina.connector.Response转换,和Context,Wrapper定位。
- 第二个是将请求交给StandardEngineValve处理。
public void service(org.apache.coyote.Request req,org.apache.coyote.Response res) {……postParseSuccess = postParseRequest(req, request, res, response);……connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);……
}
在postParseRequest方法中代码片段:
connector.getMapper().map(serverName, decodedURI, version,request.getMappingData());
request.setContext((Context) request.getMappingData().context);
request.setWrapper((Wrapper) request.getMappingData().wrapper);
request通过URI的信息找到属于自己的Context和Wrapper。而这个Mapper保存了所有的容器信息,不记得的同学可以回到Connector的startInternal方法中,最有一行代码是mapperListener.start();
在MapperListener的start()方法中,
public void startInternal() throws LifecycleException {setState(LifecycleState.STARTING);findDefaultHost();Engine engine = (Engine) connector.getService().getContainer();addListeners(engine);Container[] conHosts = engine.findChildren();for (Container conHost : conHosts) {Host host = (Host) conHost;if (!LifecycleState.NEW.equals(host.getState())) {registerHost(host);}}
}
MapperListener.startInternal()方法将所有Container容器信息保存到了mapper中。那么,现在初始化把所有容器都添加进去了,如果容器变化了将会怎么样?这就是上面所说的监听器的作用,容器变化了,MapperListener作为监听者。他的生成图示:
通过Mapper找到了该请求对应的Context和Wrapper后,CoyoteAdapter将包装好的请求交给Container处理。
3 Container处理请求流程
从下面的代码片段,我们很容易追踪整个Container的调用链:
用时序图画出来则是:
最终StandardWrapperValve将请求交给Servlet处理完成
pipeline+valve处理:
系列文章直达:
初始化与启动:https://yq.aliyun.com/articles/20169?spm=0.0.0.0.4yGfpo
容器:https://yq.aliyun.com/articles/20172?spm=0.0.0.0.2uPEZi
连接器:https://yq.aliyun.com/articles/20175?spm=0.0.0.0.2uPEZi
一个http请求的经历:https://yq.aliyun.com/articles/20177?spm=0.0.0.0.2uPEZi
重要的设计模式:https://yq.aliyun.com/articles/20179?spm=0.0.0.0.2uPEZi