静态Web

说到Servlet自然就要说到Web,Web分为静态Web和动态Web,之前我一直都傻傻分不清两者的区别,直到用JAVA编写了一个服务器后才明白二者的区别,所谓静态Web,实际上就是指,客户端要请求的资源文件,服务器已经提前把它放在了文件系统(磁盘)上,看下面用Java实现的一个静态Web服务器

public class HTTPService {private static HashMap<String,Servlet> servletCache = new HashMap<>();public static void init(){servletCache.put("HTTPServlet",new HTTPServlet());}public static void main(String[] args) {init();int port;ServerSocket serversocket;port=8080;try {serversocket = new ServerSocket(port);  //默认服务器套接字ip为本地地址System.out.println("服务器正在监听端口:8080");while (true) {try{Socket socket = serversocket.accept();//会进入阻塞状态,直到客户端与服务器TCP建立System.out.println("建立了与客户端的一个新的tcp连接,客户端地址为" + socket.getInetAddress() + ":" + socket.getPort());service(socket);}catch (Exception e){System.out.println("客户端请求资源不存在");}}} catch (Exception e) {System.out.println("客户端请求资源不存在");}}public static void service(Socket socket) throws Exception {InputStream socketIn = socket.getInputStream();//获得客户端请求信息流Thread.sleep(500);  //与客户端TCP请求已建立,还需要等待客户端发送http请求,如果在TCP后立马响应HTTP,socket内容可能为空int size = socketIn.available();byte[] buffer = new byte[size];socketIn.read(buffer);String request = new String(buffer);int endIndex = request.indexOf("\r\n");if (endIndex==-1)endIndex = request.length();String firstLineOfRequest = request.substring(0,endIndex);String[] parts = firstLineOfRequest.split(" ");String uri="";String contentType="";if (parts.length>=2){uri = parts[1];}//静态webif (uri.indexOf("html") != -1)contentType = "text/html";else if (uri.indexOf("jpg") != -1)contentType = "image/jepg";elsecontentType = "application/octet-stream";String firstLineOfResponse = "HTTP/1.1 200 OK\r\n";  //响应行String responseHeader = "Content-Type:" + contentType + "\r\n\r\n";// FileInputStream in = new FileInputStream("E:\\IDEA WORKSPACE\\ServiceDemo\\resources\\index.html");System.out.println(HttpServer.class.getResource(""));InputStream in = HTTPService.class.getResourceAsStream("root/" + uri);System.out.println(HTTPService.class.getResource("root/" + uri));OutputStream output = socket.getOutputStream();output.write(firstLineOfResponse.getBytes());output.write(responseHeader.getBytes());buffer = new byte[1024];int len = 0;while ((len = in.read(buffer)) != -1) {System.out.println(1);output.write(buffer, 0, len);}Thread.sleep(1000);//睡眠1秒,等待客户端接收http响应结果,socket代表两者间的tcp连接,如果立马断开,客户端可能就收不到响应结果了socket.close();}}

将事先准备好的index.html文件放在磁盘上,将代码运行起来,此时HTTPServer就作为一个服务开始监听电脑上的8080端口了,打开浏览器,在url地址栏输入localhost:8080/index.html,结果如下:


工作原理如下:

HTTPServer接收到来自客户端的请求后,就会在磁盘上查找客户端请求的资源文件,然后把文件响应给客户端,index.html就事先存放在磁盘上,然后当浏览器请求index.html,HTTPServer就把html文件响应给浏览器,浏览器再解析html文件后,就是我们看到的Hello页面了。

动态Web

网上经常能看见一句话,动态Web就是每个用户看到的东西是不一样的,这句话没错,但是还不太能够帮助我们理解动态Web。那么动态Web到底是什么,动态Web就是指客户端可以与服务器进行交互,并且客户端请求的资源文件,是由服务器动态生成的。举这么一个例子,假设D是一个在某城市居住了很久的人,这一天A向D问路X街怎么走,D经过思考后,告诉了A,此时B又来问路Y街怎么走,对于C来说,简直轻而易举。上述中A,B看作客户端,D是服务器,而问路可以看作客户端向服务器请求的资源文件,去某城市可以看作是客户端与服务器的交互,很明显,A和B得到的响应内容都是不同的,服务器在得到客户端的请求后,执行业务逻辑操作,得出了通往某城市怎么走,然后响应给客户端。

public class HTTPService {private static HashMap<String,Servlet> servletCache = new HashMap<>();public static void init(){servletCache.put("HTTPServlet",new HTTPServlet());}public static void main(String[] args) {init();int port;ServerSocket serversocket;port=8080;try {serversocket = new ServerSocket(port);  //默认服务器套接字ip为本地地址System.out.println("服务器正在监听端口:8080");while (true) {try{Socket socket = serversocket.accept();//会进入阻塞状态,直到客户端与服务器TCP建立System.out.println("建立了与客户端的一个新的tcp连接,客户端地址为" + socket.getInetAddress() + ":" + socket.getPort());service(socket);}catch (Exception e){System.out.println("客户端请求资源不存在");}}} catch (Exception e) {System.out.println("客户端请求资源不存在");}}public static void service(Socket socket) throws Exception {InputStream socketIn = socket.getInputStream();//获得客户端请求信息流Thread.sleep(500);  //与客户端TCP请求已建立,还需要等待客户端发送http请求,如果在TCP后立马响应HTTP,socket内容可能为空int size = socketIn.available();byte[] buffer = new byte[size];socketIn.read(buffer);String request = new String(buffer);int endIndex = request.indexOf("\r\n");if (endIndex==-1)endIndex = request.length();String firstLineOfRequest = request.substring(0,endIndex);String[] parts = firstLineOfRequest.split(" ");String uri="";String contentType="";if (parts.length>=2){uri = parts[1];}System.out.println(uri);if(uri.indexOf("servlet")!=-1){   //动态webString servletName = "";if (uri.indexOf("?")!=-1)servletName = uri.substring(uri.indexOf("servlet/")+8,uri.indexOf("?"));elseservletName = uri.substring(uri.indexOf("servlet/")+8,uri.length());System.out.println(servletName);Servlet servlet = servletCache.get(servletName);System.out.println(servletCache);System.out.println(servlet);if (servlet == null)throw new Exception();servlet.init();servlet.service(request,socket.getOutputStream());}else {//静态webif (uri.indexOf("html") != -1)contentType = "text/html";else if (uri.indexOf("jpg") != -1)contentType = "image/jepg";elsecontentType = "application/octet-stream";String firstLineOfResponse = "HTTP/1.1 200 OK\r\n";  //响应行String responseHeader = "Content-Type:" + contentType + "\r\n\r\n";// FileInputStream in = new FileInputStream("E:\\IDEA WORKSPACE\\ServiceDemo\\resources\\index.html");System.out.println(HttpServer.class.getResource(""));InputStream in = HTTPService.class.getResourceAsStream("root/" + uri);System.out.println(HTTPService.class.getResource("root/" + uri));OutputStream output = socket.getOutputStream();output.write(firstLineOfResponse.getBytes());output.write(responseHeader.getBytes());buffer = new byte[1024];int len = 0;while ((len = in.read(buffer)) != -1) {System.out.println(1);output.write(buffer, 0, len);}}Thread.sleep(1000);//睡眠1秒,等待客户端接收http响应结果,socket代表两者间的tcp连接,如果立马断开,客户端可能就收不到响应结果了socket.close();}}
public class HTTPServlet implements Servlet{@Overridepublic void init() {}@Overridepublic void service(String request, OutputStream out) throws IOException {int endIndex = request.indexOf("/r/n");String firstOfRequest = "";if (endIndex!=-1)firstOfRequest = request.substring(0,endIndex);elsefirstOfRequest = request;String[] parts = firstOfRequest.split(" ");String method = parts[0];String uri = parts[1];String userName="";if (method.equalsIgnoreCase("get")){if (uri.indexOf("username=")!=-1){String[] params = uri.substring(uri.indexOf("?") + 8, uri.length()).split("&");String[] params_parts = params[0].split("=");userName = params_parts[1];}}if (method.equalsIgnoreCase("post")){if (request.indexOf("\r\n\r\n")!=-1){String content = request.substring(request.indexOf("\r\n\r\n"+4,request.length()));if (content.indexOf("username=")!=-1){String[] contentParts = content.split("&");userName = (contentParts[0].split("="))[1];}}}userName = URLDecoder.decode(userName,"utf-8");System.out.println(userName);out.write("HTTP/1.1 200 OK\r\n".getBytes());out.write("Content-Type:text/html\r\n\r\n".getBytes());out.write(("<meta charset=\"UTF-8\"> <h1>Hello,"+userName+"</h1>").getBytes());}
}
public interface Servlet {public void init();public void service(String request, OutputStream out) throws IOException;
}

前面说过,动态Web中服务器在接收到请求后,会执行业务逻辑操作,这个业务逻辑操作其实就是由服务器内的servlet模块实现的,下面的图就是上述的代码的执行原理

如果客户端的URL访问的是servlet目录下,那么就代表是访问动态资源,服务器就会交给servlet处理,否则就会当成普通静态文件处理,从磁盘上取出响应即可。学习过一点如何编写webapp的同学会发现,上述代码中的servlet缓冲池(servletCache)与web.xml中的servlet映射很相似,都是通过名字来映射到一个具体的servlet实现类,服务器动态加载servlet类实现业务逻辑操作也体现了动态Web的特性。
在浏览器的url地址栏输入http://localhost:8080/servlet/HTTPServlet?username=“王小虎”,结果如下
在动态Web中,客户端可以与服务器交互,服务器通过与客户端的交互,来动态响应客户端。

通过Java编写一个服务器理解动态Web,静态Web相关推荐

  1. java编写一个可切换的界面_java web 项目实现手动中英文切换

    Java程序的国际化主要通过如下3个类完成 Java.util.ResourceBundle:用于加载资源包 Java.util.Locale:对应一个特定的国家/地区.语言环境 Java.text. ...

  2. java编写存钱_用Java编写一个简单的存款

    package desposit.money; public class DespositMoney { public static void main(String[] args) { Custom ...

  3. 用java编写一个简单计算器

    java 采用java编写一个简单计算器,使用awt和swing 代码如下: import java.awt.Color; import java.awt.Font; import java.awt. ...

  4. 停车场管理系统 java_使用java编写一个停车场管理系统

    使用java编写一个停车场管理系统 发布时间:2020-11-30 16:00:28 来源:亿速云 阅读:145 作者:Leah 这篇文章给大家介绍使用java编写一个停车场管理系统,内容非常详细,感 ...

  5. java编写一个个人通信录程序

    Java编写一个个人通信录程序,具有如下功能: (1)定义一个类,包括姓名.邮政编码.通信地址等成员变量 (2)查找:根据姓名在文件中查找个人信息,如果找到则显示出来 (3)添加:向文件中写个人信息 ...

  6. java编写一个彩票开奖的模拟程序.游戏共有两种玩法,一种是21选5,即玩家输入5个1到21内的不重复的数。另外一种玩法是6+1玩法,即要求玩家输入7个整数,代表所购买的彩票号码,最后一个是特码。

    java编写一个彩票开奖的模拟程序.游戏共有两种玩法,一种是21选5,即玩家输入5个1到21内的不重复的数.另外一种玩法是6+1玩法,即要求玩家输入7个整数,代表所购买的彩票号码,最后一个是特码. 具 ...

  7. 用Java编写一个最简单的桌面程序

    使用Java的优势在于网络应用方面,但Java也提供了强大的用于开发桌面程序的API,它们包含在javax.swing包中.使用这个包可以编写简单的Java桌面应用程序. Java的javax.swi ...

  8. 如何用java编写一个简单的多人PK游戏

    如何用java编写一个简单的多人PK游戏 类与对象---PK游戏的编写 素材取用----王者荣耀和BILIBILI 创建两个对战的角色(PK游戏最少需要两名角色) 创建孙尚香和Van 设置孙尚香和Va ...

  9. JAVA编写一个年龄大小判断年纪题

    JAVA编写一个年龄大小判断年纪题 public class C{public static void main(String [] args){java.util.Scanner s = new j ...

最新文章

  1. C语言中文件的读写(fputc和fgetc)(putchar和getchar)
  2. 聚类Introducion
  3. python-桶排序
  4. python时间序列动图_python中如何用matlibplot画时间序列图?
  5. VS2010 安装问题积累
  6. ros amcl 参数配置
  7. tcp为什么需要3次握手和3次握手的过程
  8. pycharm 安装_pycharm安装
  9. Java实战-山寨QQ
  10. R语言基于S3的面向对象编程
  11. Flink 1.10 SQL、HiveCatalog 与事件时间整合示例
  12. 动态域名ddclient
  13. PHP为什么会被认为是草根语言?
  14. iOS开发:图标生成器Prepo 的使用,讲的明明白白
  15. zz成人笑话四级考试(绝对经典)
  16. 黑客与画家 读书笔记
  17. 100个实用的 Linux Shell 脚本经典案例,收藏备用~
  18. 计算机网络分层及原理
  19. 如何保存BING首页的图片壁纸
  20. 半导体物理(硅的能带解读)

热门文章

  1. 关于在Windows下AndroidStudio.使用React-Native开发android报错红屏“run react-native start”解决
  2. 电信aep平台是什么意思_江苏天鼎证券:股票平台跳水是什么意思?股票为什么会跳水?...
  3. 男人的那些统一话术......
  4. 程序员搞笑故事:给女儿织的辫子 ​​​​,你知道是什么算法吗?
  5. 要成为年薪五十万的数据分析师,除了技术还需要什么?
  6. python3 csv读写_在python3中读取、更新和写入更新的CSV文件
  7. linux图形界面鼠标变成小手_加载Linux系统,树莓派变身桌面电脑
  8. linux系统管理命令使用,Linux系统管理使用之基本命令(1)
  9. java匹配两个字符_·代表任意一个字符,*代表任意一串字符,判断两个字符串是否匹配?...
  10. 独立主题需要有index.php模板文件,wordpress 主题模板文件列表及其作用