当前位置: 首页 > news >正文

新闻宣传培训网站内容建设杭州网站建设哪家最好

新闻宣传培训网站内容建设,杭州网站建设哪家最好,怎么自己学做电商,网站开发自学难吗目录 一、Tomcat底层整体架构 1.简介 : 2.分析图 : 3.基于Socket开发服务端的流程 : 4.打通服务器端和客户端的数据通道 : 二、多线程模型的实现 1.思路分析 : 2.处理HTTP请求 : 3.自定义Tomcat : 三、自定义Servlet规范 1. HTTP请求和响应 : 1 CyanServletRequest …目录 一、Tomcat底层整体架构 1.简介 :  2.分析图 :  3.基于Socket开发服务端的流程 :  4.打通服务器端和客户端的数据通道 :  二、多线程模型的实现 1.思路分析 :  2.处理HTTP请求 :  3.自定义Tomcat :  三、自定义Servlet规范 1. HTTP请求和响应 :  1° CyanServletRequest 2° CyanServletResponse 2.Servlet规范 :  1° CyanServlet 2° CyanHttpServlet 3° CyanLoginServlet 3.容器实现 :  1° 思路分析 2° web.xml配置文件 3° 最终版自定义Tomcat 4° 最终版自定义线程类 5° 容器启动测试 一、Tomcat底层整体架构 1.简介 :  Tomcat 有三种运行模式 (BIO[阻塞], NIO[非阻塞], APR)这里采用 BIO 线程模型来模拟实现。 2.分析图 :  如下图所示 :  浏览器请求servlet资源后Tomcat底层会通过Socket网络编程来接收请求每次请求都会创建一个新的线程去调用相应的Web资源并返回。 3.基于Socket开发服务端的流程 :  如下图所示 :  通过获取的Socket对象来获取Socket对象对应的字节输入流和字节输出流。                 可以利用对象转换流将字节流转换为字符流对象(InputStreamReader实现了Reader抽象类)然后再通过BufferedReader的包装将节点流转换成包装流(处理流)。 4.打通服务器端和客户端的数据通道 :  PS :                  Maven配置Web应用运行出现jakarta.servlet.ServletException:                 因为tomcat10之后不是javax.servlet而是jakarta.servlet所以Web的依赖应该换成如下所示 : (pom.xml配置文件 !--jar包的依赖--dependencygroupIdjakarta.servlet/groupIdartifactIdjakarta.servlet-api/artifactIdversion5.0.0/versionscopeprovided/scope/dependency!--jsp的依赖--dependencygroupIdjakarta.servlet.jsp/groupIdartifactIdjakarta.servlet.jsp-api/artifactIdversion3.0.0/versionscopeprovided/scope/dependency MyTomcat类代码如下 : 服务端自定义的Tomcat) package tomcat;import java.io.*; import java.net.ServerSocket; import java.net.Socket;/**服务器端*/ public class MyTomcat {public static void main(String[] args) throws IOException {ServerSocket serverSocket new ServerSocket(8080);System.out.println(Tomcat在8080端口进行监听...);System.out.println(--------------------------------------);while (!serverSocket.isClosed()) {//获取Socket对象Socket socket serverSocket.accept();//接收来自浏览器端的信息InputStream inputStream socket.getInputStream();BufferedReader bufferedReader new BufferedReader(new InputStreamReader(inputStream, UTF-8));String content null; //局部变量在使用前必须赋初值。while ((content bufferedReader.readLine()) ! null) {//判断content是否是空串儿if (content.length() 0) {break;}System.out.println(content);}//服务器向浏览器回送消息OutputStream outputStream socket.getOutputStream();//设置一个HTTP响应包的响应头// /r/n表示换行String respHeader HTTP/1.1 200\r\n Content-Type: text/html;charsetutf-8\r\n\r\n;//设置HTTP响应的响应体String respBody respHeader h1你好/h1;/*注意这里不能使用字符包装流来写数据!!!。*/outputStream.write(respBody.getBytes());System.out.println(--------------------------------------);System.out.println(respBody);//释放资源outputStream.flush();outputStream.close();inputStream.close();socket.close(); // serverSocket.close();}} }在浏览器地址栏访问本机8080端口。                 login.html代码如下 :  !DOCTYPE html html langen headmeta charsetUTF-8titlelogin/titlestyletable, tr, td {border:2px cornflowerblue solid;border-collapse: collapse;padding: 10px;background-color: lightcyan}#tr01 {text-align: center}/style /head body form action/Cyan_Tomcat/login methodsgettabletrth colspan2User Logging/th/trtrtdUsername: /tdtdinput typetext nameusername//td/trtrtdPassword: /tdtdinput typepassword namepassword//td/trtr idtr01tdinput typesubmit valueSubmit//tdtdinput typereset valueReset//td/tr/table /form /body /html LoginServlet类代码如下 :  package servlet;import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter;/*** author : Cyan_RA9* version : 21.0*/ WebServlet(urlPatterns {/login}) public class LoginServlet extends HttpServlet {Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println(LoginServlets doPost is invoked~);resp.setContentType(text/html; charsetutf-8);PrintWriter writer resp.getWriter();req.setCharacterEncoding(utf-8);String username req.getParameter(username);String password req.getParameter(password);if (Cyan.equals(username) 123.equals(password)) {writer.print(h1登录成功/h1);} else {writer.print(h1登录失败请重新尝试/h1);}}Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);} }运行效果 :  如果以Web工程配置好的Tomcat运行就会按照LoginServlet类的代码逻辑来处理业务如下图所示 : (GIF) 如果以自定义的Tomcat运行就会以MyTomcat类中的代码逻辑来处理业务。                 如下图所示 : (GIF) 二、多线程模型的实现 1.思路分析 :  当服务器端接收到浏览器端的HTTP请求后启动一个新的线程令该线程持有浏览器对应的Socket对象完成线程和浏览器的对接。                 可通过实现Runnable接口的方式定义线程类HttpRequestHandler线程对象用于处理来自浏览器的HTTP请求。 2.处理HTTP请求 :  线程类HttpRequestHandler类代码如下 :  package tomcat.handler;import tomcat.http.CyanServletRequest; import tomcat.http.CyanServletResponse; import tomcat.servlet.CyanLoginServlet;import java.io.*; import java.net.Socket;public class HttpRequestHandler implements Runnable {private Socket socket;public HttpRequestHandler(Socket socket) {this.socket socket;}Overridepublic void run() {try {//接收客户端的信息InputStream inputStream socket.getInputStream();/* 以下代码已在CyanServletRequest类中实现BufferedReader bufferedReader new BufferedReader(new InputStreamReader(inputStream, utf-8));//BIO每次请求都对应一个新的线程System.out.println(当前线程 Thread.currentThread().getName());String content null; //局部变量在使用前必须赋初值。while ((content bufferedReader.readLine()) ! null) {//判断是否读到了空字符串if (content.length() 0) {break;}System.out.println(content);} *///Die first and live second//获取客户端的信息利用了CyanServletRequest中封装好的方法//以下代码已在CyanLoginServlet中实现 /* CyanServletRequest cyanServletRequest new CyanServletRequest(inputStream);String username cyanServletRequest.getParameter(username);String password cyanServletRequest.getParameter(password);System.out.println(username username);System.out.println(password password);System.out.println(cyanServletRequest);*///给客户端回送信息//以下代码已在CyanLoginServlet类中实现。 /* CyanServletResponse cyanServletResponse new CyanServletResponse(socket.getOutputStream());String resp CyanServletResponse.respHeader h1CyanServletResponse!/h1;OutputStream outputStream cyanServletResponse.getOutputStream();outputStream.write(resp.getBytes());outputStream.flush();outputStream.close();*/CyanServletRequest cyanServletRequest new CyanServletRequest(inputStream);CyanServletResponse cyanServletResponse new CyanServletResponse(socket.getOutputStream());CyanLoginServlet cyanLoginServlet new CyanLoginServlet();cyanLoginServlet.doPost(cyanServletRequest, cyanServletResponse);//释放资源inputStream.close();socket.close();/* 以下代码已在CyanServletResponse类中实现 :String respHeader HTTP/1.1 200\r\n Content-Type: text/html;charsetutf-8\r\n\r\n;String respHttp respHeader h1Cyan_RA9/h1;System.out.println(-----------------------------------------------);System.out.println(回送的信息如下(回显));System.out.println(respHttp);OutputStream outputStream socket.getOutputStream();outputStream.write(respHttp.getBytes());//释放资源outputStream.flush();outputStream.close();inputStream.close();socket.close(); */} catch (IOException e) {throw new RuntimeException(e);} finally {//确保Socket关闭if (socket ! null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}}} }3.自定义Tomcat :  在MyTomcat_EX类中实现线程的分发。                 MyTomcat_EX类代码如下 :  package tomcat;import tomcat.handler.HttpRequestHandler;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket;/*** author : Cyan_RA9* version : 21.0*/ public class MyTomcat_EX {public static void main(String[] args) throws IOException {ServerSocket serverSocket new ServerSocket(8080);System.out.println(MyTomcat_EX在8080端口进行监听...);while (!serverSocket.isClosed()) {Socket socket serverSocket.accept();HttpRequestHandler httpRequestHandler new HttpRequestHandler(socket);Thread thread new Thread(httpRequestHandler);thread.start();}} }运行效果 : (GIF) 三、自定义Servlet规范 1. HTTP请求和响应 :  1° CyanServletRequest CyanServletRequest类的作用等同于原始的HttpServletRequest该类用于封装HTTP请求中的数据eg : method, URI, 以及表单数据的参数列表等。                 CyanServletRequest类代码如下 :  package tomcat.http;import java.io.*; import java.util.HashMap;/*** author : Cyan_RA9* version : 21.0* function : like the original HttpServletRequest.*/ public class CyanServletRequest {private String method;private String URI;private HashMapString, String parametersMapping new HashMap();private InputStream inputStream;/*此处传入的InputStream对象是和Socket关联的InputStream.*/public CyanServletRequest(InputStream inputStream) {this.inputStream inputStream;//完成对HTTP请求数据的封装this.init();}private void init() {System.out.println(\nCyanServletRequests init is invoked~);try {//注意转换流的形参列表BufferedReader bufferedReader new BufferedReader(new InputStreamReader(inputStream, utf-8));//首先读取HTTP请求的请求行/* eg : GET /Cyan/cyan.html HTTP/1.1 */String requestLine bufferedReader.readLine();String[] requestLineArr requestLine.split( );//获取methodmethod requestLineArr[0];//获取URIint index requestLineArr[1].indexOf(?);if (index -1) { //if判断成立说明请求行中没有参数列表URI requestLineArr[1];} else {URI requestLineArr[1].substring(0, index);//获取参数列表String parameters requestLineArr[1].substring(index 1);String[] parameterPairs parameters.split();//兼容性处理防止?后啥都没有。if (null ! parameterPairs !.equals(parameterPairs)) {for (String parameterPair : parameterPairs) {String[] parameter parameterPair.split();if (parameter.length 2) { //判断是否为一对完整的namevalue.parametersMapping.put(parameter[0],parameter[1]);}}}}//!!! 直接关闭Socket关联的InputStream会引起Socket的关闭。//inputStream.close();} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}public String getMethod() {return method;}public void setMethod(String method) {this.method method;}public String getURI() {return URI;}public void setURI(String URI) {this.URI URI;}//重要public String getParameter(String name) {if (parametersMapping.containsKey(name)) { //注意此处API的使用return parametersMapping.get(name);} else {return null;}}Overridepublic String toString() {return CyanServletRequest{ method method \ , URI URI \ , parametersMapping parametersMapping };} }CyanServletRequest类测试运行效果如下GIF :  2° CyanServletResponse CyanServletResponse类的作用等同于原始的HttpServletResponse用于封装HTTP响应的相关信息。                 CyanServletResponse类代码如下 :  package tomcat.http;import java.io.OutputStream;/*** author : Cyan_RA9* version : 21.0* function : like the original HttpServletResponse*/ public class CyanServletResponse {private OutputStream outputStream;//设置一个HTTP响应头public static final String respHeader HTTP/1.1 200\r\n Content-Type: text/html;charsetutf-8\r\n\r\n;//传入与Socket关联的OutputStream对象public CyanServletResponse(OutputStream outputStream) {this.outputStream outputStream;}public OutputStream getOutputStream() {return outputStream;} }运行测试如下GIF图 2.Servlet规范 :  1° CyanServlet CyanServlet仅保留原生Servlet的init, destroy, service方法其中service方法供将来CyanServlet的抽象实现类CyanHttpServlet去重写。注意service方法的形参列表要使用自定义的CyanServletRequest 和 CyanServletResponse.                 CyanServlet接口代码如下 :  package tomcat.servlet;import tomcat.http.CyanServletRequest; import tomcat.http.CyanServletResponse;import java.io.IOException;public interface CyanServlet {void init() throws Exception;void service(CyanServletRequest req, CyanServletResponse resp) throws IOException;void destroy(); }2° CyanHttpServlet CyanHttpServlet的作用类似于原生的HttpServlet在CyanHttpServlet中实现CyanServlet接口中的service方法在service方法中要对HTTP请求的method类型进行判断。 CyanHttpServlet抽象类代码如下 :  package tomcat.servlet;import tomcat.http.CyanServletRequest; import tomcat.http.CyanServletResponse;import java.io.IOException;public abstract class CyanHttpServlet implements CyanServlet{Overridepublic void service(CyanServletRequest req, CyanServletResponse resp) throws IOException {//忽略大小写if (GET.equalsIgnoreCase(req.getMethod())) {this.deGet(req, resp);} else if (POST.equalsIgnoreCase(req.getMethod())) {this.doPost(req, resp);}}//模板设计模式public abstract void deGet(CyanServletRequest req, CyanServletResponse resp);public abstract void doPost(CyanServletRequest req, CyanServletResponse resp); }3° CyanLoginServlet CyanLoginServlet是一个简单的servlet实例用于继承CyanHttpServlet抽象类并实现CyanHttpServlet类中的doGet和doPost抽象方法。之后在HttpRequestHandler线程类中先尝试直接调用CyanLoginServlet实例。                 CyanLoginServlet代码如下 :  package tomcat.servlet;import tomcat.http.CyanServletRequest; import tomcat.http.CyanServletResponse;import java.io.IOException; import java.io.OutputStream;public class CyanLoginServlet extends CyanHttpServlet{Overridepublic void deGet(CyanServletRequest req, CyanServletResponse resp) {doPost(req, resp);}Overridepublic void doPost(CyanServletRequest req, CyanServletResponse resp) {String username req.getParameter(username);String password req.getParameter(password);//获取与当前Socket相关联的OutputStream对象OutputStream outputStream resp.getOutputStream();String respInfo CyanServletResponse.respHeader h1username username /h1br/ h1password password /h1 br/ h3Cyan_RA9/h3;try {outputStream.write(respInfo.getBytes());outputStream.flush();outputStream.close();} catch (IOException e) {throw new RuntimeException(e);}}Overridepublic void init() throws Exception {}Overridepublic void destroy() {} }此外还需要更新HttpServletHandler类中的类型将已封装好的代码注释掉HttpServletHandler类已更新在上文“多线程模型实现”的HTTP请求处理模块。                 运行效果如下图所示 :  3.容器实现 :  1° 思路分析 Tomcat中维护有至少两个大的HashMap容器。以web.xml配置文件的方式为例其中一个HashMap容器key存放url-patternvalue存放servlet-name另一个HashMap容器key存放servlet-namevalue存放通过servlet-class来反射生成的servlet实例。 2° web.xml配置文件 web.xml配置文件如下 :  !DOCTYPE web-app PUBLIC-//Sun Microsystems, Inc.//DTD Web Application 2.3//ENhttp://java.sun.com/dtd/web-app_2_3.dtd !--xmlnshttp://xmlns.jcp.org/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsdversion4.0-- !--IDEA报错——因为这是我们自定义的servletIDEA无法识别无所谓继续用-- web-appdisplay-nameArchetype Created Web Application/display-nameservletservlet-nameCyanLoginServlet/servlet-nameservlet-classtomcat.servlet.CyanLoginServlet/servlet-class/servletservlet-mappingservlet-nameCyanLoginServlet/servlet-nameurl-pattern/cyanLogin/url-pattern/servlet-mapping /web-app3° 最终版自定义Tomcat 在MyTomcat_Pro类中定义两个CurrentHashMap对象定义init方法完成对两个CurrentHashMap对象的初始化使用Dom4J读取web.xml配置文件。                 首先需要在Maven的pom.xml配置文件中引入dom4j依赖如下图所示 :  然后将web.xml配置文件拷贝到/target/classes/目录下一份如下图所示 :  MyTomcat_Pro代码如下 :  package tomcat;import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import tomcat.handler.HttpRequestHandler; import tomcat.servlet.CyanHttpServlet;import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; import java.net.ServerSocket; import java.net.Socket; import java.util.List; import java.util.concurrent.ConcurrentHashMap;/*** The final own custom Tomcat.*/ public class MyTomcat_Pro {//Tomcat维护的第一个容器//String -- servlet-name//CyanHttpServlet -- 可存放它的子类(即各种servlet实例)public static final ConcurrentHashMapString, CyanHttpServlet servletMapping new ConcurrentHashMap();//Tomcat维护的第二个容器//String -- url-patterns//String -- servlet-namepublic static final ConcurrentHashMapString, String servletURLMapping new ConcurrentHashMap();public static void main(String[] args) {MyTomcat_Pro myTomcat_pro new MyTomcat_Pro();myTomcat_pro.init();myTomcat_pro.run();}public void run() {try {ServerSocket serverSocket new ServerSocket(8080);System.out.println(MyTomcat_Pro在8080端口进行监听...);while (!serverSocket.isClosed()) {Socket socket serverSocket.accept();Thread thread new Thread(new HttpRequestHandler(socket));thread.start();}} catch (IOException e) {throw new RuntimeException(e);}}public void init() {String path MyTomcat_Pro.class.getResource(/).getPath();//path /javaProject/Servlet/Cyan_Tomcat/target/classes///使用Dom4J技术解析web.xml文件SAXReader saxReader new SAXReader();try {//注意文件名Document document saxReader.read(new File(path web.xml));System.out.println(document document);//获取根元素web-appElement rootElement document.getRootElement();//得到根元素下面的所有子元素ListElement elements rootElement.elements();//遍历并判断for (Element element : elements) {if (servlet.equals(element.getName())) {Element servlet_name element.element(servlet-name);Element servlet_class element.element(servlet-class);//反射机制创建servlet实例 (注意getText()方法的使用)Class? clazz Class.forName(servlet_class.getText().trim());Constructor? constructor clazz.getConstructor();CyanHttpServlet o (CyanHttpServlet) constructor.newInstance();servletMapping.put(servlet_name.getText(), o);} else if (servlet-mapping.equals(element.getName())) {Element url_pattern element.element(url-pattern);Element servlet_name element.element(servlet-name);servletURLMapping.put(url_pattern.getText(), servlet_name.getText());}}} catch (Exception e) {throw new RuntimeException(e);}} }4° 最终版自定义线程类 package tomcat.handler;import tomcat.MyTomcat_Pro; import tomcat.http.CyanServletRequest; import tomcat.http.CyanServletResponse; import tomcat.servlet.CyanHttpServlet; import tomcat.servlet.CyanLoginServlet;import java.io.*; import java.net.Socket;public class HttpRequestHandler implements Runnable {private Socket socket;public HttpRequestHandler(Socket socket) {this.socket socket;}Overridepublic void run() {try {//接收客户端的信息CyanServletRequest cyanServletRequest new CyanServletRequest(socket.getInputStream());CyanServletResponse cyanServletResponse new CyanServletResponse(socket.getOutputStream());String uri cyanServletRequest.getURI();System.out.println(uri uri);String servlet_name MyTomcat_Pro.servletURLMapping.get(uri);/*这里的servlet_name可能为空。解决方式一 : 将CurrentHashMap替换为HashMap解决方式二 : 增加一个是否为null的判断。*/if (servlet_name null) {servlet_name ;}//多态 -- 动态绑定CyanHttpServlet cyanHttpServlet MyTomcat_Pro.servletMapping.get(servlet_name);if (cyanHttpServlet ! null) { //判断是否正常得到servlet实例cyanHttpServlet.service(cyanServletRequest, cyanServletResponse);} else {//如果没有找到servlet返回404String resp CyanServletResponse.respHeader h1404 Not Found!/h1;OutputStream outputStream cyanServletResponse.getOutputStream();outputStream.write(resp.getBytes());outputStream.flush();outputStream.close();}//释放资源socket.close();} catch (IOException e) {throw new RuntimeException(e);} finally {//确保Socket关闭if (socket ! null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}}} }5° 容器启动测试 如下图所示GIF
http://www.huolong8.cn/news/39006/

相关文章:

  • 做母婴产品哪个网站做的好处e网站建设
  • 物流跟踪网站建设临沂 网站推广
  • 营销型网站建设遨龙网上查询个人房产信息
  • 网页代码福田企业网站优化哪个好
  • 做网站用的图片公众号开发者密码是什么意思
  • 成都学校网站制作免费的小程序商城
  • 保险网站导航外国人的做视频网站吗
  • 网站名查询厦门 网站建设
  • 用asp做的网站建设工程指数网站
  • 淘客商品网站怎么做的嘉定区网站建设公司
  • 名者观看网站商城小程序开发报价
  • 网站建设企业如何为公司建设苏州马可波罗网站建设
  • 运营商做网站怎么使用模板建设网站
  • 赣榆建设局网站军事新闻播报最新
  • 网站免费制作平台wordpress显示未开启stmp服务
  • 阿里云做电脑网站电商新手入门教程
  • 做网站还有开发文档吗排版漂亮的网站
  • 网站营销代理网站设计是用ps做图吗
  • 用php做视频网站有哪些dw网站建设代码
  • 山东电力建设第一工程有限公司网站注册网站设计的主题
  • 福建省龙岩市建设培训中心网站乐清网络公司哪家最好
  • 东莞网站制作哪里找宠物发布网站模板
  • 网站建设968住房城乡建设网站查询
  • 南昌网站建设大全购物网站排名2018
  • 网站建设择网络营销的基本特点和描述
  • 深圳公司 网站建设手机下载视频网站模板下载
  • 做网站 需要 域名 空间企业市场营销
  • 广州天河网站开发公司做淘宝店头的网站
  • 网站备案需要几天不定期更新域名
  • 网站建设一般用什么语言公司网站建设东莞