Analysis of Servlet

Analysis of Servlet

(1) Basic overview of Setvlet

(1) What is Servlet?

Servlet (Server Applet) is the abbreviation of JavaServlet, called small service program or service connector. The server-side program written in Java has the characteristics of being independent of platform and protocol. The main function is to browse and generate data interactively, and generate dynamic Web content is

In JavaWeb, we will be exposed to three major components ( Servlet , Filter , Listener )

Servlet is called by the server to process the request received by the server, that is, complete, accept the request data --> process the request --> complete the response, its essence is a java class that implements the Servlet interface

The Servlet class is written by us, but the object is created by the server, and the server calls the corresponding method

(2) What is Servlet used for?

Some of the more common functions in the network, such as: login, registration, file download and upload, and other interactive functions, and Servlet can help us deal with these requests. It can be said that Servlet is one of the important knowledge points in JavaWeb knowledge.

(2) Ways to implement Servlet

There are three ways to implement Servlet:

  • Implement javax.servlet.Servlet interface;
  • Inherit the javax.servlet.GenericServlet class;
  • Inherit the javax.servlet.http.HttpServlet class;

In actual development, we usually choose to inherit the HttpServlet class to complete our ervlet, but it is also very important to know the Servlet interface, and it is an indispensable part of our introductory knowledge.

(1) Create our first Servelt

We create a web project and select the corresponding parameters. The jdk we installed is version 1.8, and we can choose the version of JavaEE8. The corresponding versions are 4.0, but here we choose the 7 version that is still used in the market.

Create a Demo class to implement the Servlet interface, and then we quickly generate the methods that are not implemented in this interface. Let s ignore the other four methods in the Servlet for now, and only care about the service() method, because it is the method used to process the request. An output statement is given in this method:

package cn.ideal.web.servlet; import javax.servlet.*; import java.io.IOException; public class ServeltDemo1 implements Servlet { //Initialization method @Override public void init (ServletConfig servletConfig) throws ServletException { } //Servlet configuration method @Override public ServletConfig getServletConfig () { return null ; } //Provide service methods @Override public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println( "Ideal 3.Years~" ); } //Servlet information method @Override public String getServletInfo () { return null ; } //Destroy method @Override public void destroy () { } } Copy code

Finished writing one of the simplest Servlet code, but how can it be accessed in the browser? We need to

web/WEB-INF
Down
web.xml
To configure, we are in
<web-app></web-app>
Add the following code (although there is an optimization method in the later stage, it is recommended that you remember it)

< servlet > <!-- Give this Servlet a name, generally the same as the class name--> < servlet-name > ServletDemo1 </servlet-name > <!--Full class name--> < servlet-class > cn .ideal.web.servlet.ServeltDemo1 </servlet-class > </servlet > <!--Configuration mapping path--> < servlet-mapping > < servlet-name > ServletDemo1 </servlet-name > <!--The path of external access--> < url-pattern >/Demo1 </url-pattern > </servlet-mapping > Copy code

Now we are based on our

url-pattern
Visit the path configured in the, and it is output in the console as expected.

(2) The role of web.xml

Build on the progress we simply analyze the causes of this web.xml, in fact, in web.xml configuration purposes of Servlet , it is to put in the browser's access paths tied together with the corresponding Servlet , the above example is the access path:

/Demo1
versus
cn.ideal.web.servlet.ServeltDemo1
Bound together

1,

<servlet></servlet>
: Specify ServletDemo1 as the Servlet name ServletDemo1, generally the same name as the corresponding class here

2,

<servlet-mapping></servlet-mapping>
: Set the specific access path

And these two in turn pass

<servlet-name></servlet-name>
Linked together

Implementation process:

1. When the server receives the request from the browser, it parses the URL path and obtains the resource path of the Servlet

2. Look for the web.xml file and find

<url-pattern>
Label, find the corresponding full class name
<servlet-class>

3. Tomcat loads the bytecode file into memory, creates an object, and calls its method

So we need to know: Most of the methods in Servlet are not created and called by us, they are all done by Tomcat

(3) Servlet interface ( )

(1) A brief overview of the life cycle

I simply understand the life cycle as these processes:

During his lifetime >Birth >Service >Death >Burial

1. Before death: When Tomcat accesses Servlet for the first time, Tomcat will create an instance of Servlet

2. Born: Tomcat will call

init()
Method to initialize this object

3. Service: When the client accesses the Servlet,

service()
Method will be called

4. Death: When Tomcat is shut down or Servlet is not used for a long time,

destroy()
Method will be called

5. Burial:

destroy()
After the method is called, the servlet waits for garbage collection (not easy), and uses it if necessary
init()
Method reinitialization

(2) Detailed life cycle

1. Before death

The server will create the servlet when the servlet is accessed for the first time , or when the server is started . If the Servlet is created when the server starts, it needs to be configured in the web.xml file, which means that by default, the Servlet is created by the server when it is accessed for the first time.

A Servlet type, the server only creates an instance object: for example, the first time we visit

<http://localhost:8080/Demo1>
, The server passed
/Demo1
Just found
cn.ideal.web.servlet.ServeltDemo1
, The server will determine whether this type of Servlet has been created, if not, it will create an instance of ServletDmoe1 through reflection, otherwise it will directly use the existing instance

2. Birth

After the servlet is created, the server will immediately call Servlet

void init(ServletConfig)
Method, and this method will only be called once during the lifetime of a Servlet. We can put some initialization work on the Servlet in
init()
In the method!

3. Service

Each time the server receives a request, it will call the service() method of the Servlet to process the request. The service() method will be called multiple times. When the server receives a request, it will call the service() method once. Because of this, we need to write the code to process the request into the service() method!

4. Death and burial

Servlet also needs to be destroyed when the server is closed, but before destruction, the server will call the Servlet

destroy()
Method, we can put some code to release resources here.

(3) 3.types of Servlet interface

In these five methods, we can see three types in the parameters that we have not touched

public void init (ServletConfig servletConfig) throws ServletException {} public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {} Copy code

That is, these three types:

ServletConfig
,
ServletRequest
,
ServletResponse

A: ServletConfig

ServletConfig
Is an object created by the server and then passed to the Servlet
init()
Method

We simply use the first one of the following methods

getServletName()
That's it, the latter method waits for us to learn to write
Context
And other knowledge to better understand

//Get the configuration name of the Servlet in the web.xml file, that is, the name specified by <servlet-name> String getServletName () //Used to get the ServletContext object ServletContext getServletContext () //Used to get the initialization parameters configured in web.xml, get the parameter value through the parameter name String getInitParameter (String name) //initialization parameters used to obtain all the names arranged in web.xml the Enumeration the getInitParameterNames () to copy the code

B: ServletRequest & ServletResponse

These two types appear in the Servlet

service()
In the method, they represent the request and response objects respectively, and the instances of both are also created by the server

But we want to make a web application. In the final analysis, it must be linked to HTTP. If we want to

service()
Using HTTP-related functions in the method, ServletRequest and ServletResponse can be forced to HttpServletRequest and HttpServletResponse

HttpServletRequest method:

//Get the value of the specified request parameter String getParameter (String paramName) //Get the request method, such as GET or POST String getMethod () //Get the value of the specified request header String getHeader (String name) //Set the code of the request body! /* GET has no request body, so this method is only valid for POST requests when called This method must be called before calling the getParameter() method! After using request.setCharacterEncoding("utf-8"), when the parameters are obtained through the getParameter() method, The parameter values have been transcoded, that is, converted into UTF-8 encoding */ Void setCharacterEncoding (String encoding) Copy the code

HttpServletResponse method:

//Get the character response stream, use this stream to output response information to the client PrintWriter getWriter () Eg: response. getWriter () . Print ("<h1>Just for test</h1>") ; //Get the byte response stream, for example, it can be realized to respond to a picture to the client ServletOutputStream getOutputStream () //Used to set the encoding of the character response stream void setCharacterEncoding (String encoding) //Add response header information to the client void setHeader (String name, String value) Eg: setHeader ("Refresh", " 3 ;url=http://www.xxx.com") means that it will be automatically refreshed after three seconds URL //This method is a convenient method of setHeader("content-type", "xxx"), which is a method used to add a response header named content-type /* The content-type response header is used to set the MIME type of the response data. For example, if you want to respond to a jpg image to the client, then You can setContentType("image/jepg"). If the response data is of text type, you must also set the editor Code, for example, setContentType("text/html;chartset=utf-8") indicates that the response data type is text type In the html type, and this method will call the setCharacterEncoding("utf-8") method; */ void setContentType (String contentType) //the client sends a status code, and an error message void the sendError ( int code, String errorMsg) copying the code

(4) GenericServlet class ( )

A: By looking at the source code of this class, we can know that there are only

public abstract void service (ServletRequest var1, ServletResponse var2) throws ServletException, IOException ; Copy code

One method needs to be implemented , and the other methods have been defined in the source code

B: GenericServlet

init()
method

The two methods that need to be mentioned are:

public void init (ServletConfig config) throws ServletException { this .config = config; this .init(); } public void init () throws ServletException { } Copy code

The GenericServlet class implements the Servlet

init(ServletConfig)
Method, put the parameters
config
Assigned to members of this class
config
, And then call this class's own parameterless
init()
method

This method is GenericServlet's own method, not inherited from Servlet. When we customize Servlet, if we want to complete the initialization function, don't repeat it

init(ServletConfig)
Method, but should be rewritten
init()
method. Because in GenericServlet
init(ServletConfig)
The ServletConfig object is saved in the method. If the code that saves the ServletConfig object is overwritten, the ServletConfig object can no longer be used

C: Implemented the ServletConfig interface

GenericServlet also implements the ServletConfig interface , so it can be called directly

getInitParameter()
,
getServletContext()
Waiting for the ServletConfig method

But this category is still not the focus of what we are going to talk about, let s move on to the next category

(5) HttpServlet class ( )

(1 Overview

In the above implementation of the Servlet interface, we need to implement 5 methods, which is very troublesome, and the HttpServlet class has implemented all the methods of the Servlet interface. When writing a Servlet, you only need to inherit the HttpServlet and rewrite the methods you need, and it provides The special support for HTTP requests is even more powerful!

(2) service() method

In HttpServlet

service(ServletRequest,ServletResponse)
The method will force ServletRequest and ServletResponse to HttpServletRequest and HttpServletResponse

//HttpServlet source code excerpt public void service (ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request; HttpServletResponse response; try { request = (HttpServletRequest)req; response = (HttpServletResponse)res; } catch (ClassCastException var6) { throw new ServletException( "non-HTTP request or response" ); } this .service(request, response); } Copy code

After the forced transfer, then call the provided in the HttpServlet class

service(HttpServletRequest,HttpServletResponse)
Method, this is the method of this class itself , not inherited, which means that when we use it, we only need to cover
service(HttpServletRequest,HttpServletResponse)
That s it, you don t need to force these two objects again~

Note: In fact, there are more simplified steps, and there is no need

service(HttpServletRequest,HttpServletResponse)

(3) doGet() and doPost()

In HttpServlet

service(HttpServletRequest,HttpServletResponse)
The method will determine whether the request is GET or POST. If it is a GET request, it will call the
doGet()
Method, if it is a POST request, call it
doPost()
Method, which means that we are going to override in the subclass
doGet()
or
doPost()
Method is fine

(6) Servlet details

(1) Thread safety issues

Servlet will only be created by the server as an instance object. In many cases, a Servlet needs to process multiple requests. Obviously, although Servlet is efficient, it is not thread-safe.

Therefore, we should not easily create member variables in the Servlet, because there may be multiple threads performing different operations on this member variable at the same time

Conclusion: Don't create members in Servlet! Create local variables, you can create stateless members, or members whose state is only readable

(2) Servlet is created when the server starts

As we said in the life cycle before, Servlet is created by the server when it is accessed for the first time, but we can configure the Servlet in web.xml so that the Servlet is created when the server starts!

<servlet> <servlet-name>ServletDemo1</servlet-name> <servlet- class > cn . ideal . web . ServletDemo1 </servlet - class > <!-- Configure < load - on - startup > in < servlet >, which gives a non-negative integer! --> < load - on - startup >0</load - on - startup > </servlet > copy code

Its role is to determine the order in which servlets are created when the server starts

(3) A Servlet can bind multiple URLs

< The servlet-Mapping > < the servlet-name > the Servlet </the servlet-name > < URL-pattern >/aServlet </URL-pattern > < URL-pattern >/BServlet </URL-pattern > </the servlet-Mapping > Copy Code

After this configuration, regardless of access

/AServlet
still is
/BServlet
, Who are visiting
AServlet

(4) Wildcard matching problem

in

<url-pattern>
You can use wildcards in, that is, "*" , which can match any prefix or suffix

<!--Path match--> <!--/servlet/a,/servlet/b, both match/servlet/* --> < url-pattern >/servlet/* < url-patter > <!--Extension match--> <!--/abc/de.xx,/a.xx, both match *.xx --> < url-pattern > *.xx </url-pattern > : <-! All match the URL of -> < url-pattern >/* < url-pattern > Copy the code

Wildcards are either prefixes or suffixes. They cannot appear in the middle of the URL. At most one wildcard can appear in a URL. If there is a more specific address, the specific address will be accessed first.

(7) ServletContext

(1 Overview

The server will create a ServletContext object for each web application, it can be said to represent the web site , and this object is created when Tomcat is started, and will be destroyed when Tomcat is shut down

(2) Function

All Servlets share a ServletContext object , so the role of the ServletContext object is to share data among the dynamic resources of the entire Web application, which means that different Servlets can communicate through ServletContext to share data

(3) Obtain the ServletContext object

The GenericServlet class has

getServletContext()
Method, so you can use it directly
this.getServletContext()
To get

public class MyServlet implements Servlet { public void init (ServletConfig config) { ServletContext context = config.getServletContext(); } } public class MyServlet extends HttpServlet { public void doGet (HttpServletRequest request, HttpServletResponse response) { ServletContext context = this .getServletContext(); } } Copy code

(4) Functions of domain objects

All domain objects have the function of accessing data. This way of storing data can be regarded as the way of ==> Map

Let's look at a few common methods for manipulating data

storage

//Used to store an object, can also be called storing a domain attribute void setAttribute (String name, Object value) EG:. Where servletContext the setAttribute ( "XXX", "XXX") //save the attribute in the ServletContext a domain, the domain attribute name XXX, XXX domain attribute is duplicated code

Obtain

//Used to get the data in ServletContext Object getAttribute (String name) //Get the domain attribute named xx Eg: String value = (String)servletContext.getAttribute("xxx"); //get the names of all domain attributes; Enumeration getAttributeNames () Copy the code

Remove

//used to remove the field properties ServletContext void removeAttribute (String name) copying the code

Small case of traffic statistics

package cn.ideal.web.servlet; import javax.servlet.*; import java.io.IOException; public class ServletDemo2 extends GenericServlet { @Override public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { //Get ServletContext object ServletContext servletContext = this .getServletContext (); //Get count attribute Integer count = ( Integer) servletContext.getAttribute( "count" ); if (count == null ) { //If the count attribute does not exist in the ServletContext, the name is set to the value of count 1, which means the first visit count = 1 ; } else { //If there is a count attribute in the Servlet, it means that it has been visited before, and the name increases the count by 1 on the original basis count++; } servletResponse.setContentType( "text/html;charset=UTF-8" ); //Respond to the client the number of times this page has been visited servletResponse.getWriter().print( "<h1>Total visits to this page" + count + " Times</h1>" ); //Save the value of count to the ServletContext object servletContext.setAttribute( "count" , count); } } Copy code

(8) Relevant methods for obtaining resources

(1) Obtaining path

Using the ServletContext object can be used to obtain resources under the Web application, for example, create aaa.txt file in the root directory of a web application, create bbb.txt file in the WEB-INF directory, if we want to obtain the two through Servlet The path can be written like this

//Get the path of aaa.txt String realPath = servletContext.getRealPath("/aaa.txt") //Get the path of bbb.txt String realPath = servletContext.getRealPath("/WEB-INF/b.txt") Copy code

This is how to get the path of a single file. We have another way to get all the resource paths in the specified directory, for example, get all the resource paths under/WEB-INF

Set set = context.getResourcePaths( "/WEB-INF" ); System.out.println(set); Copy code

(2) Obtain resource flow

Not only can we use ServletContext to get the path, we can also get the resource stream, taking the two files assumed above as an example

//Get aaa.txt InputStream in = servletContext.getResourceAsStream(/aaa.txt ); //Get bbb.txt InputStream in = servletContext.getResourceAsStream("/WEB-INF/b.txt"); Copy code

(3) Get resources under the classpath

InputStream in = this .getClass().getClassLoader().getResourceAsStream( "xxx.txt" ); System.out.println(IOUtils.toString(in)); Copy code

(9) Use annotations, no longer configure web.xml

Every time we create a Servlet, we need to configure it in web.xml, but if our Servlet version is above 3.0, we can choose not to create web.xml and use annotations to solve it, which is very simple and convenient

For example, we create a Servlet and configure web.xml as follows

< servlet > < servlet-name > ServletDemo2 </servlet-name > < servlet-class > cn.ideal.web.servlet.ServletDemo2 </servlet-class > </servlet > < servlet-mapping > < servlet-name > ServletDemo2 </servlet-name > < url-pattern >/Demo2 </url-pattern > </servlet-mapping > <!-- Write such a code above the class name, the external access path inside the quotation marks --> @WebServlet("/Demo2") Copy code

Is it very simple and convenient? Let's take a look at the principle:

//WebServlet source code excerpt @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface WebServlet { String name () default "" ; String[] value() default {}; String[] urlPatterns() default {}; int loadOnStartup () default -1 ; } Copy code

This annotation can be seen,

@Target({ElementType.TYPE})
The scope of action is the class,
@Retention(RetentionPolicy.RUNTIME)
Keep it in operation,
name()
The method is not so important here, because in web.xml, name mainly plays a related role, among which our most important is this
String[] urlPatterns() default {};
Configure an address, it is defined as an array, of course, it is also possible to configure one, namely
urlPatterns = "/Demo2"
And the most important value represented by value actually represents this address, so it can be written as
Value = "/Demo2"
, And Value can be omitted, so it can be written as
"/Demo2"
.

This article is reproduced! Original address: juejin.cn/post/684490...