In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
This article introduces the relevant knowledge of "what is the method of writing Tomcat". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Apache Tomcat is an open source implementation of Java Servlet, JavaServer Pages (JSP), the Java expression language and Java's WebSocket technology. We usually refer to Tomcat as a Web container or Servlet container.
Basic structure tomcat architecture diagram
We can simplify the above architecture diagram to:
What is http protocol?
Http is a network application layer protocol that defines how browsers communicate with web servers and the structure of data packets.
Communication can be roughly divided into four steps:
Establish a connection first.
Send a request packet.
Send a response packet.
Close the connection.
Advantages
Web servers can take advantage of limited connections to serve as many customer requests as possible.
The Operation Mode of Servlet in tomcat
Enter http://ip:port/servlet-day01/hello in the browser address bar
The browser establishes a connection based on IP and port (that is, a network connection with the web server).
The browser needs to package the relevant data (that is, according to the requirements of the http protocol, make a request packet containing some data, such as the request resource path), and send the request packet.
The web server parses the data in the request packet, adds it to the request object, and creates a response object.
The web server creates a Servlet object and then calls the object's service method (which takes request and response as parameters). Note: in the service method, get the data related to the request, such as the request parameter value, by using request, and then write the processing result to response.
The web server takes the data from the response, makes a response packet, and then sends it to the browser.
The browser parses the response packet and then displays it.
You can summarize the only picture:
What is Servlet?
Servlet is a kind of JavaEE specification, mainly to expand the function of Java as a Web service and unify the interface. The functions of web are implemented by other internal vendors such as tomcat,jetty. For example, a http request arrives: the container encapsulates the request as a HttpServletRequest object in servlet, calls init (), service () and other methods to output response, and the container wraps it as a process returned to the client by httpresponse.
What is the Servlet specification?
In terms of the Jar package, the Servlet specification is two Jar files. Servlet-api.jar and jsp-api.jar,Jsp are also a kind of Servlet.
In terms of package, it is the javax.servlet and javax.servlet.http packages.
In terms of interface, it standardizes Servlet interface, Filter interface, Listener interface, ServletRequest interface, ServletResponse interface and so on. The class diagram is as follows:
First edition: Socket edition
Use Socket programming to achieve simple client-side and server-side chat.
The server code is as follows:
Package com.tian.v1; import java.io.*; import java.net.*; public class Server {public static String readline = null; public static String inTemp = null; public static String turnLine = "\ n"; public static final String client = "client:"; public static final String server = "server:"; public static final int PORT = 8090; public static void main (String [] args) throws Exception {ServerSocket serverSocket = new ServerSocket (PORT) System.out.println ("server is ready"); Socket socket = serverSocket.accept (); BufferedReader systemIn = new BufferedReader (new InputStreamReader (System.in)); BufferedReader socketIn = new BufferedReader (new InputStreamReader (socket.getInputStream (); PrintWriter socketOut = new PrintWriter (socket.getOutputStream ()); while (true) {inTemp = socketIn.readLine () If (inTemp! = null & & inTemp.contains ("over")) {systemIn.close (); socketIn.close (); socketOut.close (); socket.close (); serverSocket.close ();} System.out.println (client + inTemp) System.out.print (server); readline = systemIn.readLine (); socketOut.println (readline); socketOut.flush ();}
The client code is as follows:
Package com.tian.v1; import java.io.*; import java.net.*; public class Client {public static void main (String [] args) throws Exception {String readline; String inTemp; final String client = "client says:"; final String server = "Server reply:"; int port = 8090; byte [] ipAddressTemp = {127,0,0,1} InetAddress ipAddress = InetAddress.getByAddress (ipAddressTemp); / / first, create socket directly. The port number 1x1023 is saved by the system. Generally, it is set outside 1023 to Socket socket = new Socket (ipAddress, port); BufferedReader systemIn = new BufferedReader (new InputStreamReader (System.in)); BufferedReader socketIn = new BufferedReader (new InputStreamReader (socket.getInputStream (); PrintWriter socketOut = new PrintWriter (socket.getOutputStream ()). While (true) {System.out.print (client); readline = systemIn.readLine (); socketOut.println (readline); socketOut.flush (); / process inTemp = socketIn.readLine (); if (inTemp! = null & & inTemp.contains ("over")) {systemIn.close () SocketIn.close (); socketOut.close (); socket.close ();} System.out.println (server + inTemp);}
The process is as follows:
Second edition: we directly request http://localhost:8090
The implementation code is as follows:
Package com.tian.v2; import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class MyTomcat {/ * set launch and listen port * / private int port = 8090 / * * @ throws IOException * / public void start () throws IOException {System.out.println ("my tomcat starting..."); String responseData = "6666666"; ServerSocket socket = new ServerSocket (port); while (true) {Socket accept = socket.accept (); OutputStream outputStream = accept.getOutputStream () String responseText = HttpProtocolUtil.getHttpHeader200 (responseData.length ()) + responseData; outputStream.write (responseText.getBytes ()); accept.close ();}} / * launch entry * / public static void main (String [] args) throws IOException {MyTomcat tomcat = new MyTomcat (); tomcat.start ();}}
Write another tool class, which is as follows
Ackage com.tian.v2 Public class HttpProtocolUtil {/ * 200 status code, header information * * @ param contentLength response message length * @ return 200 header info * / public static String getHttpHeader200 (long contentLength) {return "HTTP/1.1 200 OK\ n" + "Content-Type: text/html\ n" + "Content-Length:" + contentLength + "\ n" + "\ r\ n" } / * provide request header information for response code 404 (data content is also included here) * * @ return 404 header info * / public static String getHttpHeader404 () {String str404 = "404 not found" Return "HTTP/1.1 404 NOT Found\ n" + "Content-Type: text/html\ n" + "Content-Length:" + str404.getBytes (). Length + "\ n" + "\ r\ n" + str404;}}
Start the main method:
Use IDEA to access:
Access to the browser:
Since then, our second version has been done. Let's continue with the third version.
Third edition: encapsulating request and response information
A request for http protocol consists of three parts:
Method URI protocol / version
Header of the request
Main body content
such as
POST / index.html HTTP/1.1 Accept: text/plain; text/html Accept-Language: en-gb Connection: Keep-Alive Host: localhost User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98) Content-Length: 33 Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate lastName=tian&firstName=JohnTian
A simple explanation
The first line of data includes: method, URI, protocol, and version. In this example, the method is POST,URI / index.html, the protocol is HTTP/1.1, and the protocol version number is 1.1. They are separated by spaces.
The request header starts at the second line and uses the English colon (:) to separate the key from the value.
The request header and the main content are separated by blank lines, and the request body in the example is form data.
Similar to the request of the http protocol, the response also consists of three parts.
Protocol status description
Response header
Main body content
For example:
HTTP/1.1 200 OK Server: Microsoft-IIS/4.0 Date: Mon, 5 Jan 2004 13:13:33 GMT Content-Type: text/html Last-Modified: Mon, 5 Jan 2004 13:13:12 GMT Content-Length: 112 HTTP Response Example Welcome to Brainy Software
Simple explanation
On the first line, the HTTP/1.1 200 OK represents the protocol, status, and status description.
The response header is then indicated.
A blank line is used to separate the response header from the body content.
Code implementation
Create a utility class to get static resource information.
Package com.tian.v3; import com.tian.v2.HttpProtocolUtil; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; / * extracted some common classes and functions * / public class ResourceUtil {/ * get the complete absolute path according to the request url * / public static String getPath (String url) {String path = ResourceUtil.class.getResource ("/"). GetPath () Return path.replaceAll ("\", "/") + url;} / * output static resource information * / public static void outputResource (InputStream input, OutputStream output) throws IOException {int count = 0; while (count = = 0) {count = input.available ();} int resourceSize = count Output.write (HttpProtocolUtil.getHttpHeader200 (resourceSize). GetBytes ()); long written = 0; int byteSize = 1024; byte [] bytes = new byte [byteSize]; while (written
< resourceSize) { if (written + byteSize >ResourceSize) {byteSize = (int) (resourceSize-written); bytes = new byte [byteSize];} input.read (bytes); output.write (bytes); output.flush (); written + = byteSize;}
In addition, HttpProtocolUtil is still used in the second version.
Then create a Request class to parse and store the relevant parameters of the request.
Package com.tian.v3; import java.io.IOException; import java.io.InputStream; public class Request {/ * request method, eg: GET, POST * / private String method; / * request path, eg: / index.html * / private String url; / * request information input stream
* example * * GET / HTTP/1.1 * Host: localhost * Connection: keep-alive * Pragma: no-cache * Cache-Control: no-cache * Upgrade-Insecure-Requests: 1 * User-Agent: Mozilla/5.0 (Macintosh Intel Mac OS X 10: 15: 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36 * * / private InputStream inputStream; public Request () {} public Request (InputStream inputStream) throws IOException {this.inputStream = inputStream; int count = 0; while (count = = 0) {count = inputStream.available () } byte [] bytes = new byte [count]; inputStream.read (bytes); / / requestString reference: this.inputStream example String requestString = new String (bytes); / / separate String by newline [] requestStringArray = requestString.split ("\\ n"); / / read the first row of data, that is: GET / HTTP/1.1 String firstLine = requestStringArray [0] / / traversing the first row of data is separated by spaces String [] firstLineArray = firstLine.split (""); this.method = firstLineArray [0]; this.url = firstLineArray [1];} public String getMethod () {return method;} public void setMethod (String method) {this.method = method;} public String getUrl () {return url } public void setUrl (String url) {this.url = url;} public InputStream getInputStream () {return inputStream;} public void setInputStream (InputStream inputStream) {this.inputStream = inputStream;}}
Make a small adjustment to the second version of MyTomcat:
Package com.tian.v3; import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class MyTomcat {private static final int PORT = 8090; public void start () throws IOException {System.out.println ("my tomcat starting..."); ServerSocket socket = new ServerSocket (PORT); while (true) {Socket accept = socket.accept () OutputStream outputStream = accept.getOutputStream (); / / encapsulate Request and Response Request request = new Request (accept.getInputStream ()); Response response = new Response (outputStream); / / output response.outputHtml (request.getUrl ()) according to the url in request; accept.close () }} public static void main (String [] args) throws IOException {MyTomcat tomcat = new MyTomcat (); tomcat.start ();}}
Then create another index.html, which is simple:
Hello world you already succeed!
It should be noted that the storage path of the index.html file is not misplaced, depending on the local path, it is placed under the classes folder. You can try debug to see which directory you should put in.
Start MyTomcat.
Visit http://localhost:8090/index.html
Since then, we have done a simple parsing and encapsulation of the Http request parameters and the corresponding parameters.
Although there are still many problems, the words look a little more decent. Let's continue with the fourth edition.
Fourth edition: implementing dynamic request for resources
Students who have used servlet know that there are three very important methods in Servlet: init, destroy, and service. It remembers that when we wrote LoginServlet ourselves, we overridden the doGet () and doPost () methods in HttpServlet. Let's make one for ourselves:
The Servlet class code is as follows:
Public interface Servlet {void init () throws Exception; void destroy () throws Exception; void service (Request request, Response response) throws Exception;}
Then write a HttpServlet to implement Servlet.
The code is implemented as follows:
Package com.tian.v4; public abstract class HttpServlet implements Servlet {@ Override public void init () throws Exception {} @ Override public void destroy () throws Exception {} @ Override public void service (Request request, Response response) throws Exception {String method = request.getMethod (); if ("GET" .equalsIgnoreCase (method)) {doGet (request, response) } else {doPost (request, response);}} public abstract void doGet (Request request, Response response) throws Exception; public abstract void doPost (Request request, Response response) throws Exception;}
Let's write our own Servlet, such as LoginServlet.
Package com.tian.v4; public class LoginServlet extends HttpServlet {@ Override public void doGet (Request request, Response response) throws Exception {String repText = "LoginServlet by GET method"; response.output (HttpProtocolUtil.getHttpHeader200 (repText.length ()) + repText);} @ Override public void doPost (Request request, Response response) throws Exception {String repText = "LoginServlet by POST method"; response.output (HttpProtocolUtil.getHttpHeader200 (repText.length ()) + repText) @ Override public void init () throws Exception {} @ Override public void destroy () throws Exception {}}
Do you remember that when we were learning Servlet, there was a web.xml under the resources directory. We also introduce this xml file in this version.
Login com.tian.v4.LoginServlet login / login
Now that we have introduced the xml file, we need to read the xml file and parse the contents. So here we need to introduce two jar packages.
Dom4j dom4j 1.6.1 jaxen jaxen 1.1.6
Everything is ready, except for the east wind. At this point, let's just make some adjustments to the MyTomcat class.
Here is a very important initServlet () method, which just corresponds to the List servlets in the following figure, but in our code we use Map to store Servlet, which means, put Servlet in the collection.
This is why everyone calls Tomcat a Servlet container, but the real container is the java collection.
Package com.tian.v4; import com.tian.v3.RequestV3; import com.tian.v3.ResponseV3; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.List; import java.util.Map Public class MyTomcat {/ * set launch and listen port * / private static final int PORT = 8090; / * store Servlet information, url: Servlet instance * / private Map servletMap = new HashMap (); public void start () throws Exception {System.out.println ("my tomcat starting..."); initServlet (); ServerSocket socket = new ServerSocket (PORT) While (true) {Socket accept = socket.accept (); OutputStream outputStream = accept.getOutputStream (); / / encapsulate RequestV3 and ResponseV3 RequestV4 requestV3 = new RequestV4 (accept.getInputStream ()); ResponseV4 responseV3 = new ResponseV4 (outputStream); / / get Servlet HttpServlet httpServlet = servletMap.get (requestV3.getUrl ()) according to url / / if Servlet is empty, it is static, otherwise it is dynamic, and the method if (httpServlet = = null) {responseV3.outputHtml (requestV3.getUrl ()) in Servlet needs to be executed;} else {httpServlet.service (requestV3, responseV3);} accept.close () }} public static void main (String [] args) throws Exception {MyTomcat tomcat = new MyTomcat (); tomcat.start () Parse the web.xml file, parse url and servlet, * and save it to a java collection (Map) * / public void initServlet () throws Exception {InputStream resourceAsStream = this.getClass (). GetClassLoader (). GetResourceAsStream ("web.xml"); SAXReader saxReader = new SAXReader (); Document document = saxReader.read (resourceAsStream); Element rootElement = document.getRootElement () List list = rootElement.selectNodes ("/ / servlet"); for (Element element: list) {/ / show Element servletnameElement = (Element) element.selectSingleNode ("servlet-name"); String servletName = servletnameElement.getStringValue (); / / server.ShowServlet Element servletclassElement = (Element) element.selectSingleNode ("servlet-class"); String servletClass = servletclassElement.getStringValue () / / find url-pattern Element servletMapping = (Element) rootElement.selectSingleNode ("/ web-app/servlet-mapping [servlet-name='" + servletName + "']") according to the value of servlet-name; / / show String urlPattern = servletMapping.selectSingleNode ("url-pattern"). GetStringValue (); servletMap.put (urlPattern, (HttpServlet) Class.forName (servletClass). GetDeclaredConstructor (). NewInstance ()) }
Start up and access http://localhost:8090/index.html again
At the same time, we can access http://localhost:8090/login pictures
At this point, the fourth version is done.
But the first four versions all have a common problem, all using BIO.
BIO: synchronize and block, the server implementation mode is to connect one thread at a time, that is, when the client has a connection request, the server needs to start a thread for processing. If the connection does nothing, it will cause unnecessary thread overhead, which can of course be improved through the thread pool mechanism.
So, you see on the Internet handwritten tomcat, also use thread pool to do, here I hope you can get to why to use thread pool to achieve. In addition, BIO is no longer used in the higher version of tomcat.
HTTP/1.1 uses NIO by default.
But this is only a way of communication, the key point is that we need to understand and master the overall implementation of tomcat.
This is the end of the content of "what is the method of writing Tomcat". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.