2.一个简单的Servlet容器
章前准备
如何处理ifelse众多的问题,当然也可以说是switch case
我们经常写这样的代码,如果这货小一点,且可预测什么的,那都不是事,问题是如果他要是可拓展的类- -!让他见鬼去吧
我曾经被要求实现一个接口,这个接口会接受一个Scene参数用以区分不同实现方式(不用吐槽,国企喜欢超级接口),我相信你也会见过类似的代码,显然如果Scene是可确定的话,if...else并没有什么不可以的...遗憾的是设计人员会明确的告诉你,Scene是会不断增加的,而且if中的内容绝对不会像你想象的那么简单。。。
唯一令人兴奋的是java作为面向对象语言,最喜欢解决这种问题
呆毛:Paint类拥有print方法,他会根据传来的参数来画不同的人物
简单实现一:尝试着完成呆毛并观察
public class Paint {public static void main(String[] args) {Paint paint = new Paint();paint.print("lf","", "");paint.print("nm","", "");}/*** @param Scene 场景参数* @param name 路人甲,实现场景什么的会使用到的参数* @param id 路人乙*/void print(String scene,String name,String id){if("lf".equals(scene)){//好长好长的代码System.out.println("路飞");}else if("sl".equals(scene)){//好长好长的代码System.out.println("索隆");}else if("sz".equals(scene)){//好长好长的代码System.out.println("山治");}else{//好长好长的代码System.out.println("熊猫人");}} }
这里只是用System.out.println("");来替代绘画的过程,如果真的很长的话,即使作为BI端的屌丝程序猿也知道,这时候应该封装具体的实现
简单实现二:尝试着将ifelse中具体的实现进行封装(通过接口,不是通过方法。。。)
/*** @author 程猿* 尝试着封装所谓的具体实现,print中的逻辑将会在Print的实现*/ public class Paint {public static void main(String[] args) {Paint paint = new Paint();paint.print("lf","", "");paint.print("nm","", "");}void print(String scene,String name,String id){if("lf".equals(scene)){new PrintLF().print(scene, name, id);}else if("sl".equals(scene)){new PrintSL().print(scene, name, id);}else if("sz".equals(scene)){new PrintSZ().print(scene, name, id);}else{new PrintXMR().print(scene, name, id);}} }
public interface Print {void print(String scene,String name,String id); }
public class PrintLF implements Print{@Overridepublic void print(String scene, String name, String id) {System.out.println("路飞");} }
其他实现就不贴了
我们已用封装的方式,将处理的问题全都放在Print的实现类中,代码此处会少一节。。。当然这只是对封装的简单应用,可以看到print的方法中,是简单的判断关系与实现类的1对1的关系,如果我这里使用类似于Map这种结构的话,情况或许就不一样了....其实作为BI端的屌丝程序猿明白,我们的实现,基本上就是这样了(严格来说应该是放到方法里,而不是放到接口实现里)
简单实现三:我们要使用Map结构,key为判断,val为实现类
/*** @author 程猿* key对应判断依据,value对应实现类* 如果value为null,会使用默认类,这里的默认类的key为""...*/ public class Paint2 {public static void main(String[] args) {Paint2 paint = new Paint2();paint.print("lf","", "");paint.print("nm","", "");}Map<String,Print> paintMap=new HashMap(){{put("lf", new PrintLF());put("sl", new PrintSL());put("sz", new PrintSZ());put("", new PrintXMR());}};void print(String scene,String name,String id){Print object = paintMap.get(scene);if(object==null){object= paintMap.get("");}if(object==null){return;}object.print(scene, name, id);} }
main是控制台,很显然,如果给map一个get/set方法的话,我们就可以在控制台来控制Paint类方法的走向,而不需要在进入Paint进行修改,当然,主流的控制台还是配置文件,我们都是懂ioc的男人,当然因为说使用了ioc所以就结束显然太没良心了,那就试试用加点伪ioc呗
简单实现四:加入伪ioc实现
/*** @author 程猿 并没有一个容器去实现Print类...所以才叫伪嘛*/ public class Paint {public static void main(String[] args) {Paint paint = new Paint();paint.print("lf", "", "");paint.print("nm", "", "");}Paint() {InputStream in = this.getClass().getResourceAsStream("/t3/print.properties");try {paintMap.load(in);} catch (IOException e) {e.printStackTrace();} finally {try {in.close();} catch (IOException e) {e.printStackTrace();}}}Properties paintMap = new Properties();void print(String scene, String name, String id) {String string = paintMap.getProperty(scene);if (string == null) {string = paintMap.getProperty("");}if (string == null) {return;}Class clazz = null;try {clazz = Class.forName(string);} catch (ClassNotFoundException e) {e.printStackTrace();}Print newInstance = null;try {newInstance = (Print) clazz.newInstance();} catch (InstantiationException e) {// TODO Auto-generated catch block e.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch block e.printStackTrace();}newInstance.print(scene, name, id);} }
这是一种解决ifelse众多的解决方案,而且还是经理们经常念叨的可插拔可配置的,那他算不算一种神奇的设计模式呢?那我个人认为设计模式是解决继承,封装,多态使用时的一种不便利性而存在的,比如子类过多,或者方法暴露过多什么的,显然这里只是简单地封装和多态的使用(无视ioc...),当然或许这就是面向对象最有意思的地方,或者说面向接口
不在联想了,我们是在学tomcat,聊一下web服务器与网民(客户端的操作人员)的交互过程,首先,网民输入url,浏览器通过url(和自身设置)生成请求报文发送给服务器,服务器分析请求报文,并返回相应报文,通过这个过程可以发现,url应该称的上最精简的请求报文(或者说最重要的地方),也是网民唯一能修改的地方,换句话说不同的url对应不同的响应报文,那么,来一个
自制的可以相应多种URL的web服务器
/*** @author 程猿 通过请求报文可以观察出第一行,以空格分割,第二个就是url的路径*/ public class Test {public static String getUrl(InputStream inputStream) throws IOException {int i;String str = "";while ((i = inputStream.read()) != '\r') {str += (char) i;}String[] split = str.split(" ");if (split.length > 2) {return split[1];}return null;}public static void main(String[] args) throws Exception {ServerSocket server = new ServerSocket(8080);while (true) {Socket socket = server.accept();// 接受请求InputStream inputStream = socket.getInputStream();String url = getUrl(inputStream);System.out.println("url:" + url);if ("/a".equals(url)) {// 发送回应OutputStream outputStream = socket.getOutputStream();String str = "HTTP/1.1 200 OK\n"+ "Server: Apache-Coyote/1.1\n"+ "Content-Type: text/html\n"+ "Transfer-Encoding: chunked\n"+ "Date: Mon, 27 Oct 2014 13:38:35 GMT\n"+ "\n"+ "bb\n"+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"+ "<HTML>\n"+ " <HEAD><TITLE>A Servlet</TITLE></HEAD>\n"+ " <BODY>\n" + " this is A~\n" + " </BODY>\n"+ "</HTML>";outputStream.write(str.getBytes());socket.close();} else if ("/b".equals(url)) {OutputStream outputStream = socket.getOutputStream();String str = "HTTP/1.1 200 OK\n"+ "Server: Apache-Coyote/1.1\n"+ "Content-Type: text/html\n"+ "Transfer-Encoding: chunked\n"+ "Date: Mon, 27 Oct 2014 13:38:35 GMT\n"+ "\n"+ "bb\n"+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"+ "<HTML>\n"+ " <HEAD><TITLE>A Servlet</TITLE></HEAD>\n"+ " <BODY>\n" + " BBBBBBBBBBBBBBB~\n"+ " </BODY>\n" + "</HTML>";outputStream.write(str.getBytes());socket.close();}}} }
分别输入http://localhost:8080/a和http://localhost:8080/b很显然,在浏览器中的显示的情况是不一样的,我们可以通过完成多个ifelse达到不同的url对应不同的界面的目的,而且我们也能够解决ifelse众多的问题
tomcat_2.ifelse.zip
第二章 一个简单的Servlet容器
1.java大叔提供了一种解决web服务器的调用与实现的方案,(其接口)称之为Servlet
2.因为存在2组人工作(tomcat小组和servlet实现小组),2组人可能根本就不认识(认识就好了...),为了解决继承的向下转型的暴露问题是用外观模式
转载于:https://www.cnblogs.com/liuCy/p/4018371.html
2.一个简单的Servlet容器相关推荐
- tomcat(2)一个简单的servlet容器
[0]README 0.1)本文部分文字转自 "深入剖析Tomcat",旨在学习 一个简单的servlet容器 的基础知识: 0.2)for complete source c ...
- java nio servlet_java nio http服务器(3)简单的Servlet容器
Servlet容器中放着我们所有要访问的Servlet,根据我们具体的请求来访问不同的Servlet.下面是一个简单的Servlet容器的实现.request和response的封装以及连接器的实现代 ...
- 探秘Tomcat——一个简易的Servlet容器
即便再简陋的服务器也是服务器,今天就来循着书本的第二章来看看如何实现一个servlet容器. 背景知识 既然说到servlet容器这个名词,我们首先要了解它到底是什么. servlet 相比你或多或少 ...
- 手写一个简单的IOC容器
手写一个简单的IOC容器 原文 http://localhost:4000/2020/02/25/SSM/spring/%E6%89%8B%E5%86%99%E4%B8%80%E4%B8%AA%E5% ...
- 手写Spring-第一章-实现一个简单的Bean容器
前言 开个新坑,来整点儿大项目.有这个想法是因为用了那么久的Spring,但是某一天突然冒出来一个念头:Spring到底是怎么实现这些功能的.发现脑子一片空白.在我抽出纸巾擦干脑门儿上的汗之后,我决定 ...
- java servlet例子_Servlet学习教程(三)---- 一个简单的Servlet例子
我们用个最简单的Servlet例子来解说一下Servlet简单配置以及Servlet类实现类的写法. 第一,我们新建一个Dynamic Web Project,起名Servlet 点击NEXT,设置D ...
- Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
本文将演示如何利用namespace创建一个完整的容器,并在里面运行busybox.如果对namespace不是很熟悉,请先参考前面几遍介绍不同类型namespace的文章. busybox是一个Li ...
- 设计一个简单的缓存容器
在项目的开发中遇到一个这样的问题:没一个系统用户要有很多与之关联数据,而由于一些页面的加载是由这些数据来判断过滤的,所以与数据库交互加载这样数据的时间变的不可忍受,尤其是大数据量的时候.所以一个比较简 ...
- 实现一个简单的SpringIOC容器
主要思想: 提到IOC,第一反应就是控制反转,我以前以为SpringIOC就是控制反转,控制反转就是SpringIOC,当然这种理解是错误的,控制反转是一种思想,一种模式,而Spring的IOC容器是 ...
最新文章
- 云计算登顶之后,亚马逊人工智能走上新征程
- 设计模式之控制反转和依赖注入的使用小结
- wp7开发官方教程和开发包
- 网络基础4(TCP三次握手,四次握手,TCP流量控制,TCP状态转换 , TCP异常断开,设置TCP属性,端口复用)
- java程序 构建mycircle类_Java语言程序设计(十九)对象和类的应用实例
- 用vue和node写的简易购物车
- 数据挖掘在电信欺诈侦测中的应用
- CS224N刷题——Assignment2.3_RNN:Language Modeling
- 2022 基于SpringBoot/SSM的脚手架租赁系统
- mysql二进制日志管理
- STM32之UART、RS232、RS485通讯
- matlab 模型运行速度,用matlab求解超效率DEA模型运行结果的辨认
- Qt 报错1:cannot find -lGL
- 微信公众号模板消息推送问题汇总
- Ubuntu下安装显卡和cuda
- 十七点学完安全知识超级详细了解进程和病毒知识 转载
- 那些年,磕磕碰碰的BUG
- 网络毕业设计--基于华为ensp防火墙双出口负载拟真实验
- mysql添加字段uniquekey索引_MySQL数据库之mysql为字段添加和删除唯一性索引(unique) 的方法...
- react 条件渲染_React中的条件渲染语法