• 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

  • 相关阅读:
    基础数据类型补充
    编码转换
    is 和 == 的区别
    字典 dict
    列表与元组
    python基础第一节
    poll函数
    基本 TCP 的回射服务器
    文件IO
    base | AtomicIntegerT类
  • 原文地址:https://www.cnblogs.com/huang-changfan/p/10269356.html
Copyright © 2020-2023  润新知