Introduction to Servlet foundation of JavaWeb detailed explanation (Part I)

Posted by steelerman99 on Sun, 24 Oct 2021 05:02:37 +0200

Introduction to Servlet foundation of JavaWeb detailed explanation (Part I)

1. Overview of Serlvet

     Servlet is a java program running on the web server or application server. It is an intermediate layer responsible for connecting applications from web browsers or other HTTP clients and HTTP servers. It is a technology provided by sun company for developing dynamic web resources.

The Servlet performs the following tasks:

    1) Read the display data sent by the customer. For example: html form data

    2) Read implicit request data sent by the browser. For example: http request header

    3) Generate results.

    4) Send display data (i.e. documents) to the client. The most important task of servlet s and JSPS is to wrap the results in files in text (html), binary (picture) and other formats.

    5) Send implicit HTTP response data. For example: HTTP response header

    If we want to request a dynamic web resource with a browser, we need to complete the following two steps: a) write a Java class to implement the servlet interface. b) Deploy the developed Java classes to the web server.

    Servlet is a servlet interface (actually a java program) provided by Sun company in its API, but the Java program should follow the servlet development specification. It can help us process the HTTP request sent by the browser and return a response to the browser.

2. Getting started with servlet development

     Write the first servlet program.

2.1. The first servlet program

2.1.1 step 1

     Create a new web project, a new program named FirstServletDemo, and implement the Servlet interface, which will require us to implement its abstract methods. init, destroy, service, ServletConfig, getServletInfo

import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FirstServletDemo implements Servlet{

	@Override
	public void destroy() {
		System.out.println("I am destroy,I did");
	}
    
	@Override
	public ServletConfig getServletConfig() {
		return null;
	}

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		System.out.println("I am init,I did");
	}

	@Override
	public void service(ServletRequest req, ServletResponse rsp) throws ServletException, IOException {
		System.out.println("I am service,I did");
		OutputStream out = rsp.getOutputStream();
	    out.write("Hello Servlet!".getBytes());
	}

}

2.2 step 2

     Configure tomcat's web.xml and add the following information to it.

<!--servlet In the label:
    servlet-name to configure servlet Your name, servlet-class to configure servlet Corresponding java class
-->
<servlet>
    <servlet-name>FirstServletDemo</servlet-name>
    <servlet-class>com.cn.test.FirstServletDemo</servlet-class>
</servlet>
<!--servlet-mapping In the label:
    servlet-name to configure servlet Your name, url-pattern Configure access url
    "/": The default representation at the beginning is: http://localhost:8080/
-->
<servlet-mapping>
    <servlet-name>FirstServletDemo</servlet-name>
    <url-pattern>/FirstServletDemo</url-pattern>
</servlet-mapping>

    Start the tomcat service and enter in the browser: http://localhost:8080/FirstServletDemo

The display page is as follows:

 

2.2. servlet life cycle

    Many programs have an event flow that executes itself, and so do servlets. The Servlet runs in the Servlet container, and the container manages the whole process from creation to destruction.  

2.2.1 overview of servlet life cycle

    The Servlet life cycle can be roughly divided into:

    1) Load and instantiate

    If the Servlet container has not instantiated a Servlet object, the container loads and instantiates a Servlet. Create an instance of the Servlet class. If a Servlet object already exists, no new instance will be created at this time.

    2) Initialize init()

    When the Servlet is instantiated, Tomcat will call the init() method to initialize the object.

    3) Process request (service)

    When the Servlet container receives a Servlet request, it runs the service() method of the corresponding Servlet instance to process the user request and the response to the customer.

    4) destroy()

    When the Servlet container decides to remove a Servlet from the server (for example, the Servlet file is updated, and a Servlet will be automatically destroyed by the Servlet container if it is not used for a long time), it calls the destroy() method of the Servlet instance.

2.2.2 special notes on servlet life cycle

    There are two types of initialization performed by the init() method: regular initialization and parameterized initialization.

    1) General initialization

    When < load on startup > < / load on startup > is not configured in web.xml, init() is initialized only once, and the init() method is executed only when accessing the corresponding Servlet.

    2) Parameterized initialization

    Of course, there are more servlets. If you want to have a loading order, the programmer can use the code to realize when to initialize and the initialization order. However, if you suddenly want to adjust, the developer needs to modify the code. For convenience, it provides an initialization order that can be realized through parametric configuration, that is, parametric initialization.

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FirstServletDemo implements Servlet{

	int num = 0;
	@Override
	public void destroy() {
		System.out.println("I am destroy,I did");
	}

	@Override
	public ServletConfig getServletConfig() {
		return null;
	}

	@Override
	public String getServletInfo() {
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		System.out.println("I am init,I did");
		num = (int) (Math.random()*100);
	}

	@Override
	public void service(ServletRequest req, ServletResponse rsp) throws ServletException, IOException {
		System.out.println("I am service,I did");
		PrintWriter out = rsp.getWriter();
		out.println(num);
	}

}

Modify web.xml

<servlet>
    <servlet-name>FirstServletDemo</servlet-name>
    <servlet-class>com.cn.test.FirstServletDemo</servlet-class>
    <!--Less than 0: indicates that the initialization method is not executed
        Greater than or equal to 0: when the server starts, it will be created in the order of configuration Servlet Class, and priority 0 is the highest.
    -->
    <load-on-startup>2</load-on-startup>
</servlet>

Case effect:

      Each time it starts, it is initialized. When you visit again, the page directly displays 71.

Configure the function of parameterized initialization:

1) Write an init servlet for the web application, which is configured to load at startup, and create necessary database tables and data for the whole web application.

2) Complete some scheduled tasks [log writing and data backup regularly]

3. Three development methods of serlvet

    There are three ways to implement Servlet interface:

    1) Implement Servlet interface; 2) By inheriting GenericServlet; 3) By inheriting HttpServlet.

    We already know how to use the Servlet interface. SUN has defined two default implementation classes for the Servlet interface: GenericServlet and HttpServlet.

3.1. Inherit GenericServlet

     GenericServlet is an abstract class that implements the Servlet interface. We just need to override the service method.

Source code:

public abstract class GenericServlet implements Servlet, ServletConfig, Serializable{
    public abstract void service(ServletRequest req, ServletResponse res)
	throws ServletException, IOException;
    ......
 }

Use case:

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class GenericServletDemo extends GenericServlet{

	@Override
	public void service(ServletRequest req, ServletResponse rsp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter out = rsp.getWriter();
		out.println("GenericServletDemo!");
	}
}

3.2. Inherit HttpServlet

    When implementing the Servlet interface, HttpServlet overwrites the service method. The code in the method will automatically determine the user's request method. If it is a GET request, call the doGet method of HttpServlet; if it is a Post request, call the doPost method. Therefore, when writing servlets, developers usually only need to override doGet or doPost methods, not service methods.

Source code:

public abstract class javax.servlet.http.HttpServlet extends javax.servlet.GenericServlet{
    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String method = req.getMethod();
        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < lastModified) {
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }
        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);
        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp); 
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);   
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);   
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp); 
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);   
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }
    ......
}

Use case:

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HttpServletDemo extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		PrintWriter out = resp.getWriter();
		out.println("HttpServletDemo!");
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		super.doPost(req, resp);
	}

}

Extension: Servlet call process analysis

    

4. Servlet development details

4.1. Servlet s can be mapped multiple times

     Since the client accesses the resources in the web server through the URL address, if the servlet program wants to be accessed by the outside world, it must map the servlet program to a URL address. This work is completed by using the < servlet > element and < servlet mapping > element in the web.xml file.

The web.xml configuration is as follows:     

<servlet>
    <servlet-name>HttpServletDemo</servlet-name>
    <servlet-class>com.cn.test.HttpServletDemo</servlet-class>
</servlet>
<!-- Multiple url Map the same servlet -->
<servlet-mapping>
    <servlet-name>HttpServletDemo</servlet-name>
    <url-pattern>/HttpServletDemo</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>HttpServletDemo</servlet-name>
    <url-pattern>/HttpServletDemo/Demo2</url-pattern>
</servlet-mapping>

Case effect: the two effects are the same

 

4.2. Use wildcards

     The * wildcard can also be used in the URL to which the Servlet is mapped, but there can only be two fixed formats: one format is "*. Extension", and the other format starts with a forward slash (/) and ends with "/ *".

4.2.1, / * end

4.2.2,  *. Extension

Case study:

    If I had:

Servlet1 mapped to / abc/*

Servlet2 maps to/*

Servlet3 mapped to / abc

Servlet4 maps to *. do

Question 1: when the request URL is "/ abc/a.html", and both "/ abc / *" and "/ *" match, which servlet will respond to the request?

Answer 1: the Servlet engine will call Servlet1

Question 2: when the request URL is "/ abc/a.do", both "/ abc / *" and "*. Do" match. Which servlet will respond to the request?

Answer 2: the Servlet engine will call Servlet1

Note: when matching, the standards to be referred to are: 1) Whoever has a high degree of matching will be selected; 2) *. do has the lowest priority.

5. Thread safety of Servlet

    Because a Servlet is a single instance, when multiple clients access the same Servlet concurrently, the web server will create a thread for each client's access request and call the Servlet's service method in this thread. Therefore, if the same resource is accessed in the service method, thread safety problems may be caused.

Case: create a servlet of ServletDemo1

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletDemo1 extends HttpServlet{
	int i = 0;
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  response.setContentType("text/html;charset=gbk");
	      PrintWriter out = response.getWriter();
	      out.println("<form action='/ServletDemo1' method='post' >");
	      out.println("<input type='submit' value='Point me' /><br />");
	      out.println("</form><br />");
	      out.println("I was ordered:"+i+"second");
	      out.flush();
	      out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		i++;
		doGet(request, response);
	}
}

web.xml configuration:

<servlet>
    <servlet-name>ServletDemo1</servlet-name>
    <servlet-class>com.cn.test.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ServletDemo1</servlet-name>
    <url-pattern>/ServletDemo1</url-pattern>
</servlet-mapping>

Case effect:

    We found that in different client operations, the value of shared variable i is also shared. Click once on the right and twice on the left. Before the right reflects, the variable i has actually changed, so it also appears three times on the left. In fact, it is only clicked once.  

Scheme 2: using the SingleThreadModel interface, the Servlet engine will call its service method in single thread mode

public class ServletDemo1 extends HttpServlet implements SingleThreadModel{
	int i = 0;
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  response.setContentType("text/html;charset=gbk");
	      PrintWriter out = response.getWriter();
	      out.println("<form action='/ServletDemo1' method='post' >");
	      out.println("<input type='submit' value='Point me' /><br />");
	      out.println("</form><br />");
	      out.println("I was ordered:"+i+"second");
	      out.flush();
	      out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  i++;
		  try {
			  //In order to highlight the amount of concurrency, a delay is set here. When the amount is large, it reflects the slow time
			  Thread.sleep(5000);
		  } catch (InterruptedException e) {
			  e.printStackTrace();
		  }
		  doGet(request, response);
	}
}

Case effect:

      SingleThreadModel solves the problem of multithreading concurrency in another way (single thread mode call), and in the real sense, solving the problem of multithreading safety refers to the problem that a Servlet instance object is called by multiple threads at the same time. In fact, SingleThreadModel has been marked as Deprecated in Servlet API 2.4.

    What really avoids thread safety problems: you can write variables in methods. If local variables are thread private, there is no thread safety problem.

6. Detailed explanation of ServletConfig and ServletContext

6.1. ServletConfig details

    Servlet provides us with a ServletConfig object, which is mainly used to read the configuration information of the servlet. Allows us to write configuration information in web.xml.

    When creating a servlet instance object, the web container (Tomcat) will automatically encapsulate these initialization parameters into the ServletConfig object, and pass the ServletConfig object to the servlet when calling the init method of the servlet.

Return typeMethod & Description
java.lang.StringgetInitParameter(java.lang.String name) returns a String containing the value of the specified initialization parameter, or null if the parameter does not exist.
java.util.EnumerationgetInitParameterNames() returns the initialization parameter of the servlet name as an Enumeration String object or an empty Enumeration if the servlet has no initialization parameter.
ServletContextgetServletContext() returns a reference of the executing ServletContext
java.lang.StringgetServletName() returns the name of this servlet instance

Three functions of ServletConfig class:

1) You can obtain the value of the alias Servlet name of the Servlet program; 2) Get the initialization parameter init param; 3) Gets the ServletContext object.

Use case:

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletConfigDemo extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req,resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html");
		//The ServletConfig object is the entire Servlet
	    String charset = this.getServletConfig().getInitParameter("charset");
	    String sname = this.getServletConfig().getServletName();
	    resp.getWriter().println(charset);//Output: GBK
	    resp.getWriter().println(sname);//Output: ServletConfigDemo
	}

	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		//It can be used to connect to the database at startup and initialization
		System.out.println(config.getInitParameter("username")); //Console output: root
		System.out.println(config.getInitParameter("url")); //Console output: jdbc:mysql://localhost:3306/test
	}

}

  web.xml configuration

<servlet>
    <servlet-name>ServletConfigDemo</servlet-name>
    <servlet-class>com.cn.test.ServletConfigDemo</servlet-class>
    <!-- Initialization parameters -->
    <init-param>
        <param-name>charset</param-name>
        <param-value>GBK</param-value>
    </init-param>
    <init-param>
        <param-name>username</param-name>
        <param-value>root</param-value>
    </init-param>
    <init-param>
        <param-name>url</param-name>
        <param-value>jdbc:mysql://localhost:3306/test</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>ServletConfigDemo</servlet-name>
    <url-pattern>/ServletConfigDemo</url-pattern>
</servlet-mapping>

6.2. Detailed explanation of ServletContext

    The reference of the ServletContext object returned in ServletConfig. What is this object for? ServletConfig is the corresponding single servlet, and the ServletContext object represents the current web application. It will create a corresponding ServletContext object for each web application.

    The ServletContext object is contained in the ServletConfig object. You can obtain a reference to the ServletContext object through the ServletConfig.getServletContext method. Servlet objects can communicate with each other through the ServletContext object. ServletContext objects are also commonly referred to as context domain objects (data can be accessed like maps: setAttribute, getAttribute, removeAttribute).

    servletContext is automatically created when the web application is started. When the web application is closed / tomcat is closed / reload the web application, the servletContext will be destroyed.

    The main functions of ServletContext:

    1) Obtain the context parameter context param configured in web.xml; (getInitParameter(name))

    2) Get the current project path, format: / Project path;

    3) Obtain the absolute path of the project deployed on the server;

    4) Access data like a Map.

    5) Read the resource file.

6.2.1. Read configuration file and obtain path

Use case 1:

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletContextDemo extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req,resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html;charset=gbk");
		//The ServletConfig object is the entire Servlet
		ServletContext sc = this.getServletConfig().getServletContext();
	    String username = (String) sc.getInitParameter("username");
	    PrintWriter out = resp.getWriter();
	    out.println("Get context configuration for getInitParameter(username): "+username);//Output: context
	    //If the path is not configured in the Context in: server.xml, the getContextPath() obtained here is ""
	    out.println("<br/>Current project path getContextPath(): "+sc.getContextPath());//
	    out.println("<br/>Current project deployment path getRealPath(): "+sc.getRealPath("/"));//
	    //Set context configuration
	    sc.setAttribute("password", "test");
	}
}

web.xml configuration:

<context-param>
    <description>I am the configuration of the whole project</description>
    <param-name>username</param-name>
    <param-value>context</param-value>
</context-param>

<servlet>
    <servlet-name>ServletContextDemo</servlet-name>
    <servlet-class>com.cn.test.ServletContextDemo</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ServletContextDemo</servlet-name>
    <url-pattern>/ServletContextDemo</url-pattern>
</servlet-mapping>

Case effect:

6.2.2 data access  

Use case 2: modify ServletConfigDemo

import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletConfigDemo extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req,resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		ServletContext sc = this.getServletConfig().getServletContext();
	    String password = (String) sc.getAttribute("password");
	    resp.getWriter().println(password);//
	}

}

Case effect: the value set in ServletContextDemo can be obtained

6.2.3. Read resource file

Use case 3: reading resource files

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletContextDemo2 extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req,resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	    //Read the file first
		resp.setContentType("text/html;charset=gbk");
		PrintWriter out = resp.getWriter();
		//Put the file in the WEB-INF directory
	    InputStream in=this.getServletContext().getResourceAsStream("/WEB-INF/info.properties");
	    //Put the file in the src directory
//        ClassLoader classLoader = ServletContextDemo2.class.getClassLoader();
//        InputStream in =  classLoader.getResourceAsStream("info.properties");
	    Properties pro=new Properties();
	    pro.load(in);
	    out.println("username="+pro.getProperty("username")+"<br />");
	    out.println("password="+pro.getProperty("password")+"<br />");
	    out.flush();
	    out.close();
	}
}

info.properties

username=root
password=123456

7. Detailed explanation of HttpServletRequest and HttpServletResponse

    We saw earlier that the service (doGet or doPost) method in HttpServlet receives two parameters: service(HttpServletRequest req, HttpServletResponse resp). These two objects are described below.

7.1,HttpServletRequest

    The HttpServletRequest object represents the client's Request. When the client accesses the Tomcat server through the HTTP protocol, the server encapsulates all the information in the HTTP Request header in the Request object, and then passes it to the service method (doGet or doPost) for us to use. Through the method of this object, developers can obtain this information from customers.

Common API s:

Return typemethoddescribe
java.lang.StringgetMethod()Returns the HTTP method used for this request (for example: GET, POST, PUT)
HttpSessiongetSession() getSession(boolean create)Get the session object requested by the current client. If it does not exist, create it.
java.lang.StringgetParameter(String name)Get the data submitted by the client
java.lang.String[]getParameterValues(String name)Get all parameters
java.util.MapgetParameterMap()Get the map collection containing data passed to the client
java.lang.ObjectgetAttribute(String name)Get the key value pair passed from the previous page
voidsetAttribute(String name, Object o)Set the key value pair in the request and pass it to the next Servlet or page
voidsetCharacterEncoding(String env)Set the requested character set
RequestDispatchergetRequestDispatcher(String path)After processing the user's request: the request jumps to xxx page (request forwarding)
java.lang.StringBuffergetRequestURL()Returns the full URL when the client made the request
java.lang.StringgetQueryString()Returns the parameter part of the request line
java.lang.StringgetHeader(String name)Get request header parameters

Use case:

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ReqServletDemo extends HttpServlet{
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  response.setContentType("text/html;charset=gbk");
	      PrintWriter out = response.getWriter();
	      out.println("<form action='/ReqServletDemo' method='post' >");
	      out.print("<input type='txt' name='username' /><br /><br />");
	      out.print("<input type='checkbox' name='hobby' value='java'/>java<br />");
	      out.print("<input type='checkbox' name='hobby' value='python'/>python<br />");
	      out.print("<input type='checkbox' name='hobby' value='html'/>html<br />");
	      out.println("<input type='submit' value='Submit' /><br />");
	      out.println("</form><br />");
	      out.flush();
	      out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//Set the request response character code. The default is ISO-8859-1. If it is not set, there will be garbled code
		request.setCharacterEncoding("GBK");
		//response.setCharacterEncoding("GBK");
        //The following is recommended
        response.setHeader("Content-Type","text/html;charset=GBK");
        
		//Echo request data
		PrintWriter out = response.getWriter();
		out.println("url:"+request.getRequestURL().toString());//
		out.println("User-Agent:"+request.getHeader("User-Agent"));//
		out.println("Get request parameters username:"+request.getParameter("username"));//
		out.println("Get request parameters hobby:"+Arrays.asList(request.getParameterValues("hobby")));//
	}

}

Case effect:

7.1.1. RequestDispatcher request forwarding

    The HttpServletRequest object returns the RequestDispatcher object, which is called request forwarding: after the server receives the request, it jumps from one resource to another.

    First, we a picture under the WEB-INF directory, and then enter it in the browser: http://localhost:8080/WEB-INF/logo.jpg , go to visit, and the following page will appear. The default browser cannot directly access the WEB-INF directory.

Use case:

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ReqServletDemo extends HttpServlet{
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  response.setContentType("text/html;charset=gbk");
	      PrintWriter out = response.getWriter();
	      out.println("<form action='/ReqServletDemo' method='post' >");
	      out.print("<input type='txt' name='username' /><br /><br />");
	      out.print("<input type='checkbox' name='hobby' value='java'/>java<br />");
	      out.print("<input type='checkbox' name='hobby' value='python'/>python<br />");
	      out.print("<input type='checkbox' name='hobby' value='html'/>html<br />");
	      out.println("<input type='submit' value='Submit' /><br />");
	      out.println("</form><br />");
	      out.flush();
	      out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//Request forwarding
		RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/logo.jpg");
		//Advance to the forwarding Directory: the normal browser cannot access the resources in the WEB-INF directory, but the request for forwarding can
		rd.forward(request, response);
	}

}

  Case effect:

Characteristics of request forwarding:

    1) The browser address bar has not changed, they are a request;

    2) Share the data in the Request field;

    3) It can be forwarded to resources under the WEB-INF directory, but resources other than the project cannot be accessed.

Use case 2: application of refresh

    We often see a website post where to jump. If you don't jump after 5 seconds, please click the link.

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RspServletDemo extends HttpServlet{
	
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  response.setContentType("text/html;charset=gbk");
	      PrintWriter out = response.getWriter();
	      out.println("<form action='/first' method='post' >");
	      out.println("<input type='submit' value='Jump' /><br />");
	      out.println("</form><br />");
	      out.flush();
	      out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setHeader("refresh", "3;url='https://www.baidu.com/'");
		//Page Jump
		request.getRequestDispatcher("first.jsp").forward(request, response);
	}
}

web.xml

<servlet-mapping>
    <servlet-name>RspServletDemo</servlet-name>
    <url-pattern>/RspServletDemo</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>RspServletDemo</servlet-name>
    <url-pattern>/first</url-pattern>
</servlet-mapping>

first.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>RequestDispatcher</title>
  </head>
  <body>
      3 Jump to Baidu in seconds
      <a href="https://Www.baidu.com / "> if you don't jump, please click</a>
  </body>
</html>

  Case effect:

    Although external resources cannot be accessed, we can set the response header response.setHeader("refresh", "3;url =) Baidu once, you know '"); to make the browser jump to the specified url.  

7.2,HttpServletResponse

    HttpServletResponse object is the response of the server. This object encapsulates the method of sending data, response header and response status code to the client.

Common API s:

Return typemethoddescribe
voidsetCharacterEncoding(String charset)Set the encoding method of response client information encoding
ServletOutputStreamgetOutputStream()Returns a servlet OutputStream suitable for writing binary data in the response
java.io.PrintWritergetWriter()Returns a PrintWriter object that can send character text to the client
voidsetHeader(String name, jString value)Set a response header and the given name and value
voidsetStatus(int sc)Set status code ring
voidsendRedirect(String location)Send a temporary redirection response to the location where the client redirects using the specified URL

7.2.1 differences between getOutputStream and getWriter

    Character stream: getWriter() is used to return character data to the client

    Byte stream: getOutputStream() returns byte data (binary data, commonly used for downloading). Of course, it can also return characters, but there is no PrintWriter object, which is efficient.

    OutputStream os=response.getOutputStream();

    os.write("hello,world".getBytes());

Note: only one of two streams can be used at the same time, and the Web server will automatically check and close the stream.

Use case:

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RspServletDemo2 extends HttpServlet{

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  response.setContentType("text/html;charset=gbk");
	      PrintWriter out = response.getWriter();
	      out.println("<form action='/first' method='post' >");
	      out.println("<input type='submit' value='Jump' /><br />");
	      out.println("</form><br />");
	      OutputStream out2 = response.getOutputStream();
	      out2.write("hello,world".getBytes());
	}
}

  Case effect:

7.2.2 use of sendRedirect redirection

    Request redirection means that after a web resource receives a client request, it notifies the client to access another web resource, which is called request redirection.

Implementation method 1: set Location (not recommended)

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class sendRedirectDemo1 extends HttpServlet{

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  response.setContentType("text/html;charset=gbk");
	      PrintWriter out = response.getWriter();
	      out.println("<form action='/sendRedirectDemo1' method='post' >");
	      out.println("<input type='submit' value='set up Location' /><br />");
	      out.println("</form><br />");
	      out.flush();
	      out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setStatus(302);
		response.setHeader("Location", "http://localhost:8080/");
	}
}

Case effect:

 

  Implementation mode 2: request redirection, with the same effect

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class sendRedirectDemo2 extends HttpServlet{

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		  response.setContentType("text/html;charset=gbk");
	      PrintWriter out = response.getWriter();
	      out.println("<form action='/sendRedirectDemo2' method='post' >");
	      out.println("<input type='submit' value='set up Location' /><br />");
	      out.println("</form><br />");
	      out.flush();
	      out.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.sendRedirect("http://localhost:8080/");
	}
}

Characteristics of request redirection:

    1) The browser address will send changes;

    2) Two requests without sharing the data in the Request field;

    3) Resources under WEB-INF cannot be accessed, but resources outside the project can be accessed.

Summary: the difference between sendredirect and forward

  • The RequestDispatcher.forward method can only forward requests to components in the same WEB application; the HttpServletResponse.sendRedirect method can also redirect to resources in other applications on the same site, or even redirect to resources in other sites using absolute URL s.

  • After calling HttpServletResponse.sendRedirect method to redirect the access process, the URL displayed in the browser address bar will change from the initial URL address to the redirect target URL; after calling RequestDispatcher.forward method to forward the request, the browser address bar will keep the initial URL address unchanged.

  • The caller and callee of RequestDispatcher.forward method share the same request object and response object, which belong to the same access request and response process; while the caller and callee of HttpServletResponse.sendRedirect method use their own request object and response object, which belong to two independent access request and response processes.

Topics: Java servlet server