自定义的轻量级WEB容器

0.写WebServer类:“服务器”

  • 1.写构造方法:里面给server实例变量赋值端口
  • 2.写start方法:里面写accept()监听器
  • 3.写main方法:新建对象,并调用start方法
  • 7.在start方法里面写:写一个线程启动ClientHandler类
  • 71.删除原来的线程调用,改为"线程池",容量为100ExecutorService threadPool = Executors.newFixed
    ThreadPool(100);

4.写ClientHandler类"客户端操作类"

  • 5.实现Runnable接口
  • 6.写构造方法,要求传入一个Socket类型的参数:里面给socket实例变量赋值为形参
  • 19.响应客户端:通过解析得到的url,读取本地文件,先判断该资源存不存在
  • 20.如果存在该资源,获取服务端的输入流,发送状态行,就是协议 状态代码 状态描述
  • 21.因为输入流只可以读取byte类型,所以要将状态行转换成byte形式:void getBytes(“ISO8859-1”)
  • 22.每行后面加一个CRLF,最后一行要多加个CRLF
  • 23.创建一个输出流,按数组读取该文件(服务器输出流会追加写发送),发送给(write)给客户端
  • 32.如果不存在该资源,又新建一个HttpResponse实例对象和文件(404)对象,通过setentity方法,传入该文件对象
  • 45.因为要判断是处理业务还是请求静态资源,所以在请求资源的方法上面加一个判断
  • 55.再加一个分支:进入到处理业务的时候,判断是登录业务还是注册业务.它们所有下面一起"flush":发送响应
  • 59.写:捕获 58 抛出的异常的处理方法,可以只写个输出
  • 67.把总的分支变为两条路,处理业务的和加载静态资源的
  • 68.处理业务的写:先传入url到ServerContext中判断是否为空,若不为空,则进行下面的步骤
  • 69.Class.forName(“68获取到的className”);创建一个类对象
    1. 69 的类对象new一个实例(newInstance),然后"向下造型"为超类,值是对象的(如果对象(子类)没有重写就是父
      类的),然后用得到超类引用类型对象,调用service()方法,完成处理该业务的步骤!

8.写HttpRequest类"Http解析类"

  • 9.写五个实例变量,三个请求行相关信息的变量,两个和客户端连接相关的属性
  • 10.写构造方法,要求传入一个Socket的形参
  • 11.写三个"私有"方法,用来解析客户端请求
  • 12.写第四个方法,用来读取一行请求行—一个一个字符的读取,然后拼接成一行字符串,不要最后的回车符和换行符
  • 13.将三个解析方法调用到构造方法中,因为是私有方法,则其他类不可以调用,放在构造方法里面,创建对象的时候就会自
  • 动调用
  • 58.因为客户端可以发送空请求,所以取url的时候会数组下标越界,所以再调用读取一行的方法下面写:if 为"",则
  • throw new EmptyRequestException();然后一直抛到ClientHandler里面
  • 14.parseRequestLine()方法中写:先调用读取一行的方法,取出method,url,protocol这三个变量的值
  • 15.设置get获取请求行三个变量的值
  • 16.写一个散列表headers
  • 17.parseHeaders()方法中写:也是调用读取一行的方法,取出每个消息头装入到散列表(headers)中,去:和空格
  • 18.写一个获取map中value值的方法:传入一个String name,返回value的值
  • 41.写一个解析url的私有方法,在解析请求行方法中的url赋值之后调用/myweb/reg?username=xxx&password=
  • xxx&…
  • 42.定义三个实例变量,requestURI,queryString,Map parameters;分别是装url"?"左边和右边的,以及装
  • entry的
  • 43.先判断存不存在"?",如果不存在URI就是URL的值,就是调用资源的,如果存在就是要处理业务的
  • 44.所以要在下面写42的三个实例变量的get方法,让其他类可以获取值
  • 72.写putParamenters方法要求传入String参数:先写:URLDecoder.decode(str,“utf-8”);将传入的str参数转换为"utf-8"字符集,将str按"&“拆分,再按”="拆分装入到Map entry中
  • 73.解析消息正文:先判断消息头是否含有"Content-Length"单词,然后获取其value,用int形式装起来,然后用输入流
    读取该长度的字节,然后再获取"Content-Type"的value,判断其类型是否为表单:"application/x-www-form-
    “urlencoded”,然后用line = new String(data,“ISO8859-1”);去得到消息正文的内容,然后调用 72 方法
    来将其转换为"utf-8"字符集,完成操作

24.写HttpResponse类:“Http响应类”

  • 25.写两个实例变量socket和输入流out
  • 26.写一个传入Socket类型参数构造方法,给前面两个变量赋值
  • 27.写flush方法
  • 28.写三个方法,发送状态行,发送响应头"注意!最后一个响应头末尾有两个CRLF",发送响应正文,就是20-23的步骤,并删
  • 除这几步步骤"!!!"记得转码,如果发送的为字符串,一定记得要转换成:“ISO8859-1”!!/*注意!!在写发送响应正文
  • 时fis的read()读取一定要在括号里面写data!!*/
  • 29.将上面这三个方法调用到flush中
  • 30.写一个File类型的变量entity:目的是将实际访问的文件路径传入,并传输给客户端该资源
  • 31.写get,set:entity的获取和设置
  • 33.创建变量statusCode,statusReason:状态代码,默认为200,状态描述,默认为:“OK”,并把它们设置到状态行中
  • 39.在设置状态代码的方法里写:给状态描述赋值为传入状态代码到HttpContext中getvalue方法的返回值/*这一步可
  • 以解决每次都要对状态描述进行设置的麻烦*/
  • 41.因为每次设置路径之后都要对该文件进行Type设置,所以直接在setEntity方法里面设置Type的值
  • 42.file.getName()获取文件名,用lastIndexOf+1和substring取出后缀名,然后传入HttpContext类获取type

34.写HttpContext类:“Map”

  • 35.声明一个常量的散列表
  • 36.写一个私有方法:里面给上面的散列表赋值
  • 37.写一个静态块,里面调用该私有方法
  • 38.写一个方法值为String类型的方法,并要求传参:将传入的参数作为key,用get方法,返回该key的value
  • 40.再写一个私有方法,初始化资源后缀与Content-Type的值,再写和 38 一样的get方法,和35-38给状态描述赋值一样

46.写RegServlet类:“处理注册业务”

  • 47.先写一个业务方法service;要求传入请求和响应的对象参数
  • 48.获取请求参数里面的Map parameters(参数)散列表的指定key的value
  • 49.用raf的方法新建一个文件,用户名,密码,昵称占32字节,年龄占固定4字节,然后写进去,调用响应参数,传入file

50.写LoginServlet类:“处理登录业务”

  • 51.依旧传入请求和响应的对象参数
  • 52.获取请求里面的用户名和密码
  • 53.依旧用raf的方法去读取每一个用户名和密码(for 循环),并判断"!!这里一定要加去除空白符"
  • 54.调用响应参数,传入file,成功一个,失败一个

56.写EmptyRequestException类:“处理空请求异常”

  • 57.继承Exception类,加序列号,Alt+Shift+S里面的最后一个:from SuperClass,写父类里面的所有构造方法

60.写HttpServlet抽象类:“所有处理业务的超类”

  • 61.写抽象方法service:让所有的子类都重写该方法(服务)
  • 62.写一个公共方法forward:这个方法要求传入三个形参,里面主要设置文件的路径,request以后可以代替第一个参数
  • 63.在reg类和login类中:继承该类,然后把所有的设置文件代码改成,forward方法

64.写ServerContext类:“解析自己写的servlets.xml”

  • 65.将根元素将根元素下的所有元素取出,并将每个元素中的属性:url的值作为
  • key,className的值作为value,保存到SERVLET_MAPPING这个Map中完成初始化,/*这里的calssName是完全
  • 限定名*/
    
  • 66.写:get 65 的Map的value的方法

备注:

  • 文件路径: Demo下载地址
  • 1.要解析XML文件需要在pom.xml中写:(下载第三方的jar)/dom4j/,下载地址看Maven快速入手
	  <dependencies>
	  <dependency>
	  <groupId>dom4j</groupId>
	  <artifactId>dom4j</artifactId>
	  <version>1.6.1</version>
	  </dependency>
	  </dependencies>
  • 2.uri这里有 “/”
  • 3.File:如果不写./ 就"直接写文件名",不用加/
  • 4.一共 74 个步骤
  • 5.initStatusMapping()方法
   private static void initStatusMapping() {
		STATUS_MAPPING.put(200, "ok");
		STATUS_MAPPING.put(201, "Created");
		STATUS_MAPPING.put(202, "Accepted");
		STATUS_MAPPING.put(204, "No Content");
		STATUS_MAPPING.put(301, "Moved Permanently");
		STATUS_MAPPING.put(302, "Moved Temporarily");
		STATUS_MAPPING.put(304, "Not Modified");
		STATUS_MAPPING.put(400, "Bad Request");
		STATUS_MAPPING.put(401, "Unauthorized");
		STATUS_MAPPING.put(403, "Forbidden");
		STATUS_MAPPING.put(404, "Not Found");
		STATUS_MAPPING.put(500, "Internal Server Error");
		STATUS_MAPPING.put(501, "Not Implemented");
		STATUS_MAPPING.put(502, "Bad Gateway");
		STATUS_MAPPING.put(503, "Service Unavailable");
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值