淺談web服務(wù)器項(xiàng)目中靜態(tài)請(qǐng)求和動(dòng)態(tài)請(qǐng)求處理
在處理了核心任務(wù)之后,我們會(huì)發(fā)現(xiàn)有些請(qǐng)求并不是都是靜態(tài)的,那么我們就需要進(jìn)行實(shí)現(xiàn)處理動(dòng)態(tài)請(qǐng)求的要求,如下面代碼是我們請(qǐng)求的解決方式,我們只需在HttpRequestImpl實(shí)現(xiàn)類中,將如下代碼實(shí)現(xiàn)具體的判斷過程
//判斷當(dāng)前請(qǐng)求的否是靜態(tài)資源 public boolean isStaticResource(){ return true; } //判斷當(dāng)前請(qǐng)求的否是動(dòng)態(tài)資源 public boolean isDynamicResource(){ return true; }
1、實(shí)現(xiàn)isStaticResource()方法:
// 判斷當(dāng)前請(qǐng)求的否是靜態(tài)資源 public boolean isStaticResource() { // 存在??文件??靜態(tài)?? System.out.println("進(jìn)入isStaticResource()方法"); if (requestPath != null) { String parent = ConfigUtils.getConfigValue("rootPath"); File file = new File(parent, requestPath); return file.exists() && file.isFile(); } return false; }
2、實(shí)現(xiàn)isDynamicResource():
// 判斷當(dāng)前請(qǐng)求的否是動(dòng)態(tài)資源 public boolean isDynamicResource() { // 存在??文件??動(dòng)態(tài)?? System.out.println("進(jìn)入isDynamicResource()方法"); String path = ServletMappingUtils.getMappingValue(requestPath); /* * //使用路徑判斷,當(dāng)時(shí)我不知道還有一個(gè)叫做isContains(key)的方法,如果知道的話 就可以使用了,請(qǐng)參見測試類 * if(isContainers(requestPath())) { return *; } */ System.out.println("ServletMapping中根據(jù)requestPath獲取的映射:" + path); if (path != null) { return true; } return false; }
在動(dòng)態(tài)方法中,我們String path = ServletMappingUtils.getMappingValue(requestPath);來獲取請(qǐng)求的資源的路徑,如果存在值的話就返回結(jié)果,其實(shí)現(xiàn)如下所示,對(duì)于servlet_mapping.properties文件,還是復(fù)制到項(xiàng)目下即可:
package com.sample.utils; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class ServletMappingUtils { private static Properties p; static { InputStream in=null; p=new Properties(); try { //讀了xx.properties文件 in=ServletMappingUtils.class.getResourceAsStream("servlet_mapping.properties"); //放置到p中,即放properties文件中的key,value p.load(in); } catch (IOException e) { e.printStackTrace(); } finally { if(in!=null) try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } public static String getMappingValue(String mapping) { return p.getProperty(mapping); } public static boolean isContainsKey(String key) { return p.containsKey(key); } public static void main(String[] args) {//輸出測試 // Properties p=new Properties(); // p.setProperty("rootPath","ddd"); // System.out.println(p.get("rootPath")); System.out.println(getMappingValue("/HelloWorld")); System.out.println(isContainsKey("/Login")); } }
3、實(shí)現(xiàn)對(duì)靜態(tài)請(qǐng)求和動(dòng)態(tài)請(qǐng)求的封裝
在處理完基本的功能性要求之后,我們實(shí)現(xiàn)對(duì)核心任務(wù)取得封裝,在封裝時(shí),我們?nèi)匀徊捎妙悓?shí)現(xiàn)接口的方式,首先我們需要明確該確定一個(gè)怎么樣的接口,其代碼如下:
package com.sample.http; //Http資源處理器 //負(fù)責(zé)處理http協(xié)議的資源請(qǐng)求 public interface HttpAccessProcessor { //處理靜態(tài)資源 頁面/文件/圖片等等 public void processStaticResource(HttpRequest request,HttpResponse response); //處理動(dòng)態(tài)資源 java代碼 瀏覽器通過路徑發(fā)送請(qǐng)求可以訪問調(diào)用java代碼 public void processDynamicResource(HttpRequest request,HttpResponse response); //向?yàn)g覽器返回錯(cuò)誤信息及其頁面 public void sendError(int statusCode,HttpRequest request,HttpResponse response); }
其實(shí)現(xiàn)類如下所示:
package com.sample.http; import com.sample.utils.ServletMappingUtils; //Http資源處理器 //負(fù)責(zé)處理http協(xié)議的資源請(qǐng)求 public class HttpAccessProcessorImpl implements HttpAccessProcessor { //處理靜態(tài)資源 頁面/文件/圖片等等 public void processStaticResource(HttpRequest request,HttpResponse response) { System.out.println("進(jìn)入方法processStaticResource(HttpRequest request,HttpResponse response)"); //獲取請(qǐng)求中資源,并處理 String path=request.getRequestPath(); String[] str=path.split("[.]"); String contentType=str[str.length-1]; System.out.println("路徑的后綴:"+contentType); response.setStatusLine(200); response.setContentType(MIMEUtils.getMimeValue(contentType)); response.setCRLF(); response.printResponseHeader(); response.printResponseContent(request.getRequestPath()); } //處理動(dòng)態(tài)資源 java代碼 瀏覽器通過路徑發(fā)送請(qǐng)求可以訪問調(diào)用java代碼 public void processDynamicResource(HttpRequest request,HttpResponse response) { System.out.println("進(jìn)入processDynamicResource"); response.setStatusLine(200); response.setContentType("text/HTML"); response.setCRLF(); response.printResponseHeader(); Class className=null; try { String path=ServletMappingUtils.getMappingValue(request.getRequestPath()); System.out.println("使用反射獲取的servlet路徑:"+path); className = (Class.forName(path)); //ServletImpl servlet= (ServletImpl) className.newInstance(); Servlet servlet = (Servlet) className.newInstance(); System.out.println(servlet); servlet.service(request, response); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } //向?yàn)g覽器返回錯(cuò)誤信息及其頁面 public void sendError(int statusCode,HttpRequest request,HttpResponse response) { System.out.println("進(jìn)入sendError()"); //獲取請(qǐng)求中資源,并處理 //response.setStatusLine("OK"); response.setStatusLine(statusCode); //response.setStatusLine("OK"); response.setContentType("text/html"); response.setCRLF(); response.printResponseHeader(); //response.printResponseContent("/error/404.html"); response.printResponseContent(ErrorPageUtils.getErrorPage(statusCode+"")); } }
同樣的,在寫完代碼之后,在response.setContentType(MIMEUtils.getMimeValue(contentType));String path=ServletMappingUtils.getMappingValue(request.getRequestPath());response.printResponseContent(ErrorPageUtils.getErrorPage(statusCode+""));出現(xiàn)問題,按照以前編寫的代碼進(jìn)行處理即可,在設(shè)置ServletMappingUtils.getMappingValue(request.getRequestPath())部分時(shí),我們要將文件的配置路徑設(shè)置為自己的類所在的包下面,比如我們的Servlet實(shí)現(xiàn)類在com.sample.servlet.HelloWorldServlet,則應(yīng)該寫為/HelloWorld=com.sample.servlet.HelloWorldServlet。
值得注意的是Servlet servlet = (Servlet) className.newInstance();處的錯(cuò)誤信息,在這里我們需要再創(chuàng)建一個(gè)類進(jìn)行處理動(dòng)態(tài)跳轉(zhuǎn),如下所示:
package com.sample.servlet; import com.sample.http.HttpRequest; import com.sample.http.HttpResponse; //只有實(shí)現(xiàn)這個(gè)接口的類,才可以被瀏覽器發(fā)送請(qǐng)求訪問到 public interface Servlet { //被瀏覽器發(fā)請(qǐng)求訪問到的對(duì)象會(huì)調(diào)用這個(gè)指定方法service,進(jìn)行處理這次瀏覽器的請(qǐng)求 public void service(HttpRequest request,HttpResponse response); }
下面是實(shí)現(xiàn)類HelloWorldServlet,其代碼如下所示:
package com.sample.servlet; import java.io.PrintWriter; import com.sample.http.HttpRequest; import com.sample.http.HttpResponse; //只有實(shí)現(xiàn)這個(gè)接口的類,才可以被瀏覽器發(fā)送請(qǐng)求訪問到 public class HelloWorldServlet implements Servlet{ //被瀏覽器發(fā)請(qǐng)求訪問到的對(duì)象會(huì)調(diào)用這個(gè)指定方法service,進(jìn)行處理這次瀏覽器的請(qǐng)求 public void service(HttpRequest request,HttpResponse response) { String name=request.getParameter("name"); System.out.println(name); try { PrintWriter pw=response.getPrintWriter(); pw.println("<html>"); pw.println("<body>"); pw.println("<center>"+name+":這是我的Servlet</center>"); pw.println("</body>"); pw.println("</html>"); pw.flush(); pw.close(); } catch (Exception e) { e.printStackTrace(); } } }
這樣就完成了動(dòng)態(tài)跳轉(zhuǎn)頁面,但是,我們?cè)诿看蝿?chuàng)建是都需要來new一個(gè)新對(duì)象,這樣不僅浪費(fèi)時(shí)間空間內(nèi)存等等,最重要的用戶體驗(yàn)都找不見了,那么我們就對(duì)其再次進(jìn)行封裝,其代碼如下,實(shí)現(xiàn)request,response對(duì)象的封裝:
package com.sample.http; //負(fù)責(zé)創(chuàng)建http協(xié)議訪問過程中使用到的對(duì)象 public interface HttpCreator { //返回創(chuàng)建好的request對(duì)象 public HttpRequest getHttpRequest(); //返回創(chuàng)建好的response對(duì)象 public HttpResponse getHttpResponse(); //返回創(chuàng)建好的HttpAccessProcessor對(duì)象 public HttpAccessProcessor getHttpAccessProcessor(); }
下面就是實(shí)現(xiàn)類:
package com.sample.http; import java.net.Socket; //負(fù)責(zé)創(chuàng)建http協(xié)議訪問過程中使用到的對(duì)象 public class HttpCreatorImpl implements HttpCreator{ private Socket s; HttpRequestImpl request; HttpResponseImpl response; HttpAccessProcessorImpl hapi; public HttpCreatorImpl(Socket s) { this.s=s; } //返回創(chuàng)建好的request對(duì)象 public HttpRequest getHttpRequest() { return request=new HttpRequestImpl(s); } //返回創(chuàng)建好的response對(duì)象 public HttpResponse getHttpResponse() { return response=new HttpResponseImpl(s); } //返回創(chuàng)建好的HttpAccessProcessor對(duì)象 public HttpAccessProcessor getHttpAccessProcessor() { return hapi=new HttpAccessProcessorImpl(); } }
到此,我們完成了所有對(duì)象的封裝,下面我們進(jìn)行測試,寫測試類如下所示:
package com.sample.http; <pre name="code" class="java">import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class ServerTest { public static void main(String[] args) { //聲明變量 ServerSocket ss=null; Socket s=null; boolean flag=true; try { int port=10002; System.out.println("Server Port:"+port); ss=new ServerSocket(port); //while(flag) { //接受客戶端發(fā)送過來的Socket s=ss.accept(); HttpCreatorImpl hci=new HttpCreatorImpl(s); HttpRequest request=hci.getHttpRequest(); HttpResponse response=hci.getHttpResponse(); HttpAccessProcessor hapi=hci.getHttpAccessProcessor(); // 用于測試收到的信息 if(request.isStaticResource())//處理靜態(tài)信息 { hapi.processStaticResource(request, response); } else if(request.isDynamicResource())//處理動(dòng)態(tài)請(qǐng)求 { hapi.processDynamicResource(request, response); } else//無法處理時(shí) { System.out.println("無法處理"); hapi.sendError(404, request, response); } } } catch (IOException e) { e.printStackTrace(); } } }
當(dāng)我們?cè)跒g覽器中輸入http://127.0.0.1:10002/HelloWorld?id=1212&name=suguniang
信息回車時(shí)能夠看到如下所示界面,但是此時(shí)的狀態(tài)是在項(xiàng)目文件夾webapps中根本不存在HelloWorld頁面,但是我們能夠正常訪問到頁面信息,而此時(shí)返回的信息正是我們的Servlet實(shí)現(xiàn)類中的內(nèi)容:
而當(dāng)我們?cè)赨RL中輸入不存在的請(qǐng)求資源時(shí),則會(huì)彈出404界面
到此這篇關(guān)于淺談web服務(wù)器項(xiàng)目中靜態(tài)請(qǐng)求和動(dòng)態(tài)請(qǐng)求處理的文章就介紹到這了,更多相關(guān)web服務(wù)器中靜態(tài)請(qǐng)求和動(dòng)態(tài)請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot項(xiàng)目test文件夾下帶main方法的類不能運(yùn)行問題
這篇文章主要介紹了springboot項(xiàng)目test文件夾下帶main方法的類不能運(yùn)行問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11JAVA面試題 從源碼角度分析StringBuffer和StringBuilder的區(qū)別
這篇文章主要介紹了JAVA面試題 從源碼角度分析StringBuffer和StringBuilder的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面我們來一起學(xué)習(xí)下吧2019-07-07SpringBoot中的ThreadLocal保存請(qǐng)求用戶信息的實(shí)例demo
線程局部變量,創(chuàng)建一個(gè)線程變量后,針對(duì)這個(gè)變量可以讓每個(gè)線程擁有自己的變量副本,每個(gè)線程是訪問的自己的副本,與其他線程的相互獨(dú)立,本文介紹SpringBoot中的ThreadLocal保存請(qǐng)求用戶信息,需要的朋友可以參考下2024-05-05Java8新特性之深入解析日期和時(shí)間_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java8新特性之深入解析日期和時(shí)間_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下2017-06-06SpringCloud?集成Sentinel的實(shí)戰(zhàn)教程
這篇文章主要介紹了SpringCloud?集成Sentinel的詳細(xì)過程,本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-08-08Maven學(xué)習(xí)教程之搭建多模塊企業(yè)級(jí)項(xiàng)目
本篇文章主要介紹了Maven學(xué)習(xí)教程之搭建多模塊企業(yè)級(jí)項(xiàng)目 ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10從零開始Java實(shí)現(xiàn)Parser?Combinator
這篇文章主要為大家介紹了從零開始Java實(shí)現(xiàn)Parser?Combinator過程及原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(9)
下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你2021-07-07