java-webserver基础

手写webserver基础


反射

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

	public static void main(String[] args) throws Exception {
    
    
		
		// 三种方式
		
		// 1、对象.getClass()
		Iphone iphone = new Iphone();
		Class clz = iphone.getClass();
		// 2、类.class
		clz  = Iphone.class;
		// 3、Class.forName("包名.类名")
		clz = Class.forName("cn.xxx.server.basic.Iphone");
		
		// 创建对象
		Iphone iphone2 = (Iphone)clz.getConstructor().newInstance();
		System.out.println(iphone2);
	}

}
class Iphone{
    
    
	
	public Iphone() {
    
    
		
	}
}

xml解析

p.xml

<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person>
		<name>小黑</name>
		<age>19</age>
	</person>
	<person>
		<name>大白</name>
		<age>20</age>
	</person>
</persons>

Person.java

public class Person {
    
    
	
	private String name;
	private int age;
	
	public Person() {
    
    
		
	}

	public Person(String name, int age) {
    
    
		this.name = name;
		this.age = age;
	}

	public String getName() {
    
    
		return name;
	}

	public void setName(String name) {
    
    
		this.name = name;
	}

	public int getAge() {
    
    
		return age;
	}

	public void setAge(int age) {
    
    
		this.age = age;
	}	
}
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


/**
 * 熟悉SAX解析流程
 * @author sweetheart
 *
 */
public class XmlTest02 {
    
    

	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
    
    
		
		// SAX解析
		// 1. 获取解析工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		
		// 2. 从解析工厂获取解析器
		SAXParser parse = factory.newSAXParser();
		
		// 3. 编写处理器
		
		// 4. 加载文档Document注册处理器
		PersonPHandler handler = new PersonPHandler();
		
		// 5.解析
		parse.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("cn/whb/server/basic/p.xml"),handler);
		
		List<Person> persons;
		persons = handler.getPersons();
		
		System.out.println(persons.size());
		for(Person ps:persons) {
    
    
			System.out.println(ps.getName()+":"+ps.getAge());
		}
	}
}

class PersonPHandler extends DefaultHandler{
    
    
	
	private List<Person> persons;
	private Person person;
	
	public List<Person> getPersons() {
    
    
		return persons;
	}

	public void setPersons(List<Person> persons) {
    
    
		this.persons = persons;
	}

	private String tag; // 存储操作标签
	
	@Override
	public void startDocument() throws SAXException {
    
    
		persons = new ArrayList<>();
	}
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    
    
		
		System.out.println(qName+"-->解析开始");
		
		if(null!=qName) {
    
    
			tag = qName; // 存储标签名
			if(tag.equals("person")) {
    
    
				person = new Person();
			}
		}
	}
	
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
    
    
		
		String contents = new String(ch,start,length).trim();
		if(tag.equals("name")) {
    
    
			person.setName(contents);
		}else if(tag.equals("age")) {
    
    
			person.setAge(Integer.valueOf(contents));
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
    
    
		
		System.out.println(qName+"-->解析结束");
		
		if(qName.equals("person")) {
    
    
			persons.add(person);
		}
		tag = "";   // 防止tag对应的属性被空字符串所覆盖
	}
	
	@Override
	public void endDocument() throws SAXException {
    
    
		
		System.out.println("----解析文档结束-----");
	}
}

在这里插入图片描述

获取请求协议

在这里插入图片描述

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

/**
 * 使用ServerSocket建立与浏览器的连接,获取请求协议
 */
public class Server01 {
    
    
    private ServerSocket serverSocket;

    public static void main(String[] args) {
    
    

        Server01 server = new Server01();
        server.start();
        server.receive();
    }

    // 启动服务
    public void start(){
    
    
        try {
    
    
            serverSocket = new ServerSocket(8888);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("服务器启动失败");
        }
    }

    // 接受连接处理
    public void receive(){
    
    
        try {
    
    
            Socket client = serverSocket.accept();
            System.out.println("一个客户端建立了连接");
            // 获取请求协议
            InputStream is = client.getInputStream();
            byte[] datas = new byte[1024*1024];
            int len = is.read(datas);
            String requestInfo = new String(datas, 0, len);
            System.out.println(requestInfo);

        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("客户端错误");
        }
    }

    // 停止服务
    public void stop(){
    
    

    }

}

http协议基于tcp/ip协议,此处采用tcp-socket编程模拟服务器
在这里插入图片描述

返回响应

在这里插入图片描述

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * 返回响应
 */
public class Server02 {
    
    
    private ServerSocket serverSocket;

    public static void main(String[] args) {
    
    

        Server02 server = new Server02();
        server.start();
        server.receive();
    }

    // 启动服务
    public void start(){
    
    
        try {
    
    
            serverSocket = new ServerSocket(8888);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("服务器启动失败");
        }
    }

    // 接受连接处理
    public void receive(){
    
    
        try {
    
    
            Socket client = serverSocket.accept();
            System.out.println("一个客户端建立了连接");
            // 获取请求协议
            InputStream is = client.getInputStream();
            byte[] datas = new byte[1024*1024];
            int len = is.read(datas);
            String requestInfo = new String(datas, 0, len);
            System.out.println(requestInfo);

            StringBuilder content = new StringBuilder();
            content.append("<html>");
            content.append("<head>");
            content.append("<title>");
            content.append("标题....");
            content.append("</title>");
            content.append("</head>") ;
            content.append("<body>");
            content.append("server....start");
            content.append("</body>");
            content.append("</html>");

            // 字节长度
            int size = content.toString().getBytes().length;

            StringBuilder responseInfo = new StringBuilder();
            String blank = " ";
            String CRLF = "\r\n";

            // 返回
            // 1. 响应行: HTTP/1.1 200 OK
            responseInfo.append("HTTP/1.1").append(blank);
            responseInfo.append(200).append(blank);
            responseInfo.append("OK").append(CRLF);
            // 2. 响应头:
            /*
                Date: Mon, 15 Feb 2021 02:44:34 GMT
                Server: my-server
                Content-Type: text/html;charset=utf-8
                Content-length: 字节长度
            */
            responseInfo.append("Date: ").append(new Date()).append(CRLF);
            responseInfo.append("Server: ").append("my-server").append(CRLF);
            responseInfo.append("Content-Type: ").append("text/html;charset=utf-8").append(CRLF);
            responseInfo.append("Content-length: ").append(size).append(CRLF);
            responseInfo.append(CRLF);
            // 3. 正文
            responseInfo.append(content);

            // 写出到客户端
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
            bw.write(responseInfo.toString());
            bw.flush();

        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("客户端错误");
        }
    }

    // 停止服务
    public void stop(){
    
    

    }

}

在这里插入图片描述

封装响应信息

在这里插入图片描述

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;

public class Response {
    
    
    private BufferedWriter bw;
    // 正文
    private StringBuilder content;
    // 协议头(状态行与请求头 回车)信息
    private StringBuilder headInfo;
    private int len;  // 正文的字节数
    private static final String BLANK = " ";
    private static final String CRLF = "\r\n";

    private Response(){
    
    
        content = new StringBuilder();
        headInfo = new StringBuilder();
        len = 0;
    }

    public Response(Socket client){
    
    
        this();

        try {
    
    
            bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }


    public Response(OutputStream os){
    
    
        this();
        bw = new BufferedWriter(new OutputStreamWriter(os));
    }

    // 动态添加内容
    public Response print(String info){
    
    
        content.append(info);
        len += info.getBytes().length;
        return this;
    }

    public Response println(String info){
    
    
        content.append(info).append(CRLF);
        len += (info+CRLF).getBytes().length;
        return this;
    }


    // 构建头信息
    private void createHead(int code){
    
    
        // 1. 响应行: HTTP/1.1 200 OK
        headInfo.append("HTTP/1.1").append(BLANK);
        headInfo.append(code).append(BLANK);
        switch (code){
    
    
            case 200:
                headInfo.append("OK").append(CRLF);
                break;
            case 404:
                headInfo.append("NOT FOUND").append(CRLF);
                break;
            case 505:
                headInfo.append("SERVER ERROR").append(CRLF);
                break;
        }
        // 2. 响应头:
        headInfo.append("Date: ").append(new Date()).append(CRLF);
        headInfo.append("Server: ").append("my-server").append(CRLF);
        headInfo.append("Content-Type: ").append("text/html;charset=utf-8").append(CRLF);
        headInfo.append("Content-length: ").append(len).append(CRLF);
        headInfo.append(CRLF);
    }

    // 推送响应信息
    public void pushToBrowser(int code) throws IOException{
    
    
        if (headInfo == null){
    
    
            code = 505;
        }

        createHead(code);
        bw.append(headInfo);
        bw.append(content);
        bw.flush();

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

/**
 * 封装响应信息
 * 1. 内容动态添加
 * 2. 关注状态码, 拼接好响应的协议信息
 */
public class Server03 {
    
    
    private ServerSocket serverSocket;

    public static void main(String[] args) {
    
    

        Server03 server = new Server03();
        server.start();
        server.receive();
    }

    // 启动服务
    public void start(){
    
    
        try {
    
    
            serverSocket = new ServerSocket(8888);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("服务器启动失败");
        }
    }

    // 接受连接处理
    public void receive(){
    
    
        try {
    
    
            Socket client = serverSocket.accept();
            System.out.println("一个客户端建立了连接");
            // 获取请求协议
            InputStream is = client.getInputStream();
            byte[] datas = new byte[1024*1024];
            int len = is.read(datas);
            String requestInfo = new String(datas, 0, len);
            System.out.println(requestInfo);

            Response response = new Response(client);
            response.print("<html>");
            response.print("<head>");
            response.print("<title>");
            response.print("标题....");
            response.print("</title>");
            response.print("</head>") ;
            response.print("<body>");
            response.print("server....start");
            response.print("</body>");
            response.print("</html>");
            
            response.pushToBrowser(200);
            
        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("客户端错误");
        }
    }

    // 停止服务
    public void stop(){
    
    
    	
    }
}

封装request

在这里插入图片描述

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

/**
 * 封装请求协议: 获取method uri以及请求参数
 */
public class Request {
    
    

    // 协议信息
    private String requestInfo;
    // 请求方式
    private String method;
    // 请求url
    private String url;
    // 请求参数
    private String queryStr = "";
    private static final String CRLF = "\r\n";

    public Request(Socket client) throws IOException{
    
    

        this(client.getInputStream());

    }

    public Request(InputStream is){
    
    

        byte[] datas = new byte[1024*1024];
        int len = 0;
        try {
    
    
            len = is.read(datas);
            this.requestInfo = new String(datas, 0, len);
            System.out.println(requestInfo);

        } catch (IOException e) {
    
    
            e.printStackTrace();
            return;
        }
        // 分解字符串
        parseRequestInfo();
    }

    private void parseRequestInfo(){
    
    
        System.out.println("------分解-------");
        // 1. 获取请求方式
        this.method = requestInfo.substring(0, requestInfo.indexOf("/")).strip().toLowerCase();  // 左闭右开
        System.out.println(method);

        // 2. 获取请求的url
        int startidx = requestInfo.indexOf("/") + 1;
        int endidx = requestInfo.indexOf("HTTP/");
        this.url = requestInfo.substring(startidx, endidx).trim();
        // 获取?的位置
        int queryidx = this.url.indexOf("?");
        if (queryidx >= 0){
    
      // 存在请求参数
            String[] urlArray = this.url.split("\\?");
            this.url = urlArray[0];
            queryStr = urlArray[1];
        }

        System.out.println(this.url);
        // 3. 获取请求参数
        if (method.equals("post")){
    
    
            String qStr = requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim();
            if (queryStr.equals("")){
    
      // url中不存在参数信息
                queryStr = qStr;
            }else {
    
    
                queryStr += ("&"+qStr);
            }
        }

        System.out.println(method+"-->" + url+"-->" + queryStr);
    }
}

在这里插入图片描述

获取参数-处理中文

在这里插入图片描述

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.*;

/**
 * 封装请求协议: 封装请求参数为Map
 */
public class Request02 {
    
    

    // 协议信息
    private String requestInfo;
    // 请求方式
    private String method;
    // 请求url
    private String url;
    // 请求参数
    private String queryStr = "";
    // 存储参数
    private Map<String, List<String>> paramterMap;
    private static final String CRLF = "\r\n";

    public Request02(Socket client) throws IOException{
    
    

        this(client.getInputStream());

    }

    public Request02(InputStream is){
    
    
        paramterMap = new HashMap<>();
        byte[] datas = new byte[1024*1024];
        int len = 0;
        try {
    
    
            len = is.read(datas);
            this.requestInfo = new String(datas, 0, len);
            System.out.println(requestInfo);

        } catch (IOException e) {
    
    
            e.printStackTrace();
            return;
        }
        // 分解字符串
        parseRequestInfo();
    }

    private void parseRequestInfo(){
    
    
        System.out.println("------分解-------");
        // 1. 获取请求方式
        this.method = requestInfo.substring(0, requestInfo.indexOf("/")).strip().toLowerCase();  // 左闭右开
        System.out.println(method);

        // 2. 获取请求的url
        int startidx = requestInfo.indexOf("/") + 1;
        int endidx = requestInfo.indexOf("HTTP/");
        this.url = requestInfo.substring(startidx, endidx).trim();
        // 获取?的位置
        int queryidx = this.url.indexOf("?");
        if (queryidx >= 0){
    
      // 存在请求参数
            String[] urlArray = this.url.split("\\?");
            this.url = urlArray[0];
            queryStr = urlArray[1];
        }

        System.out.println(this.url);
        // 3. 获取请求参数
        if (method.equals("post")){
    
    
            String qStr = requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim();
            if (queryStr.equals("")){
    
      // url中不存在参数信息
                queryStr = qStr;
            }else {
    
    
                queryStr += ("&"+qStr);
            }
        }

        System.out.println(method+"-->" + url+"-->" + queryStr);
        // 转成Map
        convertMap();
    }

    private void convertMap(){
    
    
        // 分割字符串 &
        String[] keyValues = this.queryStr.split("&");

        for (String query:keyValues) {
    
    
            // 再次分割 =
            String[] kv = query.split("=");
            kv = Arrays.copyOf(kv, 2);  // 防止 "others=" 这种情况存在
            // 获取key和value
            String key = kv[0];
            String value = (kv[1] == null? kv[1]: decode(kv[1], "utf-8"));
            // 存储到Map中
            if (!paramterMap.containsKey(key)){
    
      // key不存在于map中
                paramterMap.put(key, new ArrayList<>());
            }
            paramterMap.get(key).add(value);
        }
    }

    // 处理中文
    private String decode(String value, String enc){
    
    
        try {
    
    
            return java.net.URLDecoder.decode(value, enc);
        } catch (UnsupportedEncodingException e) {
    
    
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过name获取对应的多个值
     * @param key
     * @return
     */
    public String[] getParamtersValues(String key){
    
    
        List<String> values = this.paramterMap.get(key);
        if (values==null || values.size()<1){
    
    
            return null;
        }
        return values.toArray(new String[0]);
    }

    public String getParamter(String key){
    
    
        String[] values = getParamtersValues(key);
        return values==null? null:values[0];
    }

    public String getMethod() {
    
    
        return method;
    }

    public String getUrl() {
    
    
        return url;
    }

    public String getQueryStr() {
    
    
        return queryStr;
    }

}

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

引入Servlet

在这里插入图片描述

/**
 * 服务器小脚本接口
 */
public interface Servlet {
    
    
	
	void service(Request request, Response response);
}
public class RegisterServlet implements Servlet{
    
    

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

public class LoginServlet implements Servlet{
    
    

	@Override
	public void service(Request request, Response response) {
    
    

		response.print("<html>");
		response.print("<head>");
		response.print("<title>");
		response.print("标题....");
		response.print("</title>");
		response.print("</head>") ;
		response.print("<body>");
		response.print("server....start" + Arrays.toString(request.getParamtersValues("uname")));
		response.print("</body>");
		response.print("</html>");
	}
}
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 加入了Servlet,解耦了业务代码
 */
public class Server {
    
    
    private ServerSocket serverSocket;

    public static void main(String[] args) {
    
    

        Server server = new Server();
        server.start();
        server.receive();
    }

    // 启动服务
    public void start(){
    
    
        try {
    
    
            serverSocket = new ServerSocket(8888);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("服务器启动失败");
        }
    }

    // 接受连接处理
    public void receive(){
    
    
        try {
    
    
            Socket client = serverSocket.accept();
            System.out.println("一个客户端建立了连接");
            // 获取请求协议
            Request request = new Request(client);

            // 获取响应
            Response response = new Response(client);
            Servlet servlet = null;
            if (request.getUrl().equals("login")){
    
    
                servlet = new LoginServlet();
            }else if (request.getUrl().equals("reg")){
    
    
                servlet = new RegisterServlet();
            }else {
    
    

            }
            
            servlet.service(request, response);

            response.pushToBrowser(200);

        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("客户端错误");
        }
    }

    // 停止服务
    public void stop(){
    
    
    }
}

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

整合webxml

在这里插入图片描述

在这里插入图片描述

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
	<servlet>
		<servlet-name>login</servlet-name>
		<servlet-class>server03.LoginServlet</servlet-class>
	</servlet>
	
	<servlet>
		<servlet-name>reg</servlet-name>
		<servlet-class>server03.RegisterServlet</servlet-class>
	</servlet>

	<servlet>
		<servlet-name>other</servlet-name>
		<servlet-class>server03.OtherServlet</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>login</servlet-name>
		<url-pattern>/login</url-pattern>
		<url-pattern>/g</url-pattern>
	</servlet-mapping>
	
	<servlet-mapping>
		<servlet-name>reg</servlet-name>
		<url-pattern>/reg</url-pattern>
	</servlet-mapping>

	<servlet-mapping>
		<servlet-name>other</servlet-name>
		<url-pattern>/o</url-pattern>
	</servlet-mapping>
</web-app>

WebApp

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class WebAPP {
    
    
    private static WebContext webContext;

    static {
    
    
        try {
    
    

            // SAX解析
            // 1. 获取解析工厂
            SAXParserFactory factory = SAXParserFactory.newInstance();

            // 2. 从解析工厂获取解析器
            SAXParser parse = factory.newSAXParser();

            // 3. 编写处理器

            // 4. 加载文档Document注册处理器
            WebHandler handler = new WebHandler();

            // 5.解析
            parse.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream("web.xml"),handler);

            webContext = new WebContext(handler.getEntitys(), handler.getMappings());

        }catch (Exception e){
    
    
            System.out.println("解析配置文件错误");
        }
    }

    /**
     * 通过url获取配置文件对应的servlet
     * @param url
     * @return
     */
    public static Servlet getSevletFromUrl(String url){
    
    

        String className = webContext.getClz("/" + url);
//        System.out.println(className);
        Class clz = null;
        try {
    
    

            clz = Class.forName(className);
            Servlet servlet = (Servlet)clz.getConstructor().newInstance();
            return servlet;

        } catch (Exception e) {
    
    
            // e.printStackTrace();
        }

        return null;
    }
}

WebContext

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

public class WebContext {
    
    
	
	private List<Entity> entitys = null;
	private List<Mapping> mappings = null;
	
	// key --> url-pattern  value --> servlet-name
	private Map<String,String> mappingMap = new HashMap<>();
	// key servlet-name  value --> servlet-class
	private Map<String,String> entityMap = new HashMap<>();
	
	
	public WebContext(List<Entity> entitys, List<Mapping> mappings) {
    
    
		super();
		this.entitys = entitys;
		this.mappings = mappings;
		
		// 将entity的List转成了map
		for(Entity entity:entitys) {
    
    
			entityMap.put(entity.getName(), entity.getClz());
//			System.out.println(entity.getName()+"--"+entity.getClz());
		}
		
	
		// 将mapping的List转成了map
		for(Mapping mapping:mappings) {
    
    
			for(String pattern:mapping.getPatterns()) {
    
    
				mappingMap.put(pattern, mapping.getName());
			}
			
		}
		
	}
	/**
	 * 通过URL的路径找到了对应的class
	 * @param pattern
	 * @return
	 */
	
	public String getClz(String pattern) {
    
    
		
		return entityMap.get(mappingMap.get(pattern));
	}
}

WebHandler

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

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

	public class WebHandler extends DefaultHandler {
    
    
	
	private List<Entity> entitys = new ArrayList<>();
	private List<Mapping> mappings = new ArrayList<>();
	private Entity entity;
	private Mapping mapping;
	private boolean isMapping = false;
	private String tag; // 存储操作标签
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    
    
		
		System.out.println(qName+"-->解析开始");
		
		if(null!=qName) {
    
    
			tag = qName; // 存储标签名
			if(tag.equals("servlet")) {
    
    
				entity = new Entity();
				isMapping = false;
			}else if(tag.equals("servlet-mapping")) {
    
    
				mapping = new Mapping();
				isMapping = true;
			}
		}
	}
	
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
    
    
		
		String contents = new String(ch,start,length).trim();
		if(isMapping) {
    
     // 操作servlet-mapping
			
			if(tag.equals("servlet-name")) {
    
    
				mapping.setName(contents);
			}else if(tag.equals("url-pattern")) {
    
    
				mapping.addPattern(contents);
			}
			
		}else {
    
     // 操作servlet
			if(tag.equals("servlet-name")) {
    
    
				entity.setName(contents);
			}else if(tag.equals("servlet-class")) {
    
    
				entity.setClz(contents);
			}
		}
	}
	
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
    
    
		
		System.out.println(qName+"-->解析结束");
		
		if(qName.equals("servlet")) {
    
    
			entitys.add(entity);
		}else if(qName.equals("servlet-mapping")) {
    
    
			mappings.add(mapping);
		}
		tag = "";
	}

	public List<Entity> getEntitys() {
    
    
		return entitys;
	}

	public List<Mapping> getMappings() {
    
    
		return mappings;
	}	
}

Entity

/**
 * <servlet>
 * 	<servlet-name>login</servlet-name>
 * 	<servlet-class>com.whb.server.basic.servlet</servlet-class>
 * </servlet>
 * @author sweetheart
 *
 */
public class Entity {
    
    
	private String name;
	private String clz;
	
	public Entity() {
    
    
		
	}

	public String getName() {
    
    
		return name;
	}

	public void setName(String name) {
    
    
		this.name = name;
	}

	public String getClz() {
    
    
		return clz;
	}

	public void setClz(String clz) {
    
    
		this.clz = clz;
	}
	
}

Mapping

import java.util.HashSet;
import java.util.Set;

/**
 * <servlet-mapping>
 * 	  <servlet-name>login</servlet-name>
 * 	  <url-pattern>/login</url-pattern>
 * 	  <url-pattern>/g</url-pattern>
 * </servlet-mapping>
 * @author sweetheart
 *
 */
public class Mapping {
    
    
	
	private String name;
	private Set<String> patterns;
	
	public Mapping() {
    
    
		patterns = new HashSet<>();
	}

	public String getName() {
    
    
		return name;
	}

	public void setName(String name) {
    
    
		this.name = name;
	}

	public Set<String> getPatterns() {
    
    
		return patterns;
	}

	public void setPatterns(Set<String> patterns) {
    
    
		this.patterns = patterns;
	}
	
	public void addPattern(String pattern) {
    
    
		this.patterns.add(pattern);
	}
}

Servlet

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

Server

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

/**
 * 整合配置文件
 */
public class Server {
    
    
    private ServerSocket serverSocket;

    public static void main(String[] args) {
    
    

        Server server = new Server();
        server.start();
        server.receive();
    }

    // 启动服务
    public void start(){
    
    
        try {
    
    
            serverSocket = new ServerSocket(8888);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("服务器启动失败");
        }
    }

    // 接受连接处理
    public void receive(){
    
    
        try {
    
    
            Socket client = serverSocket.accept();
            System.out.println("一个客户端建立了连接");
            // 获取请求协议
            Request request = new Request(client);

            // 获取响应
            Response response = new Response(client);
            Servlet servlet = WebAPP.getSevletFromUrl(request.getUrl());

            if (servlet!=null){
    
    

                servlet.service(request, response);
                response.pushToBrowser(200);
            }else {
    
    
                // 错误...
                response.pushToBrowser(404);
            }


        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("客户端错误");
        }
    }

    // 停止服务
    public void stop(){
    
    

    }
}

封装分发器

在这里插入图片描述

Dispatcher

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

// 分发器
public class Dispatcher implements Runnable{
    
    

    private Socket client;
    private Request request;
    private Response response;

    public Dispatcher(Socket client){
    
    
        this.client = client;
        try {
    
    
            // 获取请求协议
            request = new Request(client);
            // 获取响应
            response = new Response(client);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            this.release();
        }
    }

    @Override
    public void run() {
    
    

        try {
    
    
            Servlet servlet = WebAPP.getSevletFromUrl(request.getUrl());

            if (servlet!=null){
    
    

                servlet.service(request, response);
                response.pushToBrowser(200);
            }else {
    
    
                // 错误...
                response.pushToBrowser(404);
            }
        }catch (Exception e){
    
    
            try {
    
    
                response.pushToBrowser(500);
            } catch (IOException ex) {
    
    
                ex.printStackTrace();
            }
        }
        release();  // 防止阻塞
    }

    // 释放资源
    private void release(){
    
    
        try {
    
    
            client.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

Server

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

/**
 * 多线程处理
 */
public class Server08 {
    
    
    private ServerSocket serverSocket;
    private boolean isRunning;

    public static void main(String[] args) {
    
    

        Server08 server = new Server08();
        server.start();
        server.receive();
    }

    // 启动服务
    public void start(){
    
    
        try {
    
    
            serverSocket = new ServerSocket(8888);
            isRunning = true;
        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("服务器启动失败");
            stop();
        }
    }

    // 接受连接处理
    public void receive(){
    
    
        while (isRunning){
    
    
            try {
    
    
                Socket client = serverSocket.accept();
                System.out.println("一个客户端建立了连接");
                // 多线程
                new Thread(new Dispatcher(client)).start();

            } catch (IOException e) {
    
    
                e.printStackTrace();
                System.out.println("客户端错误");
            }
        }
    }

    // 停止服务
    public void stop(){
    
    
        isRunning = false;
        try {
    
    
            this.serverSocket.close();
            System.out.println("服务器已经停止");
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

404/505/首页处理

Dispatcher

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

// 分发器: 加入状态内容处理 404 505 及首页
public class Dispatcher implements Runnable{
    
    

    private Socket client;
    private Request request;
    private Response response;

    public Dispatcher(Socket client){
    
    
        this.client = client;
        try {
    
    
            // 获取请求协议
            request = new Request(client);
            // 获取响应
            response = new Response(client);
        } catch (IOException e) {
    
    
            e.printStackTrace();
            this.release();
        }
    }

    @Override
    public void run() {
    
    
        String url = request.getUrl();

        try {
    
    

            if (url == null || url.equals("")){
    
    
                InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("index.html");
                response.print(new String(is.readAllBytes()));
                response.pushToBrowser(200);
                is.close();
                return;
            }

            Servlet servlet = WebAPP.getSevletFromUrl(url);

            if (servlet!=null){
    
    

                servlet.service(request, response);
                response.pushToBrowser(200);
            }else {
    
    
                // 错误...
                InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("error.html");
                response.print(new String(is.readAllBytes()));
                response.pushToBrowser(404);
                is.close();
            }
        }catch (Exception e){
    
    
            try {
    
    
                response.println("服务器问题......");
                response.pushToBrowser(500);
            } catch (IOException ex) {
    
    
                ex.printStackTrace();
            }
        }
        release();  // 防止阻塞
    }

    // 释放资源
    private void release(){
    
    
        try {
    
    
            client.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

Server

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

/**
 * 处理404 505和首页
 */
public class Server09 {
    
    
    private ServerSocket serverSocket;
    private boolean isRunning;

    public static void main(String[] args) {
    
    

        Server09 server = new Server09();
        server.start();
        server.receive();
    }

    // 启动服务
    public void start(){
    
    
        try {
    
    
            serverSocket = new ServerSocket(8888);
            isRunning = true;
        } catch (IOException e) {
    
    
            e.printStackTrace();
            System.out.println("服务器启动失败");
            stop();
        }
    }

    // 接受连接处理
    public void receive(){
    
    
        while (isRunning){
    
    
            try {
    
    
                Socket client = serverSocket.accept();
                System.out.println("一个客户端建立了连接");
                // 多线程
                new Thread(new Dispatcher(client)).start();

            } catch (IOException e) {
    
    
                e.printStackTrace();
                System.out.println("客户端错误");
            }
        }
    }

    // 停止服务
    public void stop(){
    
    
        isRunning = false;
        try {
    
    
            this.serverSocket.close();
            System.out.println("服务器已经停止");
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

error.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>404页面</title>
</head>
<body>
    <h1>404错误页面</h1>
    <img src="./CrystalLiu2.jpg" />
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <h1>欢迎使用web-server</h1>
</body>
</html>

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_46456049/article/details/113806132