手写webserver

开篇

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

灵魂反射

Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目
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() {
		
	}
}

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

高效解析xml_流程

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

<?xml version="1.0" encoding="UTF-8" ?>
<persons>
    <person>
      <name>至尊宝</name>
      <age>9000</age>
   </person>
   <person>
      <name>白晶晶</name>
      <age>7000</age>
   </person>
</persons>

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项目
Java编程7手写服务器httpserver项目

高效解析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<Person> persons = handler.getPersons();
		for(Person p:persons) {
			System.out.println(p.getName()+"-->"+p.getAge());
		}
	}

}
class PersonHandler extends DefaultHandler{
	private List<Person> persons ;
	private Person person ;
	private String tag; //存储操作标签
	@Override
	public void startDocument() throws SAXException {
		persons = new ArrayList<Person>();
	}
	
	@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<Person> getPersons() {
		return persons;
	}	
}

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

解析webxml

web.xml

<?xml version="1.0" encoding="UTF-8"?>  
 <web-app>
 <servlet>
  <servlet-name>login</servlet-name>
  <servlet-class>com.sxt.server.basic.servlet.LoginServlet</servlet-class>
 </servlet>
   <servlet>
  <servlet-name>reg</servlet-name>
  <servlet-class>com.sxt.server.basic.servlet.RegisterServlet</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>
 </web-app>

Entity.java

package com.sxt.server.basic.servlet;
/**
 * <servlet>
  <servlet-name>login</servlet-name>
  <servlet-class>com.shsxt.LoginServlet</servlet-class>
  </servlet>
 */
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;
/**
 * <servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/login</url-pattern> 
  <url-pattern>/g</url-pattern> 
 </servlet-mapping>  
 */
public class Mapping {
	private String name;
	private Set<String> patterns ;
	public Mapping() {
		patterns = new HashSet<String>();
	}
	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);
	}
}

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<Entity> entitys=handler.getEntitys();
		List<Mapping> mappings=handler.getMappings();
		System.out.println(entitys.size());
		System.out.println(mappings.size());
	}

}
class WebHandler extends DefaultHandler{
	private List<Entity> entitys  = new ArrayList<Entity>();
	private List<Mapping> mappings = new ArrayList<Mapping>();
	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<Entity> getEntitys() {
		return entitys;
	}

	public List<Mapping> 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<Entity> entitys  =null;
	private List<Mapping> mappings =null;
	
	//key-->servlet-name  value -->servlet-class
	private Map<String,String> entityMap =new HashMap<String,String>();
	//key -->url-pattern value -->servlet-name
	private Map<String,String> mappingMap =new HashMap<String,String>();
	
	public WebContext(List<Entity> entitys, List<Mapping> 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<Entity> entitys  = new ArrayList<Entity>();
	private List<Mapping> mappings = new ArrayList<Mapping>();
	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<Entity> getEntitys() {
		return entitys;
	}

	public List<Mapping> 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");
	}

}

Java编程7手写服务器httpserver项目
输入不同的URL,就会有不同的对象

简单易学的html

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


第一个html登录


表单的使用



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

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

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

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

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



用户名:
密码:



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

不得不提的http协议

Java编程7手写服务器httpserver项目
应用层协议
协议就是一种交流格式
Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目

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

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

获取请求协议

Java编程7手写服务器httpserver项目
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项目
Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目

接下来测试post
Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目

返回响应协议

Java编程7手写服务器httpserver项目
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("<html>");
			content.append("<head>");
			content.append("<title>");
			content.append("服务器响应成功");
			content.append("</title>");
			content.append("</head>");
			content.append("<body>");
			content.append("shsxt server终于回来了。。。。");
			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,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项目
Java编程7手写服务器httpserver项目

封装response

Java编程7手写服务器httpserver项目
响应的信息
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("<html>");
			response.print("<head>");
			response.print("<title>");
			response.print("服务器响应成功");
			response.print("</title>");
			response.print("</head>");
			response.print("<body>");
			response.print("shsxt server终于回来了。。。。");
			response.print("</body>");
			response.print("</html>");
			//关注了状态码
			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项目

封装request分解协议

Java编程7手写服务器httpserver项目
只需要关注内容和状态码

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项目
Java编程7手写服务器httpserver项目

Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目
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("<html>"); 
			response.print("<head>"); 
			response.print("<title>");
			response.print("服务器响应成功");
			response.print("</title>");
			response.print("</head>");
			response.print("<body>");
			response.print("shsxt server终于回来了。。。。");
			response.print("</body>");
			response.print("</html>");
			//关注了状态码
			response.pushToBrowser(200);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("客户端错误");
		}
	}
	//停止服务
	public void stop() {
		
	}
}

获取参数 处理中文

Java编程7手写服务器httpserver项目
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<String,List<String>> parameterMap;
	private final  String CRLF = "\r\n";
	public Request2(Socket client) throws IOException {
		this(client.getInputStream());
	}
	public Request2(InputStream is) {		
		parameterMap = new HashMap<String,List<String>>();
		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<String>());
			}
			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<String> 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项目
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("<html>"); 
			response.print("<head>"); 
			response.print("<title>");
			response.print("服务器响应成功");
			response.print("</title>");
			response.print("</head>");
			response.print("<body>");
			response.print("shsxt server终于回来了。。。。"+request.getParameter("uname"));
			response.print("</body>");
			response.print("</html>");
			//关注了状态码
			response.pushToBrowser(200);
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("客户端错误");
		}
	}
	//停止服务
	public void stop() {
		
	}
}

引入servlet

Java编程7手写服务器httpserver项目
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<String,List<String>> parameterMap;
	private final  String CRLF = "\r\n";
	public Request(Socket client) throws IOException {
		this(client.getInputStream());
	}
	public Request(InputStream is) {		
		parameterMap = new HashMap<String,List<String>>();
		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<String>());
			}
			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<String> 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("<html>"); 
		response.print("<head>"); 
		response.print("<title>");
		response.print("第一个servlet");
		response.print("</title>");
		response.print("</head>");
		response.print("<body>");
		response.print("欢迎回来:"+request.getParameter("uname"));
		response.print("</body>");
		response.print("</html>");
	}

}

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项目

整合webxml

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

<?xml version="1.0" encoding="UTF-8"?>  
 <web-app>
 <servlet>
  <servlet-name>login</servlet-name>
  <servlet-class>com.shsxt.server.LoginServlet</servlet-class>
 </servlet>
   <servlet>
  <servlet-name>reg</servlet-name>
  <servlet-class>com.shsxt.server.RegisterServlet</servlet-class>
 </servlet>   
 <servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/login</url-pattern> 
  <url-pattern>/g</url-pattern> 
  <url-pattern>/hahaha</url-pattern> 
 </servlet-mapping>  
 <servlet-mapping>
  <servlet-name>reg</servlet-name>
  <url-pattern>/reg</url-pattern> 
 </servlet-mapping>
  <servlet> 
 <servlet-name>others</servlet-name>
  <servlet-class>com.shsxt.server.OthersServlet</servlet-class>
 </servlet>   
  <servlet-mapping>
  <servlet-name>others</servlet-name>
  <url-pattern>/o</url-pattern> 
 </servlet-mapping>
 </web-app>

Entity.java

package com.shsxt.server;
/**
 * <servlet>
  <servlet-name>login</servlet-name>
  <servlet-class>com.shsxt.LoginServlet</servlet-class>
  </servlet>
 */
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;
/**
 * <servlet-mapping>
  <servlet-name>login</servlet-name>
  <url-pattern>/login</url-pattern> 
  <url-pattern>/g</url-pattern> 
 </servlet-mapping>  
 */
public class Mapping {
	private String name;
	private Set<String> patterns ;
	public Mapping() {
		patterns = new HashSet<String>();
	}
	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);
	}
}

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<Entity> entitys  =null;
	private List<Mapping> mappings =null;
	
	//key-->servlet-name  value -->servlet-class
	private Map<String,String> entityMap =new HashMap<String,String>();
	//key -->url-pattern value -->servlet-name
	private Map<String,String> mappingMap =new HashMap<String,String>();
	public WebContext(List<Entity> entitys, List<Mapping> 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<Entity> entitys  = new ArrayList<Entity>();
	private List<Mapping> mappings = new ArrayList<Mapping>();
	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<Entity> getEntitys() {
		return entitys;
	}

	public List<Mapping> 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项目
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项目
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项目
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项目
1、获取请求协议
Java编程7手写服务器httpserver项目
2、返回响应协议
Java编程7手写服务器httpserver项目
3、封装响应信息
Java编程7手写服务器httpserver项目
4、封装请求信息
Java编程7手写服务器httpserver项目
5、处理请求参数
Java编程7手写服务器httpserver项目

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

9、处理错误和首页

Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目
Java编程7手写服务器httpserver项目
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("<html>"); 
		response.print("<head>"); 
		response.print("<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">" ); 
		response.print("<title>");
		response.print("注册成功");
		response.print("</title>");
		response.print("</head>");
		response.print("<body>");
		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("</body>");
		response.print("</html>");
		
		
		
	}

}

相关文章:

  • 2021-10-07
  • 2021-08-20
  • 2018-08-17
  • 2021-11-29
  • 2022-02-07
  • 2022-01-03
  • 2021-11-19
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-08-08
  • 2021-07-31
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案