手写webserver基础
反射
/**
* 反射:把Java类中的各种构造(方法、属性、构造器、类名)映射成一个个的Java对象
* 1. 获取Class对象
* Class.forName("完整路径")
* 2. 可以动态创建对象
* clz.getConstructor().newInstance()
* @author sweetheart
*
*/
public class ReflectTest {
public static void main(String[] args) throws Exception {
// 三种方式
// 1、对象.getClass()
Iphone iphone = new Iphone();
Class clz = iphone.getClass();
// 2、类.class
clz = Iphone.class;
// 3、Class.forName("包名.类名")
clz = Class.forName("cn.xxx.server.basic.Iphone");
// 创建对象
Iphone iphone2 = (Iphone)clz.getConstructor().newInstance();
System.out.println(iphone2);
}
}
class Iphone{
public Iphone() {
}
}
xml解析
p.xml
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<name>小黑</name>
<age>19</age>
</person>
<person>
<name>大白</name>
<age>20</age>
</person>
</persons>
Person.java
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* 熟悉SAX解析流程
* @author sweetheart
*
*/
public class XmlTest02 {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
// SAX解析
// 1. 获取解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
// 2. 从解析工厂获取解析器
SAXParser parse = factory.newSAXParser();
// 3. 编写处理器
// 4. 加载文档Document注册处理器
PersonPHandler handler = new PersonPHandler();
// 5.解析
parse.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("cn/whb/server/basic/p.xml"),handler);
List<Person> persons;
persons = handler.getPersons();
System.out.println(persons.size());
for(Person ps:persons) {
System.out.println(ps.getName()+":"+ps.getAge());
}
}
}
class PersonPHandler extends DefaultHandler{
private List<Person> persons;
private Person person;
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
private String tag; // 存储操作标签
@Override
public void startDocument() throws SAXException {
persons = new ArrayList<>();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println(qName+"-->解析开始");
if(null!=qName) {
tag = qName; // 存储标签名
if(tag.equals("person")) {
person = new Person();
}
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String contents = new String(ch,start,length).trim();
if(tag.equals("name")) {
person.setName(contents);
}else if(tag.equals("age")) {
person.setAge(Integer.valueOf(contents));
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println(qName+"-->解析结束");
if(qName.equals("person")) {
persons.add(person);
}
tag = ""; // 防止tag对应的属性被空字符串所覆盖
}
@Override
public void endDocument() throws SAXException {
System.out.println("----解析文档结束-----");
}
}
获取请求协议
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 使用ServerSocket建立与浏览器的连接,获取请求协议
*/
public class Server01 {
private ServerSocket serverSocket;
public static void main(String[] args) {
Server01 server = new Server01();
server.start();
server.receive();
}
// 启动服务
public void start(){
try {
serverSocket = new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
// 接受连接处理
public void receive(){
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端建立了连接");
// 获取请求协议
InputStream is = client.getInputStream();
byte[] datas = new byte[1024*1024];
int len = is.read(datas);
String requestInfo = new String(datas, 0, len);
System.out.println(requestInfo);
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端错误");
}
}
// 停止服务
public void stop(){
}
}
http协议基于tcp/ip协议,此处采用tcp-socket编程模拟服务器
返回响应
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
/**
* 返回响应
*/
public class Server02 {
private ServerSocket serverSocket;
public static void main(String[] args) {
Server02 server = new Server02();
server.start();
server.receive();
}
// 启动服务
public void start(){
try {
serverSocket = new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
// 接受连接处理
public void receive(){
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端建立了连接");
// 获取请求协议
InputStream is = client.getInputStream();
byte[] datas = new byte[1024*1024];
int len = is.read(datas);
String requestInfo = new String(datas, 0, len);
System.out.println(requestInfo);
StringBuilder content = new StringBuilder();
content.append("<html>");
content.append("<head>");
content.append("<title>");
content.append("标题....");
content.append("</title>");
content.append("</head>") ;
content.append("<body>");
content.append("server....start");
content.append("</body>");
content.append("</html>");
// 字节长度
int size = content.toString().getBytes().length;
StringBuilder responseInfo = new StringBuilder();
String blank = " ";
String CRLF = "\r\n";
// 返回
// 1. 响应行: HTTP/1.1 200 OK
responseInfo.append("HTTP/1.1").append(blank);
responseInfo.append(200).append(blank);
responseInfo.append("OK").append(CRLF);
// 2. 响应头:
/*
Date: Mon, 15 Feb 2021 02:44:34 GMT
Server: my-server
Content-Type: text/html;charset=utf-8
Content-length: 字节长度
*/
responseInfo.append("Date: ").append(new Date()).append(CRLF);
responseInfo.append("Server: ").append("my-server").append(CRLF);
responseInfo.append("Content-Type: ").append("text/html;charset=utf-8").append(CRLF);
responseInfo.append("Content-length: ").append(size).append(CRLF);
responseInfo.append(CRLF);
// 3. 正文
responseInfo.append(content);
// 写出到客户端
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
bw.write(responseInfo.toString());
bw.flush();
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端错误");
}
}
// 停止服务
public void stop(){
}
}
封装响应信息
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;
public class Response {
private BufferedWriter bw;
// 正文
private StringBuilder content;
// 协议头(状态行与请求头 回车)信息
private StringBuilder headInfo;
private int len; // 正文的字节数
private static final String BLANK = " ";
private static final String CRLF = "\r\n";
private Response(){
content = new StringBuilder();
headInfo = new StringBuilder();
len = 0;
}
public Response(Socket client){
this();
try {
bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public Response(OutputStream os){
this();
bw = new BufferedWriter(new OutputStreamWriter(os));
}
// 动态添加内容
public Response print(String info){
content.append(info);
len += info.getBytes().length;
return this;
}
public Response println(String info){
content.append(info).append(CRLF);
len += (info+CRLF).getBytes().length;
return this;
}
// 构建头信息
private void createHead(int code){
// 1. 响应行: HTTP/1.1 200 OK
headInfo.append("HTTP/1.1").append(BLANK);
headInfo.append(code).append(BLANK);
switch (code){
case 200:
headInfo.append("OK").append(CRLF);
break;
case 404:
headInfo.append("NOT FOUND").append(CRLF);
break;
case 505:
headInfo.append("SERVER ERROR").append(CRLF);
break;
}
// 2. 响应头:
headInfo.append("Date: ").append(new Date()).append(CRLF);
headInfo.append("Server: ").append("my-server").append(CRLF);
headInfo.append("Content-Type: ").append("text/html;charset=utf-8").append(CRLF);
headInfo.append("Content-length: ").append(len).append(CRLF);
headInfo.append(CRLF);
}
// 推送响应信息
public void pushToBrowser(int code) throws IOException{
if (headInfo == null){
code = 505;
}
createHead(code);
bw.append(headInfo);
bw.append(content);
bw.flush();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 封装响应信息
* 1. 内容动态添加
* 2. 关注状态码, 拼接好响应的协议信息
*/
public class Server03 {
private ServerSocket serverSocket;
public static void main(String[] args) {
Server03 server = new Server03();
server.start();
server.receive();
}
// 启动服务
public void start(){
try {
serverSocket = new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
// 接受连接处理
public void receive(){
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端建立了连接");
// 获取请求协议
InputStream is = client.getInputStream();
byte[] datas = new byte[1024*1024];
int len = is.read(datas);
String requestInfo = new String(datas, 0, len);
System.out.println(requestInfo);
Response response = new Response(client);
response.print("<html>");
response.print("<head>");
response.print("<title>");
response.print("标题....");
response.print("</title>");
response.print("</head>") ;
response.print("<body>");
response.print("server....start");
response.print("</body>");
response.print("</html>");
response.pushToBrowser(200);
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端错误");
}
}
// 停止服务
public void stop(){
}
}
封装request
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
/**
* 封装请求协议: 获取method uri以及请求参数
*/
public class Request {
// 协议信息
private String requestInfo;
// 请求方式
private String method;
// 请求url
private String url;
// 请求参数
private String queryStr = "";
private static final String CRLF = "\r\n";
public Request(Socket client) throws IOException{
this(client.getInputStream());
}
public Request(InputStream is){
byte[] datas = new byte[1024*1024];
int len = 0;
try {
len = is.read(datas);
this.requestInfo = new String(datas, 0, len);
System.out.println(requestInfo);
} catch (IOException e) {
e.printStackTrace();
return;
}
// 分解字符串
parseRequestInfo();
}
private void parseRequestInfo(){
System.out.println("------分解-------");
// 1. 获取请求方式
this.method = requestInfo.substring(0, requestInfo.indexOf("/")).strip().toLowerCase(); // 左闭右开
System.out.println(method);
// 2. 获取请求的url
int startidx = requestInfo.indexOf("/") + 1;
int endidx = requestInfo.indexOf("HTTP/");
this.url = requestInfo.substring(startidx, endidx).trim();
// 获取?的位置
int queryidx = this.url.indexOf("?");
if (queryidx >= 0){
// 存在请求参数
String[] urlArray = this.url.split("\\?");
this.url = urlArray[0];
queryStr = urlArray[1];
}
System.out.println(this.url);
// 3. 获取请求参数
if (method.equals("post")){
String qStr = requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim();
if (queryStr.equals("")){
// url中不存在参数信息
queryStr = qStr;
}else {
queryStr += ("&"+qStr);
}
}
System.out.println(method+"-->" + url+"-->" + queryStr);
}
}
获取参数-处理中文
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.*;
/**
* 封装请求协议: 封装请求参数为Map
*/
public class Request02 {
// 协议信息
private String requestInfo;
// 请求方式
private String method;
// 请求url
private String url;
// 请求参数
private String queryStr = "";
// 存储参数
private Map<String, List<String>> paramterMap;
private static final String CRLF = "\r\n";
public Request02(Socket client) throws IOException{
this(client.getInputStream());
}
public Request02(InputStream is){
paramterMap = new HashMap<>();
byte[] datas = new byte[1024*1024];
int len = 0;
try {
len = is.read(datas);
this.requestInfo = new String(datas, 0, len);
System.out.println(requestInfo);
} catch (IOException e) {
e.printStackTrace();
return;
}
// 分解字符串
parseRequestInfo();
}
private void parseRequestInfo(){
System.out.println("------分解-------");
// 1. 获取请求方式
this.method = requestInfo.substring(0, requestInfo.indexOf("/")).strip().toLowerCase(); // 左闭右开
System.out.println(method);
// 2. 获取请求的url
int startidx = requestInfo.indexOf("/") + 1;
int endidx = requestInfo.indexOf("HTTP/");
this.url = requestInfo.substring(startidx, endidx).trim();
// 获取?的位置
int queryidx = this.url.indexOf("?");
if (queryidx >= 0){
// 存在请求参数
String[] urlArray = this.url.split("\\?");
this.url = urlArray[0];
queryStr = urlArray[1];
}
System.out.println(this.url);
// 3. 获取请求参数
if (method.equals("post")){
String qStr = requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim();
if (queryStr.equals("")){
// url中不存在参数信息
queryStr = qStr;
}else {
queryStr += ("&"+qStr);
}
}
System.out.println(method+"-->" + url+"-->" + queryStr);
// 转成Map
convertMap();
}
private void convertMap(){
// 分割字符串 &
String[] keyValues = this.queryStr.split("&");
for (String query:keyValues) {
// 再次分割 =
String[] kv = query.split("=");
kv = Arrays.copyOf(kv, 2); // 防止 "others=" 这种情况存在
// 获取key和value
String key = kv[0];
String value = (kv[1] == null? kv[1]: decode(kv[1], "utf-8"));
// 存储到Map中
if (!paramterMap.containsKey(key)){
// key不存在于map中
paramterMap.put(key, new ArrayList<>());
}
paramterMap.get(key).add(value);
}
}
// 处理中文
private String decode(String value, String enc){
try {
return java.net.URLDecoder.decode(value, enc);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* 通过name获取对应的多个值
* @param key
* @return
*/
public String[] getParamtersValues(String key){
List<String> values = this.paramterMap.get(key);
if (values==null || values.size()<1){
return null;
}
return values.toArray(new String[0]);
}
public String getParamter(String key){
String[] values = getParamtersValues(key);
return values==null? null:values[0];
}
public String getMethod() {
return method;
}
public String getUrl() {
return url;
}
public String getQueryStr() {
return queryStr;
}
}
引入Servlet
/**
* 服务器小脚本接口
*/
public interface Servlet {
void service(Request request, Response response);
}
public class RegisterServlet implements Servlet{
@Override
public void service(Request request, Response response){
response.print("注册成功");
}
}
import java.util.Arrays;
public class LoginServlet implements Servlet{
@Override
public void service(Request request, Response response) {
response.print("<html>");
response.print("<head>");
response.print("<title>");
response.print("标题....");
response.print("</title>");
response.print("</head>") ;
response.print("<body>");
response.print("server....start" + Arrays.toString(request.getParamtersValues("uname")));
response.print("</body>");
response.print("</html>");
}
}
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 加入了Servlet,解耦了业务代码
*/
public class Server {
private ServerSocket serverSocket;
public static void main(String[] args) {
Server server = new Server();
server.start();
server.receive();
}
// 启动服务
public void start(){
try {
serverSocket = new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
// 接受连接处理
public void receive(){
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端建立了连接");
// 获取请求协议
Request request = new Request(client);
// 获取响应
Response response = new Response(client);
Servlet servlet = null;
if (request.getUrl().equals("login")){
servlet = new LoginServlet();
}else if (request.getUrl().equals("reg")){
servlet = new RegisterServlet();
}else {
}
servlet.service(request, response);
response.pushToBrowser(200);
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端错误");
}
}
// 停止服务
public void stop(){
}
}
整合webxml
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>server03.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>reg</servlet-name>
<servlet-class>server03.RegisterServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>other</servlet-name>
<servlet-class>server03.OtherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
<url-pattern>/g</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>reg</servlet-name>
<url-pattern>/reg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>other</servlet-name>
<url-pattern>/o</url-pattern>
</servlet-mapping>
</web-app>
WebApp
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class WebAPP {
private static WebContext webContext;
static {
try {
// SAX解析
// 1. 获取解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
// 2. 从解析工厂获取解析器
SAXParser parse = factory.newSAXParser();
// 3. 编写处理器
// 4. 加载文档Document注册处理器
WebHandler handler = new WebHandler();
// 5.解析
parse.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("web.xml"),handler);
webContext = new WebContext(handler.getEntitys(), handler.getMappings());
}catch (Exception e){
System.out.println("解析配置文件错误");
}
}
/**
* 通过url获取配置文件对应的servlet
* @param url
* @return
*/
public static Servlet getSevletFromUrl(String url){
String className = webContext.getClz("/" + url);
// System.out.println(className);
Class clz = null;
try {
clz = Class.forName(className);
Servlet servlet = (Servlet)clz.getConstructor().newInstance();
return servlet;
} catch (Exception e) {
// e.printStackTrace();
}
return null;
}
}
WebContext
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WebContext {
private List<Entity> entitys = null;
private List<Mapping> mappings = null;
// key --> url-pattern value --> servlet-name
private Map<String,String> mappingMap = new HashMap<>();
// key servlet-name value --> servlet-class
private Map<String,String> entityMap = new HashMap<>();
public WebContext(List<Entity> entitys, List<Mapping> mappings) {
super();
this.entitys = entitys;
this.mappings = mappings;
// 将entity的List转成了map
for(Entity entity:entitys) {
entityMap.put(entity.getName(), entity.getClz());
// System.out.println(entity.getName()+"--"+entity.getClz());
}
// 将mapping的List转成了map
for(Mapping mapping:mappings) {
for(String pattern:mapping.getPatterns()) {
mappingMap.put(pattern, mapping.getName());
}
}
}
/**
* 通过URL的路径找到了对应的class
* @param pattern
* @return
*/
public String getClz(String pattern) {
return entityMap.get(mappingMap.get(pattern));
}
}
WebHandler
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.ArrayList;
import java.util.List;
public class WebHandler extends DefaultHandler {
private List<Entity> entitys = new ArrayList<>();
private List<Mapping> mappings = new ArrayList<>();
private Entity entity;
private Mapping mapping;
private boolean isMapping = false;
private String tag; // 存储操作标签
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println(qName+"-->解析开始");
if(null!=qName) {
tag = qName; // 存储标签名
if(tag.equals("servlet")) {
entity = new Entity();
isMapping = false;
}else if(tag.equals("servlet-mapping")) {
mapping = new Mapping();
isMapping = true;
}
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String contents = new String(ch,start,length).trim();
if(isMapping) {
// 操作servlet-mapping
if(tag.equals("servlet-name")) {
mapping.setName(contents);
}else if(tag.equals("url-pattern")) {
mapping.addPattern(contents);
}
}else {
// 操作servlet
if(tag.equals("servlet-name")) {
entity.setName(contents);
}else if(tag.equals("servlet-class")) {
entity.setClz(contents);
}
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println(qName+"-->解析结束");
if(qName.equals("servlet")) {
entitys.add(entity);
}else if(qName.equals("servlet-mapping")) {
mappings.add(mapping);
}
tag = "";
}
public List<Entity> getEntitys() {
return entitys;
}
public List<Mapping> getMappings() {
return mappings;
}
}
Entity
/**
* <servlet>
* <servlet-name>login</servlet-name>
* <servlet-class>com.whb.server.basic.servlet</servlet-class>
* </servlet>
* @author sweetheart
*
*/
public class Entity {
private String name;
private String clz;
public Entity() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getClz() {
return clz;
}
public void setClz(String clz) {
this.clz = clz;
}
}
Mapping
import java.util.HashSet;
import java.util.Set;
/**
* <servlet-mapping>
* <servlet-name>login</servlet-name>
* <url-pattern>/login</url-pattern>
* <url-pattern>/g</url-pattern>
* </servlet-mapping>
* @author sweetheart
*
*/
public class Mapping {
private String name;
private Set<String> patterns;
public Mapping() {
patterns = new HashSet<>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<String> getPatterns() {
return patterns;
}
public void setPatterns(Set<String> patterns) {
this.patterns = patterns;
}
public void addPattern(String pattern) {
this.patterns.add(pattern);
}
}
Servlet
/**
* 服务器小脚本接口
*/
public interface Servlet {
void service(Request request, Response response);
}
Server
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 整合配置文件
*/
public class Server {
private ServerSocket serverSocket;
public static void main(String[] args) {
Server server = new Server();
server.start();
server.receive();
}
// 启动服务
public void start(){
try {
serverSocket = new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
}
}
// 接受连接处理
public void receive(){
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端建立了连接");
// 获取请求协议
Request request = new Request(client);
// 获取响应
Response response = new Response(client);
Servlet servlet = WebAPP.getSevletFromUrl(request.getUrl());
if (servlet!=null){
servlet.service(request, response);
response.pushToBrowser(200);
}else {
// 错误...
response.pushToBrowser(404);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端错误");
}
}
// 停止服务
public void stop(){
}
}
封装分发器
Dispatcher
import java.io.IOException;
import java.net.Socket;
// 分发器
public class Dispatcher implements Runnable{
private Socket client;
private Request request;
private Response response;
public Dispatcher(Socket client){
this.client = client;
try {
// 获取请求协议
request = new Request(client);
// 获取响应
response = new Response(client);
} catch (IOException e) {
e.printStackTrace();
this.release();
}
}
@Override
public void run() {
try {
Servlet servlet = WebAPP.getSevletFromUrl(request.getUrl());
if (servlet!=null){
servlet.service(request, response);
response.pushToBrowser(200);
}else {
// 错误...
response.pushToBrowser(404);
}
}catch (Exception e){
try {
response.pushToBrowser(500);
} catch (IOException ex) {
ex.printStackTrace();
}
}
release(); // 防止阻塞
}
// 释放资源
private void release(){
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 多线程处理
*/
public class Server08 {
private ServerSocket serverSocket;
private boolean isRunning;
public static void main(String[] args) {
Server08 server = new Server08();
server.start();
server.receive();
}
// 启动服务
public void start(){
try {
serverSocket = new ServerSocket(8888);
isRunning = true;
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
stop();
}
}
// 接受连接处理
public void receive(){
while (isRunning){
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端建立了连接");
// 多线程
new Thread(new Dispatcher(client)).start();
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端错误");
}
}
}
// 停止服务
public void stop(){
isRunning = false;
try {
this.serverSocket.close();
System.out.println("服务器已经停止");
} catch (IOException e) {
e.printStackTrace();
}
}
}
404/505/首页处理
Dispatcher
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
// 分发器: 加入状态内容处理 404 505 及首页
public class Dispatcher implements Runnable{
private Socket client;
private Request request;
private Response response;
public Dispatcher(Socket client){
this.client = client;
try {
// 获取请求协议
request = new Request(client);
// 获取响应
response = new Response(client);
} catch (IOException e) {
e.printStackTrace();
this.release();
}
}
@Override
public void run() {
String url = request.getUrl();
try {
if (url == null || url.equals("")){
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("index.html");
response.print(new String(is.readAllBytes()));
response.pushToBrowser(200);
is.close();
return;
}
Servlet servlet = WebAPP.getSevletFromUrl(url);
if (servlet!=null){
servlet.service(request, response);
response.pushToBrowser(200);
}else {
// 错误...
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("error.html");
response.print(new String(is.readAllBytes()));
response.pushToBrowser(404);
is.close();
}
}catch (Exception e){
try {
response.println("服务器问题......");
response.pushToBrowser(500);
} catch (IOException ex) {
ex.printStackTrace();
}
}
release(); // 防止阻塞
}
// 释放资源
private void release(){
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 处理404 505和首页
*/
public class Server09 {
private ServerSocket serverSocket;
private boolean isRunning;
public static void main(String[] args) {
Server09 server = new Server09();
server.start();
server.receive();
}
// 启动服务
public void start(){
try {
serverSocket = new ServerSocket(8888);
isRunning = true;
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败");
stop();
}
}
// 接受连接处理
public void receive(){
while (isRunning){
try {
Socket client = serverSocket.accept();
System.out.println("一个客户端建立了连接");
// 多线程
new Thread(new Dispatcher(client)).start();
} catch (IOException e) {
e.printStackTrace();
System.out.println("客户端错误");
}
}
}
// 停止服务
public void stop(){
isRunning = false;
try {
this.serverSocket.close();
System.out.println("服务器已经停止");
} catch (IOException e) {
e.printStackTrace();
}
}
}
error.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404页面</title>
</head>
<body>
<h1>404错误页面</h1>
<img src="./CrystalLiu2.jpg" />
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>欢迎使用web-server</h1>
</body>
</html>