Java Servlet初学入门教程

1. 简介

本文章基于:

  • Eclipse 4.6(NEON)
  • Servlet 3.0
  • Tomcat 9.0

2. Servlet是什么?

Java Servlet是在Web或应用程序服务器上运行的程序,并充当Web浏览器或其他HTTP客户端发出的请求与HTTP服务器上的数据库或应用程序之间的中间层。使用Servlet,可以通过网页表单收集用户的输入,从数据库或其他来源显示记录,并动态创建网页。

Servlet是什么

3. Servlet生命周期

下图说明了Servlet的生命周期。 自创建以来,一直处理用户的请求,直到销毁为止。

Servlet生命周期

Servlet生命周期共有5个步骤:

  • 第1步:加载Servlet类。
  • 第2步:创建Servlet实例。
  • 第3步:调用servlet init()方法。
  • 第4步:调用servlets service()方法。
  • 第5步:调用servlet destroy()方法。

最初加载Servlet时,第1、2和3步仅执行一次。默认情况下,只有在收到第一个请求后才加载servlet。不过,可以在容器启动时强制容器加载servlet。

第4步多次执行 – 对Servlet的每个HTTP请求一次都会执行第4步。当servlet容器销毁servlet时,执行第5步。

可以下图,以更好地了解Servlet的生命周期。

Servlet生命周期

当用户请求Servlet时,Servlet将调用service()方法来满足用户的需求,service()将调用doGet()doPost()
因此,当用户请求Servlet时,Servlet将在第一次请求时创建,并同时调用servlet的init()方法以对其进行初始化,而init()方法仅被调用一次。 destroy()方法用于销毁servlet,在删除Web应用程序的部署(取消部署)或停止Web服务器时,它将仅被调用一次。

4. 安装Tomcat Web服务器

要开始使用Servlet,需要下载Tomcat Web Server并在Eclipse中进行配置。参考以下网址:

5. 在Web项目中创建Servlet

打开Eclipse,选择:File/New/Other,创建一个动态Web项目,如下图所示:

创建Web项目

输入项目名称:ServletTutorial,如下图所示:

Java Servlet初学入门教程

点击下一步(Next>),如下图所示:
Java Servlet初学入门教程

勾选生成web.xml,点击完成(Finish),如下图所示:
Java Servlet初学入门教程

项目创建成功后,目录结构如下所示:
Java Servlet初学入门教程

接下来在WebContent目录中创建一个HTML文件:index.html,代码如下:

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body>     <h1>Hello World</h1>  </body> </html> 

6. 配置Eclipse在Tomcat上运行应用

到目前为止,我们只是创建了一个动态Web项目。接下来要对项目进行配置,以便它可以运行Web应用程序。

在Eclipse中,右键单击项目名称:ServletTutorial,选择Properties:

Java Servlet初学入门教程

选择运行环境的版本,如下图所示:

运行环境的版本

填写服务器的名称,并选择运行服务器的安装路径,然后点击完成。如下图所示:

Java Servlet初学入门教程

返回运行时界面,选择上面配置的服务器(Apache Tomcat v9),如下图所示:

选择服务器

右键单击项目ServletTutorial,选择“Run As / Run on Server”。如下图所示:

选择运行为...

弹出选择服务器,这里选择Tomcat V9 Server,如下图所示:

弹出选择服务器

选择发布项目,如下图所示:
选择发布项目

网站已经在Eclipse浏览器上运行。如下图所示:

运行动态网站

工作原理

当您访问以下URL时:

网站显示index.html页面的内容,这是可以理解的。但是,如果访问URL:

上面URL中并没有指定要访问的页面,因此Web服务器将查找在web.xml中声明的<welcome-file>标记中声明的默认页面以获取答案。

注意:/ServletTutorial称为上下文路径。每个网站都有一个上下文路径,可以为它配置另一个值或将其设置为空。如果为空,则可以通过以下方式访问网站:

过程如下图中所示:

执行过程

7. 加入一些类

下面将向这个示例中加入一些Java类:

文件:Constants.java

package com.xntutor.tutorial.beans;  public class Constants {      public static final String ATTRIBUTE_USER_NAME_KEY = "ATTRIBUTE_USER_NAME_KEY";      public static final String SESSION_USER_KEY = "SESSION_USER_KEY";      public static final String CALLBACK_URL_KEY = "CALLBACK_URL_KEY";  } 

文件:UserInfo.java

package com.xntutor.tutorial.beans;  public class UserInfo {      public String userName;     private int post;     private String country;      public UserInfo(String userName, String country, int post) {         this.userName = userName;         this.country = country;         this.post = post;     }      public int getPost() {         return post;     }      public void setPost(int post) {         this.post = post;     }      public String getCountry() {         return country;     }      public void setCountry(String country) {         this.country = country;     }      public void setUserName(String userName) {         this.userName = userName;     }      public UserInfo(String userName) {         this.userName = userName;     }      public String getUserName() {         return this.userName;     } } 

8. 创建一个Servlet

项目的目录结构如下所示:

创建一个Servlet

文件:HelloServlet.java,完整代码如下:

package com.xntutor.tutorial.servlet;  import java.io.IOException;  import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  public class HelloServlet extends HttpServlet {      private static final long serialVersionUID = 1L;      public HelloServlet() {     }      @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          ServletOutputStream out = response.getOutputStream();          out.println("<html>");         out.println("<head><title>Hello Servlet</title></head>");          out.println("<body>");         out.println("<h3>Hello World</h3>");         out.println("This is my first Servlet");         out.println("</body>");         out.println("<html>");     }      @Override     protected void doPost(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         this.doGet(request, response);     }  } 

如果已创建的HelloServlet类代码提示有错误,可能是您还未加入Servlet库。在这里,因为使用Tomcat,因此需要对其进行声明。

在“项目”上单击鼠标右键,选择“属性”:

Java Servlet初学入门教程

然后,选择服务器运行时,如下图所示:

选择服务器运行时

选择对应的服务器版本,如下图所示:

选择服务器版本

选择服务器版本2

现在HelloServlet类代码应该没有错误提示了。
接下来,需要在Web.xml中声明HelloServlet和访问它的路径。需要添加以下配置:

<!-- Define servlet, named helloServlet --> <servlet>    <servlet-name>helloServlet</servlet-name>    <servlet-class>com.xntutor.tutorial.servlet.HelloServlet</servlet-class> </servlet>  <!-- Defines the path to access this Servlet --> <servlet-mapping>    <servlet-name>helloServlet</servlet-name>    <url-pattern>/hello</url-pattern> </servlet-mapping> 

完整的web.xml文件中的代码如下所示:

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns="http://java.sun.com/xml/ns/javaee"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    id="WebApp_ID" version="3.0">    <display-name>ServletTutorial</display-name>      <servlet>        <servlet-name>helloServlet</servlet-name>        <servlet-class>com.xntutor.tutorial.servlet.HelloServlet</servlet-class>    </servlet>     <servlet-mapping>        <servlet-name>helloServlet</servlet-name>        <url-pattern>/hello</url-pattern>    </servlet-mapping>      <welcome-file-list>        <welcome-file>index.html</welcome-file>        <welcome-file>index.html</welcome-file>        <welcome-file>index.jsp</welcome-file>        <welcome-file>default.html</welcome-file>        <welcome-file>default.html</welcome-file>        <welcome-file>default.jsp</welcome-file>    </welcome-file-list>   </web-app> 

右键单击项目(ServletTutorial),然后选择:Run As/Run on Server,如下图所示:

右键单击项目

右键单击项目2

服务器启动完成后,使用浏览器访问以下URL:

访问结果

可以根据下面的执行流程图示来了解Servlet的工作原理。

Servlet的工作原理

调用Servlet时,根据客户端的请求方法来调用doGet(..)doPost(..)。在doGet()doPost()中,可以检索ServletOutputStream对象,这是将数据发送到用户浏览器的输出流。调用ServletOutputStream.println(..)将数据写入流中。如下示例代码:

// The output stream to send data to user's browser ServletOutputStream out = response.getOutputStream(); 

9. Servlet初始化参数

web.xml中声明servlet时,可以为servlet设置初始化参数。参考以下Servlet实现代码。

文件:InitParamServlet.java

package com.xntutor.tutorial.servlet;  import java.io.IOException;  import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  public class InitParamServlet extends HttpServlet {      private static final long serialVersionUID = 1L;      private String emailSupport1;      public InitParamServlet() {     }      // This method is always called once after the Servlet object is created.     @Override     public void init(ServletConfig config) throws ServletException {         super.init(config);          // Get the value of the initialization parameter of the Servlet.         // (According to the Configuration of this Servlet in web.xml).         this.emailSupport1 = config.getInitParameter("emailSupport1");     }      @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          // Get the initialization parameter's value in a different way.         String emailSupport2 = this.getServletConfig().getInitParameter("emailSupport2");          ServletOutputStream out = response.getOutputStream();          out.println("<html>");         out.println("<head><title>Init Param</title></head>");          out.println("<body>");         out.println("<h3>Init Param</h3>");         out.println("<p>emailSupport1 = " + this.emailSupport1 + "</p>");         out.println("<p>emailSupport2 = " + emailSupport2 + "</p>");         out.println("</body>");         out.println("<html>");     }      @Override     protected void doPost(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         this.doGet(request, response);     }  } 

接下来,向web.xml文件添加一些内容:

    <servlet>         <servlet-name>initParamServlet</servlet-name>         <servlet-class>com.xntutor.tutorial.servlet.InitParamServlet</servlet-class>          <init-param>             <param-name>emailSupport1</param-name>             <param-value>support1@xntutor.com</param-value>         </init-param>          <init-param>             <param-name>emailSupport2</param-name>             <param-value>support2@xntutor.com</param-value>         </init-param>      </servlet> 

完整的web.xml文件内容,如下所示:

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns="http://java.sun.com/xml/ns/javaee"     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"     id="WebApp_ID" version="3.0">     <display-name>ServletTutorial</display-name>     <!-- Define servlet, named helloServlet -->     <servlet>         <servlet-name>helloServlet</servlet-name>         <servlet-class>com.xntutor.tutorial.servlet.HelloServlet</servlet-class>     </servlet>     <servlet>         <servlet-name>initParamServlet</servlet-name>         <servlet-class>com.xntutor.tutorial.servlet.InitParamServlet</servlet-class>          <init-param>             <param-name>emailSupport1</param-name>             <param-value>support1@xntutor.com</param-value>         </init-param>          <init-param>             <param-name>emailSupport2</param-name>             <param-value>support2@xntutor.com</param-value>         </init-param>      </servlet>       <servlet-mapping>         <servlet-name>initParamServlet</servlet-name>         <url-pattern>/initParam</url-pattern>     </servlet-mapping>      <!-- Defines the path to access this Servlet -->     <servlet-mapping>         <servlet-name>helloServlet</servlet-name>         <url-pattern>/hello</url-pattern>     </servlet-mapping>     <welcome-file-list>         <welcome-file>index.html</welcome-file>         <welcome-file>index.html</welcome-file>         <welcome-file>index.jsp</welcome-file>         <welcome-file>default.html</welcome-file>         <welcome-file>default.html</welcome-file>         <welcome-file>default.jsp</welcome-file>     </welcome-file-list> </web-app> 

重新运行Web应用程序并访问以下URL:

应该会看到类似下面的结果:

运行结果

10. 使用注释配置Servlet

在Servlet 3.0或更高版本中,可以使用Annotation配置Servlet,在本项目中,我们使用Servlet 3.x版,以便可以使用Annotation进行配置。参考下面的一个例子。

文件:AnnotationExampleServlet.java

package com.xntutor.tutorial.servlet;  import java.io.IOException;  import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  // You can configure one or multiple 'URL Patterns' can access this Servlet. @WebServlet(urlPatterns = { "/annotationExample", "/annExample" }, initParams = {         @WebInitParam(name = "emailSupport1", value = "support1@xntutor.com"),         @WebInitParam(name = "emailSupport2", value = "support2@xntutor.com") }) public class AnnotationExampleServlet extends HttpServlet {      private static final long serialVersionUID = 1L;      private String emailSupport1;      public AnnotationExampleServlet() {     }      // In any case, init() is guaranteed to be called     // before the Servlet handles its first request.     @Override     public void init(ServletConfig config) throws ServletException {         super.init(config);          this.emailSupport1 = config.getInitParameter("emailSupport1");     }      @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          String emailSupport2 = this.getServletConfig().getInitParameter("emailSupport2");          ServletOutputStream out = response.getOutputStream();          out.println("<html>");         out.println("<head><title>Init Param</title></head>");          out.println("<body>");         out.println("<h3>Servlet with Annotation configuration</h3>");         out.println("<p>emailSupport1 = " + this.emailSupport1 + "</p>");         out.println("<p>emailSupport2 = " + emailSupport2 + "</p>");         out.println("</body>");         out.println("<html>");     }      @Override     protected void doPost(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         this.doGet(request, response);     }  } 

可以通过以下两个链接之一来访问此Servlet:

它们运行的结果相同:

使用注释配置Servlet

上面Servlet不需要在web.xml文件中配置。

11. Servlet URL模式

Servlet URL模式

有四种方法可以配置Servlet的路径:

第1种方式: /*,示例如下:

  • http://example.com/contextPath
  • http://example.com/contextPath/status/abc

第2种方式: /status/abc/*,示例如下:

  • http://example.com/contextPath/status/abc
  • http://example.com/contextPath/status/abc/mnp
  • http://example.com/contextPath/status/abc/mnp?date=today

第3种方式: *.map,示例如下:

  • http://example.com/contextPath/status/abc.map
  • http://example.com/contextPath/status.map?date=today

第4种方式: /,这是默认的Servlet。

当用户在浏览器上输入链接时,它将被发送到WebContainerWebContainer必须决定是否
Servlet将处理来自用户的请求。

下图说明了WebContainer如何决定使用Servlet来响应来自客户端的请求。

响应客户端的请求

例如,创建一个带有星号的Servlet url-pattern:

  • url-pattern = "/any/*";

文件:AsteriskServlet.java

package com.xntutor.tutorial.servlet;  import java.io.IOException;  import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  @WebServlet(urlPatterns = { "/any/*" }) public class AsteriskServlet extends HttpServlet {      private static final long serialVersionUID = 1L;      public AsteriskServlet() {     }      @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          ServletOutputStream out = response.getOutputStream();          out.println("<html>");         out.println("<head><title>Asterisk</title></head>");          out.println("<body>");          out.println("<h3>Hi, your URL match /any/*</h3>");          out.println("</body>");         out.println("<html>");     }      @Override     protected void doPost(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         this.doGet(request, response);     }  } 

以下URL由AsteriskServlet(/any/*)提供服务:

  • http://localhost:8080/ServletTutorial/any/path1/a.html
  • http://localhost:8080/ServletTutorial/any/something
  • http://localhost:8080/ServletTutorial/any

访问上面URL,可以看到以下结果:

默认的Servlet

默认Servlet

作为默认Servlet,Servlet将用于处理路径与应用程序中声明的Servlet的url-pattern不匹配的请求。下面来看看默认servlet的示例:

文件:MyDefaultServlet.java

package com.xntutor.tutorial.servlet;  import java.io.IOException;  import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  @WebServlet(urlPatterns = { "/" }) public class MyDefaultServlet extends HttpServlet {     private static final long serialVersionUID = 1L;     public MyDefaultServlet() {    }     @Override    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {         ServletOutputStream out = response.getOutputStream();         out.println("<html>");        out.println("<head><title>Page not found</title></head>");         out.println("<body>");        out.println("<h3>Sorry! Page not found</h3>");        out.println("<h1>404</h1>");        out.println("Message from servlet: " + this.getClass().getName());        out.println("</body>");        out.println("<html>");    }     @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doGet(request, response);    }  } 

重新运行Web应用程序,并访问URL:

  • http://localhost:8080/ServletTutorial/news/someonewho

上面的链接servletPath = /news/tomAndJerry,与声明的url模式不匹配。但是“默认Servlet”满足该请求。

默认Servlet

12. 获取Servlet的基本信息

有时因为某种需要,想了解Servlet实例提供的时间有关的信息,这些信息包括:

  • 来自客户端的信息请求。
  • 服务器信息。
  • 客户资料。
  • 标头信息按要求发送。

创建一个Servlet类文件:ExampleInfoServlet.java

package com.xntutor.tutorial.servlet;  import java.io.IOException; import java.util.Enumeration;  import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  @WebServlet("/other/exampleInfo") public class ExampleInfoServlet extends HttpServlet {      private static final long serialVersionUID = 1L;      public ExampleInfoServlet() {         super();     }      @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         ServletOutputStream out = response.getOutputStream();          out.println("<style> span {color:blue;} </style>");          String requestURL = request.getRequestURL().toString();         out.println("<br><span>requestURL:</span>");         out.println(requestURL);          String requestURI = request.getRequestURI();         out.println("<br><span>requestURI:</span>");         out.println(requestURI);          String contextPath = request.getContextPath();         out.println("<br><span>contextPath:</span>");         out.println(contextPath);          out.println("<br><span>servletPath:</span>");         String servletPath = request.getServletPath();         out.println(servletPath);          String queryString = request.getQueryString();         out.println("<br><span>queryString:</span>");         out.println(queryString);          String param1 = request.getParameter("text1");         out.println("<br><span>getParameter text1:</span>");         out.println(param1);          String param2 = request.getParameter("text2");         out.println("<br><span>getParameter text2:</span>");         out.println(param2);          // Server Infos         out.println("<br><br><b>Server info:</b>");          out.println("<br><span>serverName:</span>");         String serverName = request.getServerName();         out.println(serverName);          out.println("<br><span>serverPort:</span>");         int serverPort = request.getServerPort();         out.println(serverPort + "");          // Client Infos         out.println("<br><br><b>Client info:</b>");          out.println("<br><span>remoteAddr:</span>");         String remoteAddr = request.getRemoteAddr();         out.println(remoteAddr);          out.println("<br><span>remoteHost:</span>");         String remoteHost = request.getRemoteHost();         out.println(remoteHost);          out.println("<br><span>remoteHost:</span>");         int remotePort = request.getRemotePort();         out.println(remotePort + "");          out.println("<br><span>remoteUser:</span>");         String remoteUser = request.getRemoteUser();         out.println(remoteUser);          // Header Infos         out.println("<br><br><b>headers:</b>");          Enumeration<String> headers = request.getHeaderNames();         while (headers.hasMoreElements()) {             String header = headers.nextElement();             out.println("<br><span>" + header + "</span>: " + request.getHeader(header));         }          // Servlet Context info:         out.println("<br><br><b>Servlet Context info:</b>");         ServletContext servletContext = request.getServletContext();          // Location of web application in hard disk         out.println("<br><span>realPath:</span>");         String realPath = servletContext.getRealPath("");         out.println(realPath);     }      @Override     protected void doPost(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         this.doGet(request, response);     }  } 

请参阅下图以了解一些您感兴趣的信息:
感兴趣的信息

重新运行Web应用程序并访问链接:

得到以下结果:

获取Servlet的基本信息

13. Servlet转发

转发(Forward):向Servlet发送请求时,它可以将请求转发到另一个页面(或另一个Servlet)。 用户浏览器上的地址仍然是第一页的链接,但是内容是由转发的页面创建的。

请求的页面被转发到位于Web应用程序上的页面(或servlet)。使用转发,可以使用request.setAttribute()将数据从第1页传输到第2页。

Servlet转发

创建一个Servlet类文件:ForwardDemoServlet.java

import java.io.IOException;  import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  import com.xntutor.tutorial.beans.Constants;  @WebServlet("/other/forwardDemo") public class ForwardDemoServlet extends HttpServlet {     private static final long serialVersionUID = 1L;      // Request:     // http://localhost:8080/ServletTutorial/other/forwardDemo?forward=true     @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          // Get value of parameter on URL.         String forward = request.getParameter("forward");          if ("true".equals(forward)) {             System.out.println("Forward to ShowMeServlet");              // Set data to attribute of the request.             request.setAttribute(Constants.ATTRIBUTE_USER_NAME_KEY, //                     "Hi, I'm Tom come from Walt Disney !");              RequestDispatcher dispatcher //                     = request.getServletContext().getRequestDispatcher("/showMe");             dispatcher.forward(request, response);              return;         }         ServletOutputStream out = response.getOutputStream();         out.println("<h3>Text of ForwardDemoServlet</h3>");         out.println("- servletPath=" + request.getServletPath());     }      @Override     protected void doPost(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         this.doGet(request, response);     }  } 

重新运行Web应用并分别访问以下2个URL:

情况1: 没有转发,页面的数据由ForwardDemoServlet生成。如下图所示:
ForwardDemoServlet

情况2:向前转移到ShowMeServlet。在这种情况下,页面上的URL不变,而页面的数据是由ShowMeServlet生成的。如下图所示:
ShowMeServlet

在某些情况下(例如,当用户请求Servlet-A时)通常使用转发。但是,此页面必须先登录。Servlet-A会检查用户的登录,如果尚未登录,它将移至Servlet-Login。回到RequestDispatcher,有两种获取RequestDispatcher对象的方法。

RequestDispatcher对象

request.getServletContext ().getRequestDispatcher(url)返回RequestDispatcher对象,它是位于相对于contextPath(相对于网站根目录的位置)。

request.getRequestDispatcher(url)返回RequestDispatcher对象,它是相对于当前页面位置。

注意:

  • 重定向允许导航到网站以外的页面。
  • 转发仅允许移动到网站内的页面,并且可以通过request.setAttribute在两个页面之间传输数据。

14. Servlet重定向

重定向:当用户向Servlet(页面A)发出请求时,Servlet可以将请求重定向到另一个页面(页面B),并结束其任务。 页面被重定向到应用程序中的页面,也可以Web应用以外是任何页面。

不同与转发,使用重定向不能使用request.setAttribute(..)将数据从页面A传输到页面B。

重定向

创建一个Servlet类文件:ShowMeServlet.java

package com.xntutor.tutorial.servlet.other;  import java.io.IOException;  import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  import com.xntutor.tutorial.beans.Constants;   @WebServlet("/showMe") public class ShowMeServlet extends HttpServlet {     private static final long serialVersionUID = 1L;      @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          // Get value of an attribute of the request.         String value = (String) request.getAttribute(Constants.ATTRIBUTE_USER_NAME_KEY);          ServletOutputStream out = response.getOutputStream();          out.println("<h1>ShowMeServlet</h1>");         out.println(value);     }      @Override     protected void doPost(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         this.doGet(request, response);     }  } 

创建另一个Servlet类文件:RedirectDemoServlet.java

package com.xntutor.tutorial.servlet.other;  import java.io.IOException;  import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;  @WebServlet("/other/redirectDemo") public class RedirectDemoServlet extends HttpServlet {      private static final long serialVersionUID = 1L;      // Request:     // http://localhost:8080/ServletTutorial/other/redirectDemo?redirect=true     @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          // Get the value of parameter on the URL.         String redirect = request.getParameter("redirect");          if ("true".equals(redirect)) {             System.out.println("Redirect to ShowMeServlet");              // contextPath: Is an empty string "" or non-empty.             // If it is non-empty, it always starts with /             // and does not ends with /             String contextPath = request.getContextPath();              // ==> /ServletTutorial/showMe             response.sendRedirect(contextPath + "/showMe");             return;         }          ServletOutputStream out = response.getOutputStream();         out.println("<h3>Text of RedirectDemoServlet</h3>");         out.println("- servletPath=" + request.getServletPath());     }      @Override     protected void doPost(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {         this.doGet(request, response);     }  } 

重新运行服务器并在浏览器中分别访问以下2个URL:

访问第一个URL显示内容如下:
第一个URL

访问第二个URL,请求将重定向到ShowMeServlet。在浏览器上看到的URL是Servlet ShowMeServlet的路径。显示内容如下:

第二个URL

15. Servlet会话

HttpSession对象代表一个用户会话。 用户会话包含有关多个HTTP请求的用户信息。当用户首次进入网站时,Servlet会为用户提供唯一的ID来标识其会话依据。 此ID通常存储在cookie或请求参数中。

下面是访问会话对象的方式:

protected void doGet(HttpServletRequest request,    HttpServletResponse response)        throws ServletException, IOException {     HttpSession session = request.getSession(); } 

可以将值存储在会话对象中,并在以后检索(读取)它们。首先,让我们看看如何在会话对象中存储值:

// Get the HttpSession object. HttpSession session = request.getSession();  // Suppose user has successfully logged. UserInfo loginedInfo = new UserInfo("Maxsu", "China", 5);  // Store user information into a Session attribute. // You can retrieve this information using the getAttribute method. session.setAttribute(Constants.SESSION_USER_KEY, loginedInfo); 

并检索(读取)存储在Session中特定页面的信息。

// Get the HttpSession object. HttpSession session = request.getSession();  // Get the UserInfo object stored to the session  // after the user login successfully. UserInfo loginedInfo      = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY); 

下面通过一个完整的示例,演示创建使用会话。

Servlet类文件:LoginServlet.java

package com.xntutor.tutorial.servlet.session;  import java.io.IOException;  import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;  import com.xntutor.tutorial.beans.Constants; import com.xntutor.tutorial.beans.UserInfo;  @WebServlet(urlPatterns = { "/login" }) public class LoginServlet extends HttpServlet {      private static final long serialVersionUID = 1L;      public LoginServlet() {     }      @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          ServletOutputStream out = response.getOutputStream();          // Get HttpSession object         HttpSession session = request.getSession();          // Suppose a user has successfully logged.         UserInfo loginedInfo = new UserInfo("Maxsu", "China", 5);          // Storing user information in an attribute of Session.         session.setAttribute(Constants.SESSION_USER_KEY, loginedInfo);          out.println("<html>");         out.println("<head><title>Session example</title></head>");          out.println("<body>");         out.println("<h3>You are logined!, info stored in session</h3>");          out.println("<a href='userInfo'>View User Info</a>");         out.println("</body>");         out.println("<html>");     }  } 

Servlet类文件:LoginServlet.java

package com.xntutor.tutorial.servlet.session;  import java.io.IOException;  import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;  import com.xntutor.tutorial.beans.Constants; import com.xntutor.tutorial.beans.UserInfo;  @WebServlet(urlPatterns = { "/userInfo" }) public class UserInfoServlet extends HttpServlet {      private static final long serialVersionUID = 1L;      public UserInfoServlet() {     }      @Override     protected void doGet(HttpServletRequest request, HttpServletResponse response)             throws ServletException, IOException {          ServletOutputStream out = response.getOutputStream();          // Get HttpSession object.         HttpSession session = request.getSession();          // Get UserInfo object stored in session after user login successful.         UserInfo loginedInfo = (UserInfo) session.getAttribute(Constants.SESSION_USER_KEY);          // If not logined, redirect to login page (LoginServlet).         if (loginedInfo == null) {             // ==> /ServletTutorial/login             response.sendRedirect(this.getServletContext().getContextPath() + "/login");             return;         }          out.println("<html>");         out.println("<head><title>Session example</title></head>");          out.println("<body>");          out.println("<h3>User Info:</h3>");          out.println("<p>User Name:" + loginedInfo.getUserName() + "</p>");         out.println("<p>Country:" + loginedInfo.getCountry() + "</p>");         out.println("<p>Post:" + loginedInfo.getPost() + "</p>");          out.println("</body>");         out.println("<html>");     }  } 

重新运行服务器并在浏览器中以下URL:

运行结果

点击上面链接查看登录的用户信息,结果如下所示:

查看登录的用户信息

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/264052.html

(0)
上一篇 2022年6月6日 23:20
下一篇 2022年6月6日 23:25

相关推荐

发表回复

登录后才能评论