Java编程7手写服务器httpserver项目

手写webserver

开篇

Java编程7手写服务器httpserver项目_第1张图片
Java编程7手写服务器httpserver项目_第2张图片
1、面向对象编程OOP
2、容器
3、IO
4、多线程
5、网络编程
6、XML解析
7、反射
8、HTML
9、HTTP协议

灵魂反射

Java编程7手写服务器httpserver项目_第3张图片
Java编程7手写服务器httpserver项目_第4张图片
ReflectTest.java

package com.sxt.server.basic;

import java.lang.reflect.InvocationTargetException;

/**
 * 反射: 把java类中的各种结构(方法、属性、构造器、类名)映射成一个个的Java对象。
 * 1、获取Class对象
 *三种方式: Class.forName("完整路径")
 * 2、可以动态创建对象
 * clz.getConstructor().newInstance()
 */
public class ReflectTest {

	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
		//三种方式
		//1、对象.getClass()
		Iphone iphone =new Iphone();
		Class clz = iphone.getClass();
		//2、类.class()
		clz = Iphone.class;
		//3、Class.forName("包名.类名")
		clz = Class.forName("com.sxt.server.basic.Iphone");
		
		//创建对象
		/*Iphone iphone2 =(Iphone)clz.newInstance();//不推荐这种方式
		System.out.println(iphone2);*/
		Iphone iphone2 =(Iphone)clz.getConstructor().newInstance();//推荐用构造器去
		System.out.println(iphone2);
	}

}

class Iphone{
	public Iphone() {
		
	}
}

在这里插入图片描述

高效解析xml_流程

Java编程7手写服务器httpserver项目_第5张图片
p.xml



    
      至尊宝
      9000
   
   
      白晶晶
      7000
   

XmlTest01.java

package com.sxt.server.basic;

import java.io.IOException;

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解析流程
 */
public class XmlTest01 {

	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
		//SAX解析
		//1、获取解析工厂
		SAXParserFactory factory=SAXParserFactory.newInstance();
		//2、从解析工厂获取解析器
		SAXParser parse =factory.newSAXParser();
		//3、编写处理器
		//4、加载文档 Document 注册处理器
		PHandler handler=new PHandler();
		//5、解析
		parse.parse(Thread.currentThread().getContextClassLoader()
		.getResourceAsStream("com/sxt/server/basic/p.xml")
		,handler);

	}

}
class PHandler extends DefaultHandler{
	@Override
	public void startDocument() throws SAXException {
		System.out.println("----解析文档开始----");
	}
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		System.out.println(qName+"-->解析开始");
	}
	
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		String contents = new String(ch,start,length).trim();
		if(contents.length()>0) {
			System.out.println("内容为->"+contents);			
		}else {
			System.out.println("内容为->"+"空");		
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		System.out.println(qName+"-->解析结束开始");
	}
	@Override
	public void endDocument() throws SAXException {
		System.out.println("----解析文档结束----");
	}
}

mei
Java编程7手写服务器httpserver项目_第6张图片
在这里插入图片描述

高效解析xml_数据处理

Person.java

package com.sxt.server.basic;

public class Person {
	private String name;
	private int age;
	public Person() {
	}
	public Person(String name, int age) {
		super();
		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;
	}
	
}

XmlTest02.java

package com.sxt.server.basic;

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解析流程
 */
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 注册处理器
		PersonHandler handler=new PersonHandler();
		//5、解析
		parse.parse(Thread.currentThread().getContextClassLoader()
		.getResourceAsStream("com/sxt/server/basic/p.xml")
		,handler);
		
		//获取数据
		List persons = handler.getPersons();
		for(Person p:persons) {
			System.out.println(p.getName()+"-->"+p.getAge());
		}
	}

}
class PersonHandler extends DefaultHandler{
	private List persons ;
	private Person person ;
	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 {
		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(null!=tag) { //处理了空
			if(tag.equals("name")) {
				person.setName(contents);
			}else if(tag.equals("age")) {
				if(contents.length()>0) {
					person.setAge(Integer.valueOf(contents));
				}			
			}
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if(null!=qName) { 
			if(qName.equals("person")) {
				persons.add(person);
			}
		}
		tag = null; //tag丢弃了
	}
	@Override
	public void endDocument() throws SAXException {
	}

	public List getPersons() {
		return persons;
	}	
}

Java编程7手写服务器httpserver项目_第7张图片

解析webxml

web.xml

  
 
 
  login
  com.sxt.server.basic.servlet.LoginServlet
 
   
  reg
  com.sxt.server.basic.servlet.RegisterServlet
    
 
  login
  /login 
  /g 
   
 
  reg
  /reg 
 
 

Entity.java

package com.sxt.server.basic.servlet;
/**
 * 
  login
  com.shsxt.LoginServlet
  
 */
public class Entity {
	private String name;
	private String clz;
	public Entity() {
		// TODO Auto-generated constructor stub
	}
	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.java

package com.sxt.server.basic.servlet;

import java.util.HashSet;
import java.util.Set;
/**
 * 
  login
  /login 
  /g 
   
 */
public class Mapping {
	private String name;
	private Set patterns ;
	public Mapping() {
		patterns = new HashSet();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set getPatterns() {
		return patterns;
	}
	public void setPatterns(Set patterns) {
		this.patterns = patterns;
	}
	public void addPattern(String pattern) {
		this.patterns.add(pattern);
	}
}

XmlTest02.java

package com.sxt.server.basic.servlet;

import java.util.ArrayList;
import java.util.List;

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解析流程
 */
public class XmlTest02 {

	public static void main(String[] args) throws Exception{
		//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("com/sxt/server/basic/servlet/web.xml")
		,handler);
		
		//获取数据
		List entitys=handler.getEntitys();
		List mappings=handler.getMappings();
		System.out.println(entitys.size());
		System.out.println(mappings.size());
	}

}
class WebHandler extends DefaultHandler{
	private List entitys  = new ArrayList();
	private List mappings = new ArrayList();
	private Entity entity ;
	private Mapping mapping ;
	private String tag; //存储操作标签
	private boolean isMapping = false;
	
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		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(null!=tag) { //处理了空
			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 {
		if(null!=qName) { 
			if(qName.equals("servlet")) {
				entitys.add(entity);
			}else if(qName.equals("servlet-mapping")) {
				mappings.add(mapping);
			}
		}
		tag = null; //tag丢弃了
	}

	public List getEntitys() {
		return entitys;
	}

	public List getMappings() {
		return mappings;
	}	
	
}

反射webxml

WebContext.java

package com.sxt.server.basic.servlet;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class WebContext {
	private List entitys  =null;
	private List mappings =null;
	
	//key-->servlet-name  value -->servlet-class
	private Map entityMap =new HashMap();
	//key -->url-pattern value -->servlet-name
	private Map mappingMap =new HashMap();
	
	public WebContext(List entitys, List mappings) {
		this.entitys = entitys;
		this.mappings = mappings;
		
		//将entity 的List转成了对应map
		for(Entity entity:entitys) {
			entityMap.put(entity.getName(), entity.getClz());
		}
		//将map 的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) {
		String name = mappingMap.get(pattern);
		return entityMap.get(name);
	}
	
}

XmlTest02.java

package com.sxt.server.basic.servlet;

import java.util.ArrayList;
import java.util.List;

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解析流程
 */
public class XmlTest02 {

	public static void main(String[] args) throws Exception{
		//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("com/sxt/server/basic/servlet/web.xml")
		,handler);
		
		//获取数据
		WebContext context = new WebContext(handler.getEntitys(),handler.getMappings());
		//假设你输入了 /login
		String className = context.getClz("/g");
		Class clz =Class.forName(className);
		Servlet servlet =(Servlet)clz.getConstructor().newInstance();//实例化(面向接口)
		System.out.println(servlet);
		servlet.service();
		
	}

}
class WebHandler extends DefaultHandler{
	private List entitys  = new ArrayList();
	private List mappings = new ArrayList();
	private Entity entity ;
	private Mapping mapping ;
	private String tag; //存储操作标签
	private boolean isMapping = false;
	
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		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(null!=tag) { //处理了空
			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 {
		if(null!=qName) { 
			if(qName.equals("servlet")) {
				entitys.add(entity);
			}else if(qName.equals("servlet-mapping")) {
				mappings.add(mapping);
			}
		}
		tag = null; //tag丢弃了
	}

	public List getEntitys() {
		return entitys;
	}

	public List getMappings() {
		return mappings;
	}	
	
}

Servlet.java

package com.sxt.server.basic.servlet;

public interface Servlet {
	void service();
}

LoginServlet.java

package com.sxt.server.basic.servlet;

public class LoginServlet implements Servlet {

	@Override
	public void service() {
		System.out.println("loginServlet");
	}

}

RegisterServlet.java

package com.sxt.server.basic.servlet;

public class RegisterServlet implements Servlet {

	@Override
	public void service() {
		System.out.println("RegisterServlet");
	}

}

在这里插入图片描述
输入不同的URL,就会有不同的对象

简单易学的html

Java编程7手写服务器httpserver项目_第8张图片
Java编程7手写服务器httpserver项目_第9张图片
Java编程7手写服务器httpserver项目_第10张图片
login.html


第一个html登录


表单的使用



post:提交 ,基于http协议不同 量大 请求参数url不可见 安全

get: 默认,获取,基于http协议不同 量小 请求参数url可见 不安全

action: 请求web服务器的资源 URL

name:作为后端使用,区分唯一: 请求服务器,必须存在,数据不能提交

id: 作为前端使用,区分唯一



用户名:
密码:



在这里插入图片描述
在这里插入图片描述

不得不提的http协议

Java编程7手写服务器httpserver项目_第11张图片
应用层协议
协议就是一种交流格式
Java编程7手写服务器httpserver项目_第12张图片
Java编程7手写服务器httpserver项目_第13张图片

Java编程7手写服务器httpserver项目_第14张图片

Java编程7手写服务器httpserver项目_第15张图片

获取请求协议

Java编程7手写服务器httpserver项目_第16张图片
Server01.java

package com.shsxt.server;

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();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			 receive();
		} 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() {
		
	}
}

Java编程7手写服务器httpserver项目_第17张图片
在这里插入图片描述
Java编程7手写服务器httpserver项目_第18张图片

接下来测试post
Java编程7手写服务器httpserver项目_第19张图片
Java编程7手写服务器httpserver项目_第20张图片
在这里插入图片描述
Java编程7手写服务器httpserver项目_第21张图片

返回响应协议

Java编程7手写服务器httpserver项目_第22张图片
get:请求参数在URL后面
post:请求参数在请求体后面

Server02.java

package com.shsxt.server;

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();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			 receive();
		} 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("");
			content.append("");
			content.append("");
			content.append("服务器响应成功");
			content.append("");
			content.append("");
			content.append("");
			content.append("shsxt server终于回来了。。。。");
			content.append("");
			content.append("");
			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,31Dec209904:25:57GMT
			Server:shsxt Server/0.0.1;charset=GBK
			Content-type:text/html
			Content-length:39725426
			 */
			responseInfo.append("Date:").append(new Date()).append(CRLF);
			responseInfo.append("Server:").append("shsxt Server/0.0.1;charset=GBK").append(CRLF);
			responseInfo.append("Content-type:text/html").append(CRLF);
			responseInfo.append("Content-length:").append(size).append(CRLF);
			responseInfo.append(CRLF);
			//3、正文
			responseInfo.append(content.toString());
			
			//写出到客户端			
			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() {
		
	}
}

Java编程7手写服务器httpserver项目_第23张图片
Java编程7手写服务器httpserver项目_第24张图片

封装response

Java编程7手写服务器httpserver项目_第25张图片
响应的信息
Server03.java

package com.shsxt.server;

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 Server03 {
	private ServerSocket serverSocket ;
	public static void main(String[] args) {
		Server03 server = new Server03();
		server.start();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			 receive();
		} 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("");
			response.print("");
			response.print("");
			response.print("服务器响应成功");
			response.print("");
			response.print("");
			response.print("");
			response.print("shsxt server终于回来了。。。。");
			response.print("");
			response.print("");
			//关注了状态码
			response.pushToBrowser(200);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("客户端错误");
		}
	}
	//停止服务
	public void stop() {
		
	}
}

Response.java

package com.shsxt.server;

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 final String BLANK =" ";
	private 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();
			headInfo = null;
		}
	}
	
	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;
	}
	
	//推送响应信息
	public void pushToBrowser(int code) throws IOException {
		if(null ==headInfo) {
			code = 505;
		}
		createHeadInfo(code);
		bw.append(headInfo);
		bw.append(content);
		bw.flush();
	}
		
	//构建头信息
	private void createHeadInfo(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("shsxt Server/0.0.1;charset=GBK").append(CRLF);
		headInfo.append("Content-type:text/html").append(CRLF);
		headInfo.append("Content-length:").append(len).append(CRLF);
		headInfo.append(CRLF);		
	}
	
}

Java编程7手写服务器httpserver项目_第26张图片

封装request分解协议

Java编程7手写服务器httpserver项目_第27张图片
只需要关注内容和状态码

Request1.java

package com.shsxt.server;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

/**
 * 封装请求协议: 获取 method uri以及请求参数
 */
public class Request1 {
	//协议信息
	private String requestInfo;
	//请求方式
	private String method; 
	//请求url
	private String url; 
	//请求参数
	private String queryStr;
	private final  String CRLF = "\r\n";
	public Request1(Socket client) throws IOException {
		this(client.getInputStream());
	}
	public Request1(InputStream is) {		
		byte[] datas = new byte[1024*1024];
		int len;
		try {
			len = is.read(datas);
			this.requestInfo = new String(datas,0,len);			
		} catch (IOException e) {
			e.printStackTrace();
			return ;
		}
		//分解字符串
		parseRequestInfo();
	}
	
	private void parseRequestInfo() {
		System.out.println("------分解-------");
		System.out.println("---1、获取请求方式: 开头到第一个/------");
		this.method = this.requestInfo.substring(0, this.requestInfo.indexOf("/")).toLowerCase();
		this.method=this.method.trim();
		System.out.println("---2、获取请求url: 第一个/ 到 HTTP/------");
		System.out.println("---可能包含请求参数? 前面的为url------");
		//1)、获取/的位置
		int startIdx = this.requestInfo.indexOf("/")+1;
		//2)、获取 HTTP/的位置
		int endIdx = this.requestInfo.indexOf("HTTP/");
		//3)、分割字符串
		this.url = this.requestInfo.substring(startIdx, endIdx);		
		//4)、获取?的位置
		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);
		
		System.out.println("---3、获取请求参数:如果Get已经获取,如果是post可能在请求体中------");
		
		if(method.equals("post")) {
			String qStr =this.requestInfo.substring(this.requestInfo.lastIndexOf(CRLF)).trim();
			System.out.println(qStr+"-->"); 
			if(null==queryStr) {
				queryStr =qStr;
			}else { 
				queryStr +="&"+qStr;
			}
		}
		queryStr = null==queryStr?"":queryStr;
		System.out.println(method+"-->"+url+"-->"+queryStr);
	}

}

Java编程7手写服务器httpserver项目_第28张图片
在这里插入图片描述

Java编程7手写服务器httpserver项目_第29张图片
在这里插入图片描述
Java编程7手写服务器httpserver项目_第30张图片
在这里插入图片描述
Server04.java

package com.shsxt.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 目标: 封装请求信息
 */
public class Server04 {
	private ServerSocket serverSocket ;
	public static void main(String[] args) {
		Server04 server = new Server04();
		server.start();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			 receive();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("服务器启动失败....");
		}
	}
	//接受连接处理
	public void receive() {
		try {
			Socket client = serverSocket.accept();
			System.out.println("一个客户端建立了连接....");
			//获取请求协议
			Request1 request =new Request1(client);
			
			Response response =new Response(client);
			//关注了内容
			response.print(""); 
			response.print(""); 
			response.print("");
			response.print("服务器响应成功");
			response.print("");
			response.print("");
			response.print("");
			response.print("shsxt server终于回来了。。。。");
			response.print("");
			response.print("");
			//关注了状态码
			response.pushToBrowser(200);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("客户端错误");
		}
	}
	//停止服务
	public void stop() {
		
	}
}

获取参数 处理中文

Java编程7手写服务器httpserver项目_第31张图片
Request2.java

package com.shsxt.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 封装请求协议: 封装请求参数为Map
 * 
 * @author 裴新 QQ:3401997271
 *
 */
public class Request2 {
	//协议信息
	private String requestInfo;
	//请求方式
	private String method; 
	//请求url
	private String url; 
	//请求参数
	private String queryStr;
	//存储参数
	private Map> parameterMap;
	private final  String CRLF = "\r\n";
	public Request2(Socket client) throws IOException {
		this(client.getInputStream());
	}
	public Request2(InputStream is) {		
		parameterMap = new HashMap>();
		byte[] datas = new byte[1024*1024];
		int len;
		try {
			len = is.read(datas);
			this.requestInfo = new String(datas,0,len);			
		} catch (IOException e) {
			e.printStackTrace();
			return ;
		}
		//分解字符串
		parseRequestInfo();
	}
	//分解字符串
	private void parseRequestInfo() {
		System.out.println("------分解-------");
		System.out.println("---1、获取请求方式: 开头到第一个/------");
		this.method = this.requestInfo.substring(0, this.requestInfo.indexOf("/")).toLowerCase();
		this.method=this.method.trim();
		System.out.println("---2、获取请求url: 第一个/ 到 HTTP/------");
		System.out.println("---可能包含请求参数? 前面的为url------");
		//1)、获取/的位置
		int startIdx = this.requestInfo.indexOf("/")+1;
		//2)、获取 HTTP/的位置
		int endIdx = this.requestInfo.indexOf("HTTP/");
		//3)、分割字符串
		this.url = this.requestInfo.substring(startIdx, endIdx);		
		//4)、获取?的位置
		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);
		
		System.out.println("---3、获取请求参数:如果Get已经获取,如果是post可能在请求体中------");
		
		if(method.equals("post")) {
			String qStr =this.requestInfo.substring(this.requestInfo.lastIndexOf(CRLF)).trim();
			System.out.println(qStr+"-->"); 
			if(null==queryStr) {
				queryStr =qStr;
			}else { 
				queryStr +="&"+qStr;
			}
		}
		queryStr = null==queryStr?"":queryStr;
		System.out.println(method+"-->"+url+"-->"+queryStr);
		//转成Map fav=1&fav=2&uname=shsxt&age=18&others=
		convertMap();
	}
	//处理请求参数为Map
	private void convertMap() {
		//1、分割字符串 &
		String[] keyValues =this.queryStr.split("&");
		for(String queryStr:keyValues) {
			//2、再次分割字符串  =
			String[] kv = queryStr.split("=");
			kv =Arrays.copyOf(kv, 2);
			//获取key和value
			String key = kv[0];
			String value = kv[1]==null?null:decode( kv[1],"utf-8");
			//存储到map中
			if(!parameterMap.containsKey(key)) { //第一次
				parameterMap.put(key, new ArrayList());
			}
			parameterMap.get(key).add(value);			
		}
	}
	/**
	 * 处理中文
	 * @return
	 */
	private String decode(String value,String enc) {
		try {
			return java.net.URLDecoder.decode(value, enc);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 通过name获取对应的多个值
	 * @param key
	 * @return
	 */
	public String[] getParameterValues(String key) {
		List values = this.parameterMap.get(key);
		if(null==values || values.size()<1) {
			return null;
		}
		return values.toArray(new String[0]);
	}
	/**
	 * 通过name获取对应的一个值
	 * @param key
	 * @return
	 */
	public String getParameter(String key) {
		String []  values =getParameterValues(key);
		return values ==null?null:values[0];
	}
	public String getMethod() {
		return method;
	}
	
	public String getUrl() {
		return url;
	}
	
	public String getQueryStr() {
		return queryStr;
	}	
}

Java编程7手写服务器httpserver项目_第32张图片
Server05.java

package com.shsxt.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 目标: 封装请求信息中参数转成map
 */
public class Server05 {
	private ServerSocket serverSocket ;
	public static void main(String[] args) {
		Server05 server = new Server05();
		server.start();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			 receive();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("服务器启动失败....");
		}
	}
	//接受连接处理
	public void receive() {
		try {
			Socket client = serverSocket.accept();
			System.out.println("一个客户端建立了连接....");
			//获取请求协议
			Request2 request =new Request2(client);
			
			Response response =new Response(client);
			//关注了内容
			response.print(""); 
			response.print(""); 
			response.print("");
			response.print("服务器响应成功");
			response.print("");
			response.print("");
			response.print("");
			response.print("shsxt server终于回来了。。。。"+request.getParameter("uname"));
			response.print("");
			response.print("");
			//关注了状态码
			response.pushToBrowser(200);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("客户端错误");
		}
	}
	//停止服务
	public void stop() {
		
	}
}

引入servlet

Java编程7手写服务器httpserver项目_第33张图片
Response.java

package com.shsxt.server;

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 final String BLANK =" ";
	private 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();
			headInfo = null;
		}
	}
	
	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;
	}
	
	//推送响应信息
	public void pushToBrowser(int code) throws IOException {
		if(null ==headInfo) {
			code = 505;
		}
		createHeadInfo(code);
		bw.append(headInfo);
		bw.append(content);
		bw.flush();
	}
		
	//构建头信息
	private void createHeadInfo(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("shsxt Server/0.0.1;charset=GBK").append(CRLF);
		headInfo.append("Content-type:text/html").append(CRLF);
		headInfo.append("Content-length:").append(len).append(CRLF);
		headInfo.append(CRLF);		
	}
	
}

Request.java

package com.shsxt.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 封装请求协议: 封装请求参数为Map
 */
public class Request {
	//协议信息
	private String requestInfo;
	//请求方式
	private String method; 
	//请求url
	private String url; 
	//请求参数
	private String queryStr;
	//存储参数
	private Map> parameterMap;
	private final  String CRLF = "\r\n";
	public Request(Socket client) throws IOException {
		this(client.getInputStream());
	}
	public Request(InputStream is) {		
		parameterMap = new HashMap>();
		byte[] datas = new byte[1024*1024];
		int len;
		try {
			len = is.read(datas);
			this.requestInfo = new String(datas,0,len);			
		} catch (IOException e) {
			e.printStackTrace();
			return ;
		}
		//分解字符串
		parseRequestInfo();
	}
	//分解字符串
	private void parseRequestInfo() {
		System.out.println("------分解-------");
		System.out.println("---1、获取请求方式: 开头到第一个/------");
		this.method = this.requestInfo.substring(0, this.requestInfo.indexOf("/")).toLowerCase();
		this.method=this.method.trim();
		System.out.println("---2、获取请求url: 第一个/ 到 HTTP/------");
		System.out.println("---可能包含请求参数? 前面的为url------");
		//1)、获取/的位置
		int startIdx = this.requestInfo.indexOf("/")+1;
		//2)、获取 HTTP/的位置
		int endIdx = this.requestInfo.indexOf("HTTP/");
		//3)、分割字符串
		this.url = this.requestInfo.substring(startIdx, endIdx).trim();		
		//4)、获取?的位置
		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);
		
		System.out.println("---3、获取请求参数:如果Get已经获取,如果是post可能在请求体中------");
		
		if(method.equals("post")) {
			String qStr =this.requestInfo.substring(this.requestInfo.lastIndexOf(CRLF)).trim();
			System.out.println(qStr+"-->"); 
			if(null==queryStr) {
				queryStr =qStr;
			}else { 
				queryStr +="&"+qStr;
			}
		}
		queryStr = null==queryStr?"":queryStr;
		System.out.println(method+"-->"+url+"-->"+queryStr);
		//转成Map fav=1&fav=2&uname=shsxt&age=18&others=
		convertMap();
	}
	//处理请求参数为Map
	private void convertMap() {
		//1、分割字符串 &
		String[] keyValues =this.queryStr.split("&");
		for(String queryStr:keyValues) {
			//2、再次分割字符串  =
			String[] kv = queryStr.split("=");
			kv =Arrays.copyOf(kv, 2);
			//获取key和value
			String key = kv[0];
			String value = kv[1]==null?null:decode( kv[1],"utf-8");
			//存储到map中
			if(!parameterMap.containsKey(key)) { //第一次
				parameterMap.put(key, new ArrayList());
			}
			parameterMap.get(key).add(value);			
		}
	}
	/**
	 * 处理中文
	 * @return
	 */
	private String decode(String value,String enc) {
		try {
			return java.net.URLDecoder.decode(value, enc);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 通过name获取对应的多个值
	 * @param key
	 * @return
	 */
	public String[] getParameterValues(String key) {
		List values = this.parameterMap.get(key);
		if(null==values || values.size()<1) {
			return null;
		}
		return values.toArray(new String[0]);
	}
	/**
	 * 通过name获取对应的一个值
	 * @param key
	 * @return
	 */
	public String getParameter(String key) {
		String []  values =getParameterValues(key);
		return values ==null?null:values[0];
	}
	public String getMethod() {
		return method;
	}
	
	public String getUrl() {
		return url;
	}
	
	public String getQueryStr() {
		return queryStr;
	}
	
	
}

Servlet.java

package com.shsxt.server;
/**
 * 服务器小脚本接口
 */
public interface Servlet {
	void service(Request request,Response response);
}

RegisterServlet.java

package com.shsxt.server;

public class RegisterServlet implements Servlet {

	@Override
	public void service(Request request,Response response) {
		response.print("注册成功"); 
	}

}

LoginServlet.java

package com.shsxt.server;

public class LoginServlet implements Servlet {
	@Override
	public void  service(Request request,Response response) {
		response.print(""); 
		response.print(""); 
		response.print("");
		response.print("第一个servlet");
		response.print("");
		response.print("");
		response.print("");
		response.print("欢迎回来:"+request.getParameter("uname"));
		response.print("");
		response.print("");
	}

}

Server06.java

package com.shsxt.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 目标: 加入了Servlet解耦了业务代码
 */
public class Server06 {
	private ServerSocket serverSocket ;
	public static void main(String[] args) {
		Server06 server = new Server06();
		server.start();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			 receive();
		} 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() {
		
	}
}

Java编程7手写服务器httpserver项目_第34张图片

整合webxml

Java编程7手写服务器httpserver项目_第35张图片
web.xml

  
 
 
  login
  com.shsxt.server.LoginServlet
 
   
  reg
  com.shsxt.server.RegisterServlet
    
 
  login
  /login 
  /g 
  /hahaha 
   
 
  reg
  /reg 
 
   
 others
  com.shsxt.server.OthersServlet
    
  
  others
  /o 
 
 

Entity.java

package com.shsxt.server;
/**
 * 
  login
  com.shsxt.LoginServlet
  
 */
public class Entity {
	private String name;
	private String clz;
	public Entity() {
		// TODO Auto-generated constructor stub
	}
	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.java

package com.shsxt.server;

import java.util.HashSet;
import java.util.Set;
/**
 * 
  login
  /login 
  /g 
   
 */
public class Mapping {
	private String name;
	private Set patterns ;
	public Mapping() {
		patterns = new HashSet();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set getPatterns() {
		return patterns;
	}
	public void setPatterns(Set patterns) {
		this.patterns = patterns;
	}
	public void addPattern(String pattern) {
		this.patterns.add(pattern);
	}
}

WebContext.java

package com.shsxt.server;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class WebContext {
	private List entitys  =null;
	private List mappings =null;
	
	//key-->servlet-name  value -->servlet-class
	private Map entityMap =new HashMap();
	//key -->url-pattern value -->servlet-name
	private Map mappingMap =new HashMap();
	public WebContext(List entitys, List mappings) {
		this.entitys = entitys;
		this.mappings = mappings;
		
		//将entity 的List转成了对应map
		for(Entity entity:entitys) {
			entityMap.put(entity.getName(), entity.getClz());
		}
		//将map 的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) {
		String name = mappingMap.get(pattern);
		return entityMap.get(name);
	}

}

WebApp.xml

package com.shsxt.server;

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 getServletFromUrl(String url) {		
		//假设你输入了 /login
		String className = webContext.getClz("/"+url);
		Class clz;
		try {
			System.out.println(url+"-->"+className+"-->");
			clz = Class.forName(className);
			Servlet servlet =(Servlet)clz.getConstructor().newInstance();
			return servlet;
		} catch (Exception e) {
			
		}
		
		return null;
		
	}
}

WebHandler.java

package com.shsxt.server;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
 * 处理器
 */
public class WebHandler extends DefaultHandler{
	private List entitys  = new ArrayList();
	private List mappings = new ArrayList();
	private Entity entity ;
	private Mapping mapping ;
	private String tag; //存储操作标签
	private boolean isMapping = false;
	
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		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(null!=tag) { //处理了空
			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 {
		if(null!=qName) { 
			if(qName.equals("servlet")) {
				entitys.add(entity);
			}else if(qName.equals("servlet-mapping")) {
				mappings.add(mapping);
			}
		}
		tag = null; //tag丢弃了
	}

	public List getEntitys() {
		return entitys;
	}

	public List getMappings() {
		return mappings;
	}	
	
}

Server07.java

package com.shsxt.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 目标: 整合配置文件
 */
public class Server07 {
	private ServerSocket serverSocket ;
	public static void main(String[] args) {
		Server07 server = new Server07();
		server.start();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			 receive();
		} 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.getServletFromUrl(request.getUrl());
			if(null!=servlet) {
				servlet.service(request, response);
				//关注了状态码
				response.pushToBrowser(200);
			}else {
				//错误....
				response.pushToBrowser(404);
			}		
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("客户端错误");
		}
	}
	//停止服务
	public void stop() {
	}
}

Java编程7手写服务器httpserver项目_第36张图片
OthersServlet.java

package com.shsxt.server;

public class OthersServlet implements Servlet {

	@Override
	public void service(Request request,Response response) {
		response.print("其他测试页面"); 
	}

}

只需要关注servlet里面的业务就好

高效分发器

Java编程7手写服务器httpserver项目_第37张图片
Server08.java

package com.shsxt.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();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			isRunning = true;
			 receive();
		} 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();
		}
	}
}

Dispatcher.java

package com.shsxt.server;

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() {	
		
		try {
			if(null== request.getUrl() || request.getUrl().equals("")) {
				InputStream is =Thread.currentThread().getContextClassLoader().getResourceAsStream("index.html");
				response.print((new String(is.readAllBytes())));
				response.pushToBrowser(200);
				is.close();
				return ;
			}
			Servlet servlet= WebApp.getServletFromUrl(request.getUrl());
			if(null!=servlet) {
				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 e1) {
				e1.printStackTrace();
			}
		}		
		release();
	}
	//释放资源
	private void release() {
		try {
			client.close();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

}

经典404及首页处理

Java编程7手写服务器httpserver项目_第38张图片
Server09.java

package com.shsxt.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();
	}
	//启动服务
	public void start() {
		try {
			serverSocket =  new ServerSocket(8888);
			isRunning = true;
			 receive();
		} 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


404页面


你懂得



index.html

首页

欢迎使用shsxt服务器简易版,牛叉版本来面授吧。。。哈哈

终极完结

Java编程7手写服务器httpserver项目_第39张图片
1、获取请求协议
Java编程7手写服务器httpserver项目_第40张图片
2、返回响应协议
Java编程7手写服务器httpserver项目_第41张图片
3、封装响应信息
Java编程7手写服务器httpserver项目_第42张图片
4、封装请求信息
Java编程7手写服务器httpserver项目_第43张图片
5、处理请求参数
Java编程7手写服务器httpserver项目_第44张图片

6、引入servlet
Java编程7手写服务器httpserver项目_第45张图片
7、加入配置文件和反射
Java编程7手写服务器httpserver项目_第46张图片
8、封装多线程的分发器
Java编程7手写服务器httpserver项目_第47张图片

9、处理错误和首页

在这里插入图片描述
Java编程7手写服务器httpserver项目_第48张图片
Java编程7手写服务器httpserver项目_第49张图片
RegisterServlet.java

package com.shsxt.user;

import com.shsxt.server.core.Request;
import com.shsxt.server.core.Response;
import com.shsxt.server.core.Servlet;

public class RegisterServlet implements Servlet {
	@Override
	public void service(Request request,Response response) {
		//关注业务逻辑
		String uname = request.getParameter("uname");
		String[] favs =request.getParameterValues("fav");	
		response.print(""); 
		response.print(""); 
		response.print("" ); 
		response.print("");
		response.print("注册成功");
		response.print("");
		response.print("");
		response.print("");
		response.println("你注册的信息为:"+uname);
		response.println("你喜欢的类型为:");
		for(String v:favs) {
			if(v.equals("0")) {
				response.print("萝莉型");
			}else if(v.equals("1")) {
				response.print("豪放型");
			}else if(v.equals("2")) {
				response.print("经济节约型");
			}
		}
		response.print("");
		response.print("");
		
		
		
	}

}

你可能感兴趣的:(Java语言基础)