●訪問過程
瀏覽器發送完整域名:端口號/文件名
由網絡供應商的dns服務器解析域名獲得ip地址
●模擬服務器
·主類
package cn.itcast.server;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
/**
* ServerSocket 監聽計算機的一個端口
* Socket 代表客戶端
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 監聽計算機的一個端口
ServerSocket serverSocket = new ServerSocket(8888);
while(true) {
Socket socket = serverSocket.accept(); // 此方法會阻塞
// 開啓一個新的線程
new Thread(new MyServicer(socket)).start();
}
}
}
·子線程類監聽每次請求
package cn.itcast.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class MyServicer implements Runnable {
// 組合
private Socket socket;
public MyServicer(Socket socket) {
this.socket = socket;
}
public void run() {
// 運行在新線程上的代碼
try {
// 查看ie瀏覽器自動發送的數據
// 獲得輸入流
InputStream in = socket.getInputStream();
// 讀數據
// 估計一下對方給我發了多少數據
Thread.sleep(20); //延遲估算數組以免出現客戶端未能及時發送請求數組爲0
int len = in.available(); // 估計此流不受阻塞能讀取的字節數 0
byte[] buffer = new byte[len];
// 讀入緩衝數組
in.read(buffer);
// 輸出讀到的字符
String request = new String(buffer);
//System.out.println(request);
/*
GET /news.html HTTP/1.1
Accept:
Accept-Language: zh-CN,ja-JP;q=0.8,de-CH;q=0.7,ar-YE;q=0.5,en-GB;q=0.3,en-US;q=0.2
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6.5; CIBA)
Host: 127.0.0.1:8888
Connection: Keep-Alive
*/
// 解析出用戶訪問的資源名
// 解析出第一行數據
String firstLine = request.substring(0, request.indexOf("\r\n"));
// 解析出 uri 資源名
String uri = firstLine.split(" ")[1];
// 創建文件對象
File file = new File("src" + uri);
// 獲得輸出流
OutputStream out = socket.getOutputStream();
// 判斷文件是否存在
if(!file.exists()) {
// 告訴對方沒有這個資源
out.write("對不起!您訪問的資源不存在!".getBytes());
out.close();
return;
}
// 說明文件存在 讀文件
FileInputStream fis = new FileInputStream(file);
// IO流的對拷
byte[] buf = new byte[1024];
while((len=fis.read(buf))!=-1)
out.write(buf,0,len);
fis.close();
out.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
●tomcat的安裝配置與啓動
·配置JAVA_HOME=jdk安裝目錄(不需要bin目錄)
·解壓tomcat
·用dos命令行啓動bin/startup.bat文件
·當配置了環境變量catalina_home爲D:\Develop\apache-tomcat-6.0.14\bin後startbat粘貼在哪都能運行
或者直接修改startup.bat寫死catalina_home的路徑
注意:當環境變量catalina_home配置完成後 以後永遠運行的都是此配置配置的tomcat服務器 無論在哪啓動都是
·當修改了conf/server.xml中的端口號8080爲80後 不用敲端口號即可訪問服務器的網頁
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
·項目不想放在webapps目錄下配置虛擬目錄
1)在conf/server.xml中</Host>前配置<Context path="/news" docBase="f:\news" />
相當於把f盤目錄下的news文件夾配置成一個web服務,然後通過/news即可訪問。
注意:server.xml中不能有中文!
2)在conf/catalina/localhost目錄下配置一個xml xml名稱就是訪問路徑
名稱爲aaa#bbb.xml 則訪問路徑爲aaa/bbb/ 當名稱爲ROOT.xml時候 此頁面爲缺省的web應用(lohost那個tom貓頁面就看不到了)
<Context docBase="f:\news" /> docBase爲實際路徑
·設置每個web應用的默認首頁
在每個應用目錄下的WEB-INF目錄中的web.xml中配置
因爲每個xml文件繼承了conf目錄下的web的xml中的配置 所以當默認頁的文件名爲index時可以不設置
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
●配置虛擬主機
服務器允許在一個IP上配置多個主機,即虛擬主機
在conf/server.xml中</Host>前配置
<Host name="www.sohu.com" appBase="F:\sohu\webapps" />
說明主機域名爲www.sohu.com 本地文件存在F:\sohu\webapps
●http響應消息頭的實驗
package cn.itcast.servlet;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// request 用於獲得ie發送的請求消息
// response 用於向ie瀏覽器會送響應消息
//test1(response);
//test2(response);
//test3(response);
//test4(response);
//test5(response);
// 禁止瀏覽器緩存動態的web資源
response.setHeader("Expires", "-1");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setHeader("content-type", "text/html;charset=utf-8");
response.getWriter().write("中國");
}
private void test5(HttpServletResponse response) throws IOException,
FileNotFoundException {
// 發送一張圖片給ie
response.setHeader("content-type", "application/octet-stream"); // mime 格式
// 告訴瀏覽器以下載的方式打開
response.setHeader("content-disposition","attachment;filename=b.jpg");
OutputStream out = response.getOutputStream();
InputStream in = new FileInputStream("d:/picture/b.jpg");
int len;
byte[] buffer = new byte[1024];
while((len=in.read(buffer))!=-1)
out.write(buffer,0,len);
in.close();
out.close();
}
private void test4(HttpServletResponse response) {
// 通知瀏覽器自動刷新
//response.setHeader("refresh", "3;url=http://www.sina.com"); // 註冊成功! 3秒後自動跳轉
response.setHeader("refresh", "1"); // 定時刷新
}
private void test3(HttpServletResponse response) throws IOException,
FileNotFoundException {
// 發送一張圖片給ie
// 告訴瀏覽器數據類型
response.setHeader("content-type", "image/jpeg"); // mime 格式
OutputStream out = response.getOutputStream();
InputStream in = new FileInputStream("d:/picture/b.jpg");
int len;
byte[] buffer = new byte[1024];
while((len=in.read(buffer))!=-1)
out.write(buffer,0,len);
in.close();
out.close();
}
private void test2(HttpServletResponse response) throws IOException {
// 壓縮數據
String str = "abcdfafadfdafadsfasdfadsfsdafadsfasdfadfadsaf<br>";
StringBuilder sb = new StringBuilder();
for(int i=0; i<100; i++)
sb.append(str);
str = sb.toString();
// GzipOutputStream / ZipOutputStream
// FileOutputStream
// 二進制流 關聯內存
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 壓縮流
GZIPOutputStream gout = new GZIPOutputStream(baos);
System.out.println("壓縮前的數據大小:" + str.getBytes().length);
gout.write(str.getBytes());
gout.close();
// 壓縮後的數據
byte[] data = baos.toByteArray();
// 告訴瀏覽器發送的是壓縮數據 讓瀏覽器解壓
response.setHeader("content-encoding", "gzip");
response.setHeader("content-length", data.length+"");
System.out.println("壓縮後的數據大小:" + data.length);
OutputStream out = response.getOutputStream();
out.write(data);
out.close();
}
// 請求重定向
private void test1(HttpServletResponse response) {
response.setStatus(302);
response.setHeader("location", "http://www.sina.com.cn:8080");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
●servlet中防盜鏈
package cn.itcast.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownloadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 防盜鏈
// 獲得訪問者是從哪個網站點擊超鏈接過來的
String referer = request.getHeader("referer");
if(referer==null || !referer.startsWith("http://localhost")) {
// 是盜鏈者
// 跳轉到首頁看了廣告再來
response.setStatus(302);
response.setHeader("location", "http://localhost:8080/day04_httpresponse/index.jsp");
return ;
}
response.setHeader("content-disposition","attachment;filename=fjrj.txt");
response.getOutputStream().write("鳳姐日記".getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}