java http服务端例子_简单的用 Java Socket 编写的 HTTP 服务器应用
/***?SimpleHttpServer.java*/importjava.io.*;importjava.net.*;importjava.util.StringTokenizer;/***?一個簡單的用?Java?Socket?編寫的?HTTP?服務(wù)器應(yīng)用,?演示了請求和應(yīng)答的協(xié)議通信內(nèi)容以及?*?給客戶端返回?HTML?文本和二進制數(shù)據(jù)文件(一個圖片),?同時展示了?404,?200?等狀態(tài)碼.?*?首先運行這個程序,然后打開Web瀏覽器,鍵入http://localhost,則這個程序能夠顯示出瀏覽器發(fā)送了那些信息?*?并且向瀏覽器返回一個網(wǎng)頁和一副圖片,?并測試同瀏覽器對話.?*?當瀏覽器看到?HTML?中帶有圖片地址時,?則會發(fā)出第二次連接來請求圖片等資源.?*?這個例子可以幫您理解?Java?的?HTTP?服務(wù)器軟件是基于?J2SE?的?Socket?等軟件編寫的概念,?并熟悉?*?HTTP?協(xié)議.?*?相反的用?Telnet?連接到已有的服務(wù)器則可以幫忙理解瀏覽器的運行過程和服務(wù)器端的返回內(nèi)容.?*?*?
?*???????當用戶在Web瀏覽器地址欄中輸入一個帶有http://前綴的URL并按下Enter后,或者在Web頁面中某個以http://開頭的超鏈接上單擊鼠標,HTTP事務(wù)處理的第一個階段--建立連接階段就開始了.HTTP的默認端口是80.?*????隨著連接的建立,HTTP就進入了客戶向服務(wù)器發(fā)送請求的階段.客戶向服務(wù)器發(fā)送的請求是一個有特定格式的ASCII消息,其語法規(guī)則為:?*?????*?{?:?}*?*??*?{?Entity?Body?}?*????請求消息的頂端是請求行,用于指定方法,URL和HTTP協(xié)議的版本,請求行的最后是回車換行.方法有GET,POST,HEAD,PUT,DELETE等.?*?在請求行之后是若干個報頭(Header)行.每個報頭行都是由一個報頭和一個取值構(gòu)成的二元對,報頭和取值之間以":"分隔;報頭行的最后是回車換行.常見的報頭有Accept(指定MIME媒體類型),Accept_Charset(響應(yīng)消息的編碼方式),Accept_Encoding(響應(yīng)消息的字符集),User_Agent(用戶的瀏覽器信息)等.?*????在請求消息的報頭行之后是一個回車換行,表明請求消息的報頭部分結(jié)束.在這個/n之后是請求消息的消息實體(Entity?Body).具體的例子參看httpRequest.txt.?*?????Web服務(wù)器在收到客戶請求并作出處理之后,要向客戶發(fā)送應(yīng)答消息.與請求消息一樣,應(yīng)答消息的語法規(guī)則為:?*???[]?*?{?:??}?*?*??*?{?Entity?Body?}?*????應(yīng)答消息的第一行為狀態(tài)行,其中包括了HTTP版本號,狀態(tài)碼和對狀態(tài)碼進行簡短解釋的消息;狀態(tài)行的最后是回車換行.狀態(tài)碼由3位數(shù)字組成,有5類:??*?參看:HTTP應(yīng)答碼及其意義??*??*?1XX?保留??*?2XX?表示成功??*?3XX?表示URL已經(jīng)被移走??*?4XX?表示客戶錯誤??*?5XX?表示服務(wù)器錯誤??*?例如:415,表示不支持改媒體類型;503,表示服務(wù)器不能訪問.最常見的是200,表示成功.常見的報頭有:Last_Modified(最后修改時間),Content_Type(消息內(nèi)容的MIME類型),Content_Length(內(nèi)容長度)等.?*????在報頭行之后也是一個回車換行,用以表示應(yīng)答消息的報頭部分的結(jié)束,以及應(yīng)答消息實體的開始.?*????下面是一個應(yīng)答消息的例子:?*?HTTP/1.0?200?OK?*?Date:?Moday,07-Apr-97?21:13:02?GMT?*?Server:NCSA/1.1?*?MIME_Version:1.0?*?Content_Type:text/html?*?Last_Modified:Thu?Dec?5?09:28:01?1996?*?Coentent_Length:3107?*??*??*??*?在用Java語言實現(xiàn)HTTP服務(wù)器時,首先啟動一個java.net.ServerSocket在提供服務(wù)的端口上監(jiān)聽連接.向客戶返回文本時,可以用PrintWriter,但是如果返回二進制數(shù)據(jù),則必須使用OutputStream.write(byte[])方法,返回的應(yīng)答消息字符串可以使用String.getBytes()方法轉(zhuǎn)換為字節(jié)數(shù)組返回,或者使用PrintStream的print()方法寫入文本,用write(byte[])方法寫入二進制數(shù)據(jù).?*??*?
?*@author劉長炯?*@version1.0?2007-07-24?Sunday*/publicclassSimpleHttpServerimplementsRunnable?{/****/ServerSocket?serverSocket;//服務(wù)器Socket/***?服務(wù)器監(jiān)聽端口,?默認為?80.*/publicstaticintPORT=80;//標準HTTP端口/***?開始服務(wù)器?Socket?線程.*/publicSimpleHttpServer()?{try{????????????serverSocket=newServerSocket(PORT);????????}catch(Exception?e)?{????????????System.out.println("無法啟動HTTP服務(wù)器:"+e.getLocalizedMessage());????????}if(serverSocket==null)??System.exit(1);//無法開始服務(wù)器newThread(this).start();????????System.out.println("HTTP服務(wù)器正在運行,端口:"+PORT);????}/***?運行服務(wù)器主線程,?監(jiān)聽客戶端請求并返回響應(yīng).*/publicvoidrun()?{while(true)?{try{????????????????Socket?client=null;//客戶Socketclient=serverSocket.accept();//客戶機(這里是?IE?等瀏覽器)已經(jīng)連接到當前服務(wù)器if(client!=null)?{????????????????????System.out.println("連接到服務(wù)器的用戶:"+client);try{//第一階段:?打開輸入流BufferedReader?in=newBufferedReader(newInputStreamReader(????????????????????????????????client.getInputStream()));????????????????????????????????????????????????System.out.println("客戶端發(fā)送的請求信息:/n***************");//讀取第一行,?請求地址String?line=in.readLine();????????????????????????System.out.println(line);????????????????????????String?resource=line.substring(line.indexOf('/'),line.lastIndexOf('/')-5);//獲得請求的資源的地址resource=URLDecoder.decode(resource,"UTF-8");//反編碼?URL?地址String?method=newStringTokenizer(line).nextElement().toString();//獲取請求方法,?GET?或者?POST//讀取所有瀏覽器發(fā)送過來的請求參數(shù)頭部信息while(?(line=in.readLine())!=null)?{????????????????????????????System.out.println(line);if(line.equals(""))break;????????????????????????}//顯示?POST?表單提交的內(nèi)容,?這個內(nèi)容位于請求的主體部分if("POST".equalsIgnoreCase(method))?{????????????????????????????System.out.println(in.readLine());????????????????????????}????????????????????????????????????????????????System.out.println("請求信息結(jié)束/n***************");????????????????????????System.out.println("用戶請求的資源是:"+resource);????????????????????????System.out.println("請求的類型是:"+method);//GIF?圖片就讀取一個真實的圖片數(shù)據(jù)并返回給客戶端if(resource.endsWith(".gif"))?{????????????????????????????fileService("images/test.gif",?client);????????????????????????????closeSocket(client);continue;????????????????????????}//請求?JPG?格式就報錯?404if(resource.endsWith(".jpg"))?{????????????????????????????????????????????????????PrintWriter?out=newPrintWriter(client.getOutputStream(),true);????????????????????????out.println("HTTP/1.0?404?Not?found");//返回應(yīng)答消息,并結(jié)束應(yīng)答out.println();//根據(jù)?HTTP?協(xié)議,?空行將結(jié)束頭信息out.close();????????????????????????closeSocket(client);continue;????????????????????????}else{//用?writer?對客戶端?socket?輸出一段?HTML?代碼PrintWriter?out=newPrintWriter(client.getOutputStream(),true);????????????????????????????out.println("HTTP/1.0?200?OK");//返回應(yīng)答消息,并結(jié)束應(yīng)答out.println("Content-Type:text/html;charset=GBK");????????????????????????????out.println();//根據(jù)?HTTP?協(xié)議,?空行將結(jié)束頭信息out.println("?Hello?Http?Server
");????????????????????????????out.println("你好,?這是一個?Java?HTTP?服務(wù)器?demo?應(yīng)用.");????????????????????????????out.println("您請求的路徑是:"+resource+"
");????????????????????????????out.println("這是一個支持虛擬路徑的圖片:
"+"點擊打開abc.gif,?是個服務(wù)器虛擬路徑的圖片文件.");????????????????????????????out.println("
這是個會反饋?404?錯誤的的圖片:點擊打開test.jpg
");????????????????????????????out.println("POST?表單??");????????????????????????????out.close();????????????????????????????closeSocket(client);????????????????????????}????????????????????}catch(Exception?e)?{????????????????????????System.out.println("HTTP服務(wù)器錯誤:"+e.getLocalizedMessage());????????????????????}????????????????}//System.out.println(client+"連接到HTTP服務(wù)器");//如果加入這一句,服務(wù)器響應(yīng)速度會很慢}catch(Exception?e)?{????????????????System.out.println("HTTP服務(wù)器錯誤:"+e.getLocalizedMessage());????????????}????????}????}/***?關(guān)閉客戶端?socket?并打印一條調(diào)試信息.?????*@paramsocket?客戶端?socket.*/voidcloseSocket(Socket?socket)?{try{????????????socket.close();????????}catch(IOException?ex)?{????????????ex.printStackTrace();????????}????????????????????????????System.out.println(socket+"離開了HTTP服務(wù)器");????????????}/***?讀取一個文件的內(nèi)容并返回給瀏覽器端.?????*@paramfileName?文件名?????*@paramsocket?客戶端?socket.*/voidfileService(String?fileName,?Socket?socket)????{try{????????????PrintStream?out=newPrintStream(socket.getOutputStream(),true);????????????File?fileToSend=newFile(fileName);if(fileToSend.exists()&&!fileToSend.isDirectory())????????????{????????????????out.println("HTTP/1.0?200?OK");//返回應(yīng)答消息,并結(jié)束應(yīng)答out.println("Content-Type:application/binary");????????????????out.println("Content-Length:"+fileToSend.length());//返回內(nèi)容字節(jié)數(shù)out.println();//根據(jù)?HTTP?協(xié)議,?空行將結(jié)束頭信息FileInputStream?fis=newFileInputStream(fileToSend);bytedata[]=newbyte[fis.available()];????????????????fis.read(data);????????????????out.write(data);????????????????out.close();????????????????fis.close();????????????}????????}catch(Exception?e)????????{????????????System.out.println("傳送文件時出錯:"+e.getLocalizedMessage());????????}????}/***?打印用途說明.*/privatestaticvoidusage()?{????????System.out.println("Usage:?java?HTTPServer?/nDefault?port?is?80.");????}/***?啟動簡易?HTTP?服務(wù)器?????*@paramargs*/publicstaticvoidmain(String[]?args)?{try{if(args.length!=1)?{????????????????usage();????????????}elseif(args.length==1)?{????????????????PORT=Integer.parseInt(args[0]);????????????}????????}catch(Exception?ex)?{????????????System.err.println("Invalid?port?arguments.?It?must?be?a?integer?that?greater?than?0");????????}newSimpleHttpServer();????}????}
總結(jié)
以上是生活随笔為你收集整理的java http服务端例子_简单的用 Java Socket 编写的 HTTP 服务器应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不能卸载java_无法卸载注入的DLL
- 下一篇: java利用求余水仙花数_java求水仙