1.2(学习笔记)Servlet基础(doGet、doPost、生命周期、页面跳转)

一、doGet()与doPost()

  我们在TestServlet类中重写doGet()、doPost()、service()。

  

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet{
    public TestServlet() {};
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doPost");
    }

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("sevice");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doGet");
    }
}

同时在WebContent创建一个Test.html文件

  

<!DOCTYPE html>
<!-- http://localhost:8080/TestServlet/Test.html -->
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <!--表单提交调用servlet  -->
    <!-- http://localhost:8080/TestServlet/TestServlet.html -->
    <form name = f1 action = "/TestServlet/TestServlet.html" method = "get">
        username:<input type = "text" name = "username"></input>
        pwd:<input type = "password" name = "pwd"></input>
        <input type = "submit" value = "提交">
    </form>
    
</body>
</html>

我们点击提交按钮会发现控制台输出sevice,说明调用的service()方法。

我们看下API中关于service()方法的介绍:接收标准的HTTP请求,并将其

发送到此类中定义的doXXX方法,不需要重写这个方法。

也就是说请求会先传递到service()中,在由其发送给doXXX方法。

只要service()被重写了,请求就会一直传递给service().

我们将service()方法注释

再来提交信息,看下会执行那个方法。

可以看4到此时执行的是doGet,这时因为在form中设置了method=“get”,

代表提交方式为get,请求先提交给service(),然后再由其转发给对应的doXXX方法。

<form name = f1 action = "/TestServlet/TestServlet.html" method = "get">

由于设置了提交方式为get,所以是执行给doGet()。

doGet调用时我会发现在地址栏显示传递给servlet的数据:

 这样是不安全的,而且采用get方式传递的数据有大小限制,后面跟随的信息字节不能超过1.3k。

我们来看下API中对doGet()的叙述:

由服务器调用,以允许servlet处理get请求,重写此方法时,读取请求数据、

写入响应头、获取响应的写入器或输出流对象,最后写入响应数据。

如果将"get"设置为“post”,则会执行doPost()方法。

采用post传递数据不会在URL上显示出来,有一定的安全性。

而且post可以传递的数据理论上是无限大的。

二、Servlet生命周期

  2.1实例化一个Servlet

    创建一个servlet实例

  2..2调用Init()

    调用一次。

  2.3调用service方法(doGet、doPost)

    被调用多次,每次请求调用。

  2.4调用destory方法。

    调用一次销毁Servlet

  我们创建一个TestServlet类,继承HTTPServlet。

  重写里面的intI()、doget() doPost() destroy() 并添加一个无参构造器。

  HTML采用上述代码。

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 TestServlet extends HttpServlet{
    public TestServlet() {
        System.out.println("TestServlet");
    };
    
    @Override
    public void init() throws ServletException {
        System.out.println("Init");
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doPost");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("doGet");
    }
    
    @Override
    public void destroy() {
        System.out.println("destroy");
    }
}

然后将项目添加到Tomcat上。

点击提交我们会发现控制台中打印的信息:

一开始首先实例化一个Servlet,然后初始化,我们提交数据时调用对应的servlet方法(doGet或doPost)。

我们继续刷新会发现控制台继续打印doGet,但实例化和初始化只调用一次,有请求是调用则调用doGet方法。

最后我们将Tomcat停止运行,会发现控制会输出destroy,此时servlet被销毁了。

 三、获取初始化参数

  首先在web.xml文件中配置初始化参数。

  初始化参数分为:局部初始化,只有当前Servlet可以获取其参数。

          全局初始化:所有Servlet都可以获取其参数。

  我们首先要在web.xml中设置初始参数信息。

  

<context-param> <!-- 设置全局参数 -->
      <param-name>context-param</param-name>
      <param-value>localhost:3306/mydatabase</param-value>
  </context-param>
  
  <servlet>
    <servlet-name>firstServlet</servlet-name>
    <servlet-class>com.servlet.firstServlet.TestServlet</servlet-class>
    
    <init-param>   <!-- 设置局部初始化参数 -->
        <param-name>initParam</param-name>   <!-- 设置参数名称和值 -->
        <param-value>initParam</param-value> <!-- 该初始化参数是设置在当前这个Servlet下的-->
    </init-param>                 <!-- 所以也只有当前Servlet可以获取到-->
  </servlet>
  <servlet-mapping>
    <servlet-name>firstServlet</servlet-name>
    <url-pattern>/TestServlet.html</url-pattern>
  </servlet-mapping>

设置好了参数,我们来获取参数。

  

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 TestParam extends HttpServlet{
    
    private String initParam = null;
    private String contextParam = null;
    
    @Override
    public void init() throws ServletException {
     //获取初始化参数,和全局参数
this.initParam = this.getInitParameter("initParam"); this.contextParam = this.getServletContext().getInitParameter("context-param"); } @Override //在doGet中输出参数。 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("initparam:"+initParam); System.out.println("contextParam:"+contextParam); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp);//调用doGet方法 } }

初始化之后我们提交数据就会调用doGet方法,将获取到的初始化参数打印出来。

四、页面跳转

  4.1请求重定向

  请求重定向,即进行页面跳转。

  需要用到void  sendRedirect(java.lang.String location)

  当location是带有/的话,将被解释为容器的根,

  即此时的地址会被解释为localhost:8080+location。

  例如localtion为"/fail.htm",此时跳转的地址位localhost:8080/fail.html

  当没有‘/’时,将解释为相对于当前请求的URL地址。

  例如localtion为"fail.htm",此时跳转的是localhost:8080/项目名/fail.html

 

  使用指定的重定向URL向客户端发送临时重定向响应。

  获取表达数据采用getParameter(Stringz name),

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 TestServlet extends HttpServlet{
    private String initParam = null;
    private String contextParam = null;
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //获取HTML中设置了 name = "username" 标签的数据 String name
= req.getParameter("username");//获取表单提交的数据, //如果输入框的内容等于百度则跳转到百度,其他跳转到fail.html if("baidu".equals(name)) //跳转到百度 resp.sendRedirect("http://www.baidu.com"); else //跳转到当前工程WebContext目录下的fail.html resp.sendRedirect("fail.html"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }

采用重定向的跳转方法,不共享request的信息。

当username输入框的为百度时则跳转到百度首页,

其他的输入跳转到当前项目WebContent下的fail.html

重定向时地址栏会显示重定向资源的路径。

 

 

  4.2请求转发:将当前请求转发到另一个资源处理。

  请求转发时我们需要用到一个接口 RequestDispatcher。

  TequestDispatcher:接收客户端请求,并将请求发送到服务器上的其他资源(如servlet、html文件或jsp文件)。

  主要方法:

  void forward(ServletRequest request, ServletResponse response)

  将请求转发到服务器上另一资源,request为客户端对Servlet的请求的request对象,

  response为表示servlet返回到客户端的响应的servletResponse对象

    那么要想调用转发,我们必须向获取一个实现了RequestDispatcher接口的对象。

  这时可以request下的RequestDispatcher getRequestDispatcher(java.lang.String path)方法

  该方法获取一个RequestDispathcher对象,path为指定资源的路径名,可以为相对路径,

  当为相对路径时必须是相对当前Servlet而言的。

  请求转发只能在本应用资源下,不能先请求重定向那样跨应用(重定向到百度)。

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 TestServlet extends HttpServlet{
    private PrintStream out = System.out;
    private String initParam = null;
    private String contextParam = null;
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     PrintWriter out = resp.getWriter();
     out.println("servlet..");
//设置资源路径 RequestDispatcher rd = req.getRequestDispatcher("fail.html"); //转发,由于是携带req、resp转发的,所以转发后的资源可以获取其数据。 rd.forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }

但提交表单,进入doGet()方法后,会转发请求到指定的资源。

  我们会发现请求转发并没有像重定向那样将URL变为fail.html,这时因为此时转发的是请求。

  而且当前servlet输出的信息(“servlet..”)也没有打印出来,

  转发就相当于将事情交给另外一个人去处理。自己不插手了。 

  4.3请求包含:将其他资源的响应结果包含到当前Servlet中。

  请求包含和请求转发都是RequestDispatcher中定义的方法。

  所以都是首先获取RequestDispatcher对象,然后调用对应方法。

  请求包含是调用的是void include(ServletRequest request, ServletResponse response)

  

import java.io.IOException;
import java.io.PrintStream;
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 TestServlet extends HttpServlet{
//    private PrintStream out = System.out;
    private String initParam = null;
    private String contextParam = null;
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        out.println("servlet");
        //设置资源路径
        RequestDispatcher rd = req.getRequestDispatcher("/fail.html");
        //转发,由于是携带req、resp转发的servlet..,所以转发后的资源可以获取其数据。
        rd.include(req, resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

  

  

  请求包含的url也不会发生变化,并且包含了fail.htm界面。

  如果没有servlet,界面上会显示html所代表的内容,即Fail。

  但当前界面将fail.htm的代码包含进来了,破坏了html的结构,

  所以显示的是servlet+html代码。

  包含是当前Servlet将另外一个资源及其处理流程包含进来。

  转发时当前Servlet将事情交给另外一个资源去完成。

  请求转发与请求包含的区别可参阅:https://blog.csdn.net/u013425438/article/details/81606248

原文地址:https://www.cnblogs.com/huang-changfan/p/10269356.html