Servlet Technology - Overview, Implementation, Details, Getting Resources, ServletConfig, ServletContext

(1) Basic overview of Setvlet s

(1) What is a Servlet?

Servlet (Server Applet) is short for Java Servlet, which is called small service program or service connector. Server-side program written in Java has platform-independent and protocol-independent characteristics. Its main function is to interactively browse and generate data and generate dynamic Web content.

In JavaWeb, we will come into contact with three components (Servlet, Filter, Listener), which are called by the server to process requests received by the server, i.e., complete, accept request data-->process request-->complete response, essentially 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 appropriate method

(2) What does the Servlet do?

Some of the more common functions in the network, such as login, registration, so there are interactive functions, and Servlets can help us handle these requests, so to speak, Servlets are one of the important knowledge points in JavaWeb knowledge.

(2) Ways to implement Servlet

There are three ways to implement a Servlet:

  • Implement the 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 Servlet, but understanding the Servlet interface is also important and an integral part of our getting started knowledge

(1) Create our first Servelt

We create a web project and select the appropriate parameters. We have a 1.8 version of jdk installed. You can choose the version of JavaEE 8 which corresponds to version 4.0, but here we choose which version 7 is available or more.

Create a Demo class to implement the Servlet interface, and then we quickly generate methods that are not implemented in this interface. For the moment, we ignore the other four methods in the Servlet and only care about the service() method, because it is the method used to process requests. Within this method, we give an output statement

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;
    }

    //Providing service methods
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Ideal more than two decades");
    }

    //Servlet Information Method
    @Override
    public String getServletInfo() {
        return null;
    }

    //destroy-method
    @Override
    public void destroy() {
    }
}

I've written the simplest Servlet code, but how can I access it in a browser?We need to configure web.xml under web/WEB-INF. We add the following code in <web-app></web-app> (although there are later optimization methods, it is recommended that you remember them)

<servlet>
        <!--Give this Servlet Give a name, usually the same as the class name-->
        <servlet-name>ServletDemo1</servlet-name>
        <!--Full class name-->
        <servlet-class>cn.ideal.web.servlet.ServeltDemo1</servlet-class>
    </servlet>

    <!--Configure Mapping Path-->
    <servlet-mapping>
        <servlet-name>ServletDemo1</servlet-name>
        <!--Outside Access Path-->
        <url-pattern>/Demo1</url-pattern>
    </servlet-mapping>

Now let's take a look at the path we configured in url-pattern and output it in the console, ideally more than this string in February

(2) The role of web.xml

While the iron is hot, let's briefly analyze the reason for this web.xml. In fact, the purpose of configuring a Servlet in web.xml is to bind the access path in the browser to the corresponding Servlet. The example above is to bind the access path: "/Demo1" to "cn.ideal.web.servlet.ServeltDemo1"

1. <servlet></servlet>: Specify ServletDemo1 This Servlet's name is ServletDemo1, which is usually the same name as the corresponding class here

2. <servlet-mapping></servlet=mapping>: Set the specific path to access

The two are related by <servlet-name></servlet-name>

Execution process:

1. When the server receives the request from the browser, parse the URL path and get the resource path to the Servlet

2. Find the web.xml file, find the <url-pattern>tag, and find the corresponding full class name <servlet-class>

3. Tomcat loads the byte code file into memory, creates an object, and calls the methods in it

So we need to know that most of the methods in Servlet s are not created and invoked by us and are done by Tomcat

(3) Servlet interface

(1) A brief overview of the life cycle

I simply think of life cycle as a few processes:

Prenatal - Birth - Service - Death - Burial

1. Before birth: When Tomcat first visits a Servlet, Tomcat creates an instance of the Servlet

2. Birth: Tomcat calls the init() method to initialize this object

3. Service: When a client accesses a Servlet, the service() method is called

4. Death: When Tomcat is closed or Servlet is not used for a long time, the destroy() method is called

5. Burial: After the destroy() method is called, the Servlet waits for garbage collection (not easy), and reinitializes with the init() method if necessary

(2) Detailed life cycle

1. Before birth

The server creates a Servlet the first time the Servlet is accessed, or when the server is started.If you create a Servlet at server startup, you also need to configure it in the web.xml file, which means that by default, a Servlet is created by the server on first access

A Servlet type where the server creates only one instance object: for example, when we first visit <http://localhost:8080/Demo1>, the server finds cn.ideal.web.servlet.ServeltDemo1 through/Demo1, the server will determine if a Servlet of this type has been created, and if it has not, it will create ServletDmoe1 through reflectionInstances, otherwise use existing instances directly

2. Birth

Once a Servlet is created, the server immediately calls the Servlet's void init(ServletConfig) method, and a Servlet's lifetime, this method will only be called once, so we can put some initialization of the Servlet into the method!

3. Services

Each time the server receives a request, it calls the service() method of the Servlet to process the request.The service() method is called many times, and once the server receives a request, the service() method is called once. That's why we need to write the code that handles the request into the service() method!

4. Death and burial

Servlets also need to be destroyed when the server shuts down, but before destroying, the server calls the destroy() method in the Servlet, where we can put some code to free resources

(3) Three types of Servlet interfaces

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 {}

This is the three types: ServletConfig, ServletRequest, ServletResponse

A: ServletConfig

ServletConfig is an object created by the server and passed to the Servlet's init() method

In the following ways, we can simply use the first getServletName(), while in the latter way we can better understand it until we have learned Context and other knowledge

//Gets the configuration name of the Servlet in the web.xml file, that is, <servlet-name>specified name
String getServletName()

//Used to get the ServletContext object
ServletContext getServletContext()

//Used to get the initialization parameters configured in web.xml and get the parameter values by the parameter name;
String getInitParameter(String name)

//Used to get all initialization parameter names configured in web.xml
Enumeration getInitParameterNames()

B: ServletRequest & ServletResponse

These two types appear in the service() method of the Servlet, representing request and response objects, and instances of both are created by the server

But we want to make a web application that is ultimately tied to HTTP. If we want to use HTTP-related functionality in the service() method, we can strongly convert ServletRequest and ServletResponse to HttpServletRequest and HttpServletResponse

HttpServletRequest method:

//Gets the value of the specified request parameter;
String getParameter(String paramName)

//Get the request method, such as GET or POST
String getMethod()
    
//Gets the value of the specified request header;
String getHeader(String name)

//Set the encoding of the request body!
/*
    GET There is no 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"), get the parameter through the getParameter() method
    When the parameter values are transcoded, they are converted to UTF-8 encoding.
*/
void setCharacterEncoding(String encoding)

HttpServletResponse method:

//Gets a character response stream that can be used to output response information to the client.
PrintWriter getWriter()
Eg: response.getWriter().print("<h1>Just for test</h1>");
    
//Get a byte response stream, for example, to respond to a picture to the client
ServletOutputStream getOutputStream()

//Encoding used to set character response stream
void setCharacterEncoding(String encoding)
   
//Add response header information to client
void setHeader(String name, String value)
Eg: setHeader("Refresh", "3;url=http://www.xxx.com"means automatically refresh to the web address in three seconds

//This method is an easy way to setHeader("content-type", "xxx"), which is a way to add a response header named content-type
/*
    content-type The response header sets the MIME type of the response data, such as a picture that responds to jpg to the client, then
    You can set ContentType ("image/jepg"), and if the response data is of type text, set the editing at the same time
    Codes, such as setContentType("text/html;chartset=utf-8"), indicate that the response data type is text type
    The html type in the and calls the setCharacterEncoding("utf-8") method;
*/
void setContentType(String contentType)
    
//Send status codes and error messages to clients
void sendError(int code, String errorMsg)

(4) GenericServlet class

A: By looking at the source code for this class, you know that only

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

One method needs to be implemented, and the others are already defined in the source code

The init() method of B:GenericServlet

Two ways to mention them are

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

public void init() throws ServletException {
}

The GenericServlet class implements the Servlet's init(ServletConfig) method, assigns the parameter config to the member config of the class, and then calls the class's own init() method with no parameters

This method is GenericServlet's own, not inherited from Servlet.When customizing a Servlet, instead of repeating the init(ServletConfig) method, you should override the init() method if you want to complete the initialization.Because the ServletConfig object is saved in the init(ServletConfig) method in the GenericServlet, if you overwrite the code that saves ServletConfig, you can no longer use ServletConfig.

C: Implement ServletConfig interface

GenericServlet also implements the ServletConfig interface, so you can call ServletConfig methods such as getInitParameter(), getServletContext() directly.

But this class is still not the focus of our discussion. Let's move on to the next class.

(5) HttpServlet class

(1) Overview

Above we implement the Servlet interface, which requires five methods, which is very cumbersome. The HttpServlet class already implements all the methods of the Servlet interface. When writing a Servlet, you only need to inherit the HttpServlet, override the method you need, and it provides special support for HTTP requests and is more powerful

(2) service() method

ServletRequest and ServletResponse are strongly converted into HttpServletRequest and HttpServletResponse in the service(ServletRequest,ServletResponse) method of HttpServlet

//Source excerpt for HttpServlet
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);
    }

After a strong switch, the service(HttpServletRequest,HttpServletResponse) method provided in the HttpServlet class is called, which is the method of the class itself, not inherited, indicating that when we use it, we just need to override the service(HttpServletRequest,HttpServletResponse) and no longer need toForcing these two objects

Note: There are actually more steps to simplify, and you don't need to use service(HttpServletRequest,HttpServletResponse)

(3) doGet() and doPost()

The service(HttpServletRequest,HttpServletResponse) method of the HttpServlet will determine whether the request is GET or POST, call the doGet() method in the class if it is a GET request, or call the doPost() method if it is a POST request, which means we can override the doGet() or doPost() method in the subclass.

(6) Servlet details

(1) Thread security issues

Servlets are only created by the server as an instance object. In many cases, a single Servlet needs to handle multiple requests. Obviously, a Servlet is efficient, but not thread-safe.

So we shouldn't easily create a member variable in a Servlet because there may be multiple threads working on it differently at the same time

Conclusion: Do not create members in Servlet!Create a local variable, you can create a stateless number of members, or the state is only a readable member

(2) Servlet is created at server startup

As we said earlier in our life cycle, Servlet s are created by the server on first access, but we can configure them in web.xml so that they are created at server startup

<servlet>
    <servlet-name>ServletDemo1</servlet-name>
    <servlet-class>cn.ideal.web.ServletDemo1</servlet-class>
     <!--stay<servlet>Configuration in<load-on-startup>,It gives a non-negative integer!-->
    <load-on-startup>0</load-on-startup>
</servlet>

Its purpose is to determine the order in which Servlet s are created at server startup

(3) A Servlet can bind multiple URL s

<servlet-mapping>
    <servlet-name>Servlet</servlet-name>
    <url-pattern>/AServlet</url-pattern>
    <url-pattern>/BServlet</url-pattern>
</servlet-mapping>  

After configuration, whether you access/AServlet or/BServlet, all you access is AServlet

(4) Wildcard matching problem

A wildcard, or'*', can be used in <url-pattern>, which matches any prefix or suffix

<!--Path Matching-->
<url-pattern>/servlet/*<url-patter>:/servlet/a, /servlet/b, all match/servlet/*;

<!--Extension Matching-->
<url-pattern>*.xx</url-pattern>:/abc/de.xx, /a.xx, all match*.xx;

<!--Everything matches-->
<URL-pattern>/*<URL-pattern>: Match all URLs;

Wildcards are either prefixes or suffixes and cannot appear in the middle of a URL, and 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 creates a ServletContext object for each web application, which you can say represents the web site, and this object is created when Tomcat starts and destroyed when Tomcat closes

(2) Functions

All Servlets share a ServletContext object, so the ServletContext object is used to share data between dynamic resources throughout the Web application, that is, different Servlets can communicate through the ServletContext to share data

(3) Get the ServletContext object

The GenericServlet class has a getServletContext() method, so it can be obtained directly using this.getServletContext()

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();
    }
}

(4) Functions of domain objects

All domain objects have access to data, and you can think of this as a way to store data, a way to Map

Let's look at a few common ways to manipulate data

storage

//Used to store an object, also known as storing a domain property
void setAttribute(String name, Object value)
    
Eg: servletContext.setAttribute("xxx", "XXX")
//A domain property is saved in the ServletContext with the name XXX and the value XXX

Obtain

//Used to get data in ServletContext
Object getAttribute(String name)
//Gets the field property named xx
Eg: String value = (String)servletContext.getAttribute("xxx");


//Gets the names of all domain properties;
Enumeration getAttributeNames()

remove

//Used to remove domain properties from ServletContext
void removeAttribute(String name)

Small Case of Visit 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 the ServletContext object
        ServletContext servletContext = this.getServletContext();
        //Gets the count property in the ServletContext object
        Integer count = (Integer) servletContext.getAttribute("count");
        if (count == null) {
            //If the count property does not exist in the ServletContext, the value of name set to count is 1, indicating the first visit
            count = 1;
        } else {
            //If the count attribute exists in the Servlet, indicating that it has been accessed before, name lets count add 1 to the original
            count++;
        }
        servletResponse.setContentType("text/html;charset=UTF-8");
        //Number of times this page has been visited in response to clients
        servletResponse.getWriter().print("<h1>Visit this page altogether" + count + "second</h1>");
        //Save the value of count to the ServletContext object
        servletContext.setAttribute("count", count);
    }
}

(8) Approaches to obtaining resources

(1) Get Path

Using the ServletContext object can be used to get resources under a Web application, such as creating an aaa.txt file in the root directory of a Web application, and a bbb.txt file in the WEB-INF directory, which we can write if we want to get the paths to both through a Servlet

//Get the path to aaa.txt
String realPath = servletContext.getRealPath("/aaa.txt")

//Get the path to bbb.txt
String realPath = servletContext.getRealPath("/WEB-INF/b.txt")

Getting a single file path is like this, but there is also a way to get all the resource paths in the specified directory, such as Get/WEB-INF

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

(2) Obtaining resource flows

Not only can we use the ServletContext to get the path, but we can also get the resource flow, using the two files assumed above as examples

//Get aaa.txt
InputStream in = servletContext.getResourceAsStream("/aaa.txt");

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

(3) Obtaining resources under the class path

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

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

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

For example, let's 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 a code above the class name with an external access path in quotation marks
@WebServlet("/Demo2")

Whether it's easy or not, let's see how it works:

//WebServlet Source Selection
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
    String name() default "";

    String[] value() default {};

    String[] urlPatterns() default {};

    int loadOnStartup() default -1;

As you can see from this comment, @Target({ElementType.TYPE}) scopes on classes, @Retention(RetentionPolicy.RUNTIME) remains at runtime, and the name() method is less important here because in web.xml, name plays a major role in association, and the most important of which is this String[] urlPatterns ()Default {}; configure an address, which is defined as an array, and of course configure one, which is also possible, that is, urlPatterns ='/Demo2', and the most important value represented by value, which actually represents this address, so it can be written as Value ='/Demo2', and Value can be omitted, so it can be written as'/Demo2'

Ending:

If there are any inadequacies or errors in the content, you are welcome to leave a message for me, Crab and Crab!^^

If you can help, pay attention to me!(The series will be updated at the first time on Public Number)

We don't know each other here, but we are working hard for our dreams.

A public slogan insisting on the original Java technology: more than 20 years

Tags: Java xml Tomcat encoding

Posted on Sat, 24 Aug 2019 20:20:43 -0700 by tc48