本次主要是賞析作者的第一次提交intialized project辰如,這次提交主要把項(xiàng)目的雛形搭建起來(lái)和單元測(cè)試兩部分內(nèi)容嘱腥。
先從項(xiàng)目的組織框架來(lái)看殿雪,項(xiàng)目共有八個(gè)類(lèi)钧栖,其中Moco類(lèi)是入口嘿悬,有server()方法和running()方法实柠,server()方法的作用是新創(chuàng)建一個(gè)MocoServer對(duì)象并返回,running()方法則是啟動(dòng)該MocoServer對(duì)象善涨。MocoServer類(lèi)是服務(wù)器類(lèi)窒盐,有啟動(dòng)、停止钢拧、response等方法蟹漓。MocoHandler類(lèi)繼承了SimpleChannelHandler類(lèi),重寫(xiě)了messageReceived()方法娶靡,當(dāng)收到request后牧牢,負(fù)責(zé)把RequestSetting寫(xiě)入response返回。RequestSetting姿锭、BaseRequestSetting塔鳍、AnyRequestSetting、URIRequestSetting呻此、ContentRequestSetting這五個(gè)類(lèi)的關(guān)系如下:
其中三個(gè)RequestSetting實(shí)現(xiàn)類(lèi)是針對(duì)不同的request輸入類(lèi)型或不同的請(qǐng)求方式轮纫,所做的三種不同的處理方法。
下面看一些具體的代碼焚鲜,
public void response(String response) {
new AnyRequestSetting(this).response(response);
}
public BaseRequestSetting withContent(String requestContent) {
return new ContentRequestSetting(this, requestContent);
}
public BaseRequestSetting withUri(String uri) {
return new UriRequestSetting(this, uri);
}
這三個(gè)方法分別對(duì)應(yīng)Request中的三種不同的輸入或請(qǐng)求方式:get請(qǐng)求掌唾、post請(qǐng)求放前、輸入為uri(addrA/addrB)。根據(jù)不同的輸入糯彬,new出來(lái)不同的RequestSetting對(duì)象裝入response中凭语。
RequestSetting的五個(gè)類(lèi)中多次運(yùn)用了多態(tài),如:RequestSetting中的addToServer()抽象方法撩扒,在BaseRequestSetting中得到了重寫(xiě)似扔、BaseRequestSetting中match()方法是個(gè)抽象方法,三個(gè)實(shí)現(xiàn)類(lèi)分別重寫(xiě)了這個(gè)方法搓谆,擁有了針對(duì)不同的輸入的不同處理方法炒辉。
public abstract boolean match(HttpRequest request);
public boolean match(HttpRequest request) {
return true;
}
public boolean match(HttpRequest request) {
long contentLength = HttpHeaders.getContentLength(request);
ChannelBuffer contentBuffer = request.getContent();
String content = contentBuffer.toString((int) (contentBuffer.capacity() - contentLength), (int) contentLength, Charset.defaultCharset());
return content.equals(this.content);
}
public boolean match(HttpRequest request) {
return (request.getUri().equals(uri));
}
在這版代碼中,由于下兩段代碼中的isMatchAny被作者在三個(gè)RequestSetting的實(shí)現(xiàn)類(lèi)中均置為false泉手,所以有兩部分代碼是不會(huì)被訪問(wèn)的黔寇。我想作者這么做一定是有意為之,目的是為了針對(duì)不同的業(yè)務(wù)需求而做更好的擴(kuò)展斩萌,且等日后繼續(xù)看后面的代碼~
if (requestSetting.isMatchAny()) {
this.anyRequestSetting = requestSetting;
}
if (anyRequestSetting != null) {
channel.write(createResponse(anyRequestSetting));
} else {
channel.write(new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
}