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 type | Method & Description |
---|---|
java.lang.String | getInitParameter(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.Enumeration | getInitParameterNames() returns the initialization parameter of the servlet name as an Enumeration String object or an empty Enumeration if the servlet has no initialization parameter. |
ServletContext | getServletContext() returns a reference of the executing ServletContext |
java.lang.String | getServletName() 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 type | method | describe |
---|---|---|
java.lang.String | getMethod() | Returns the HTTP method used for this request (for example: GET, POST, PUT) |
HttpSession | getSession() getSession(boolean create) | Get the session object requested by the current client. If it does not exist, create it. |
java.lang.String | getParameter(String name) | Get the data submitted by the client |
java.lang.String[] | getParameterValues(String name) | Get all parameters |
java.util.Map | getParameterMap() | Get the map collection containing data passed to the client |
java.lang.Object | getAttribute(String name) | Get the key value pair passed from the previous page |
void | setAttribute(String name, Object o) | Set the key value pair in the request and pass it to the next Servlet or page |
void | setCharacterEncoding(String env) | Set the requested character set |
RequestDispatcher | getRequestDispatcher(String path) | After processing the user's request: the request jumps to xxx page (request forwarding) |
java.lang.StringBuffer | getRequestURL() | Returns the full URL when the client made the request |
java.lang.String | getQueryString() | Returns the parameter part of the request line |
java.lang.String | getHeader(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 type | method | describe |
---|---|---|
void | setCharacterEncoding(String charset) | Set the encoding method of response client information encoding |
ServletOutputStream | getOutputStream() | Returns a servlet OutputStream suitable for writing binary data in the response |
java.io.PrintWriter | getWriter() | Returns a PrintWriter object that can send character text to the client |
void | setHeader(String name, jString value) | Set a response header and the given name and value |
void | setStatus(int sc) | Set status code ring |
void | sendRedirect(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.