簡單web服務器
回憶socket
創建客服端(在httpClient_1包下)
public class Client {
public static void main(String[] args) {
//1.創建socket物件
Socket client=null;
?
DataOutputStream dos = null;
DataInputStream dis =null;
try {
client = new Socket("localhost", 8888);
//2.獲取輸出流請求
dos = new DataOutputStream(client.getOutputStream());
dos.writeUTF("我是客服端:服務器你好!");
//3.獲取輸出流回應
dis = new DataInputStream(client.getInputStream());
System.out.println(dis.readUTF());
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.關閉流
IOClose.closeAll(dis,dos,client);
}
?
?
}
創建IOClose類
public class IOClose {
//關閉全部的工具類
public static void closeAll(Closeable...c){
for (Closeable closeable : c) {
if (closeable!=null){
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
創建服務端(在httpserver_1包下)
package com.feng.server;
?
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
?
public class Server {
public static void main(String[] args) {
//1.創建ServerSocket物件
ServerSocket server = null;
Socket client =null;
DataInputStream dis =null;
DataOutputStream dos =null;
try {
server = new ServerSocket(8888);
//2.監聽是否有客服端發送請求
client = server.accept();
//3.獲取Socket物件
//4.獲取輸入流 ->得到客服端的請求
dis = new DataInputStream(client.getInputStream());
System.out.println(dis.readUTF());
//5.獲取輸出流 ->給客服端回應結果
dos = new DataOutputStream(client.getOutputStream());
dos.writeUTF("客服端你好,我是服務器,我接受到了你的資訊");
} catch (IOException e) {
e.printStackTrace();
} finally {
IOClose.closeAll(dos,dis,client,server);
}
同樣創建IOClose
在CS結構server(2)
package com.feng.server;
?
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
?
public class Server2 {
public static void main(String[] args) {
//1.創建ServerSocket物件
ServerSocket server = null;
Socket client =null;
?
BufferedReader br = null;
try {
server = new ServerSocket(8888);
//2.監聽是否有客服端發送請求
client = server.accept();
//獲取來自瀏覽器的請求資訊
br = new BufferedReader(new InputStreamReader(client.getInputStream(), "utf-8"));
String str=null;
while ((str=br.readLine()).length()>0) {
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IOClose.closeAll(br,client,server);
}
}
}
創建HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>javaWeb</title>
</head>
<body>
<h1>HelloWorld</h1>
<form action="http://localhost:8888/index.html" method="post">
<p>用戶名:<input type="text" id="uname" name="username"></p>
<p>密碼:<input type="password" id="pwd" name="password"></p>
<p><input type="submit" value=https://www.cnblogs.com/zzy8080/p/"登入"/></p>
</form>
</body>
</html>
創建server3
獲取來自瀏覽器的請求資訊
//獲取來自瀏覽器的請求資訊
is = client.getInputStream();
byte[] buf = new byte[20480];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
對web瀏覽器做出回應
添加引數
String CRLF="\r\n";
String BLANK=" ";
InputStream is = null;
/**對web瀏覽器做出回應*/
StringBuilder sb = new StringBuilder();
StringBuilder sbContent = new StringBuilder(); //回應的文本
sbContent.append("<html><head><title>回應結果</title></head>");
sbContent.append("<body>登入成功</body></html>");
?
//1拼接回應頭
sb.append("HTTP/1.1").append(BLANK).append(200).append(BLANK).append("OK");
sb.append(CRLF);
sb.append("Content-Type: text/html;charset=UTF-8");
sb.append(CRLF);
sb.append("Content-Length:").append(sbContent.toString().getBytes().length).append(CRLF);
sb.append(CRLF);//帶表回應頭與回應正文部分之間的換行
sb.append(sbContent);
//2通過輸出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream(),"UTF-8"));
bw.write(sb.toString());
bw.flush();
bw.close();
整合server3
public class Server3 {
public static void main(String[] args) {
//1.創建ServerSocket物件
ServerSocket server = null;
Socket client =null;
String CRLF="\r\n";
String BLANK=" ";
InputStream is = null;
try {
server = new ServerSocket(8888);
//2.監聽是否有客服端發送請求
client = server.accept();
//獲取來自瀏覽器的請求資訊
is = client.getInputStream();
byte[] buf = new byte[20480];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
/**對web瀏覽器做出回應*/
StringBuilder sb = new StringBuilder();
StringBuilder sbContent = new StringBuilder(); //回應的文本
sbContent.append("<html><head><title>回應結果</title></head>");
sbContent.append("<body>登入成功</body></html>");
?
//1拼接回應頭
sb.append("HTTP/1.1").append(BLANK).append(200).append(BLANK).append("OK");
sb.append(CRLF);
sb.append("Content-Type: text/html;charset=UTF-8");
sb.append(CRLF);
sb.append("Content-Length:").append(sbContent.toString().getBytes().length).append(CRLF);
sb.append(CRLF);//帶表回應頭與回應正文部分之間的換行
sb.append(sbContent);
//2通過輸出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream(),"UTF-8"));
bw.write(sb.toString());
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
//6.關閉流
IOClose.closeAll(is,client,server);
}
?
?
}
}
手寫服務器 整體架構,撰寫XML檔案
創建Request,Response,Server,WebApp(在server包下)
創建Servlet,LoginServlet(在servlet包下)
創建IOCloseUtil(在util包下)
創建web.xml(在WEB_INFO包下)
<?xml version="1.0" encoding="UTF-8"?>
<web-app >
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.feng.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/log</url-pattern>
</servlet-mapping>
?
</web-app>
創建Entity,Mapping,ServletContext,WebDom4j,創建IOClose在util包下
配置決議XML檔案
補充物體類
package com.feng.server;
?
public class Entity { //servlet-name或每一個servlet-name所對應得物體類
private String name;
private String clazz;
?
public Entity() {
}
?
public Entity(String name, String clazz) {
this.name = name;
this.clazz = clazz;
}
?
public String getName() {
return name;
}
?
public void setName(String name) {
this.name = name;
}
?
public String getClazz() {
return clazz;
}
?
public void setClazz(String clazz) {
this.clazz = clazz;
}
}
補充Mapping類
package com.feng.server;
?
import java.util.ArrayList;
import java.util.List;
?
public class Mapping { //映射關系,多個路徑可以訪問資源
private String name; //servlet-name
private List<String> urlPattern;//url-pattern
?
public String getName() {
return name;
}
?
public void setName(String name) {
this.name = name;
}
?
public List<String> getUrlPattern() {
return urlPattern;
}
?
public void setUrlPattern(List<String> urlPattern) {
this.urlPattern = urlPattern;
}
?
public Mapping() {
this.urlPattern = new ArrayList<String>();
}
?
public Mapping(String name, List<String> urlPattern) {
this.name = name;
this.urlPattern = urlPattern;
}
}
配置dom4j
package com.feng.server;
?
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
?
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
?
public class WebDom4j { //用于決議xml
private List<Entity> entityList; //用于儲存物體類,每一個物體類一個servlet-name對應一個servlet-class
private List<Mapping> mappingList;//用于儲存映射類,每一個servlet-name對應一個url-pattern
public List<Entity> getEntityList() {
return entityList;
}
?
public void setEntityList(List<Entity> entityList) {
this.entityList = entityList;
}
?
public List<Mapping> getMappingList() {
return mappingList;
}
?
public void setMappingList(List<Mapping> mappingList) {
this.mappingList = mappingList;
}
?
//構造方法
public WebDom4j() {
entityList = new ArrayList<Entity>();
mappingList = new ArrayList<Mapping>();
}
?
//獲取Document物件的方法
public Document getDocument(){
?
try {
//創建SAXReader物件
SAXReader reader = new SAXReader();
//呼叫read方法
return reader.read(new File("web/WEB-INF/web.xml"));
} catch (DocumentException e) {
e.printStackTrace();
}
return null;
}
//獲取元素
public void parse(Document doc) {
//1獲取根元素
Element root = doc.getRootElement(); //web-app
//2獲取servlet子元素
for (Iterator<Element> ite = root.elementIterator("servlet"); ite.hasNext();) {
Element subElement = ite.next(); //得到每一個servlet
//創建一個物體類
Entity ent = new Entity(); //用于儲存servlet-name與servlet-class
for (Iterator<Element> subIte 