JavaWeb学习——Servlet学习(Reponse、Request)、转发和重定向的区别

1.Servlet简介

Servlet是sun公司提供的一门用于动态开发WEB资源的技术,sun(Sun Microsystems)公司创建于1982年,2009年4月20日被Oracle公司收购。

  • 使用servlet技术步骤
  • 1.编写好一个类,实现servlet接口
  • 2.把开发好的Java类部署到WEB服务器中,通常我们把实现了servlet接口的Java程序,称为Servlet
2.Servlet运行过程
  • ①Web服务器检查是否已经装在并创建了该Servlet的实例对象。如果装载了,直接执行第④步
  • ②装载并创建Servlet实例对象
  • ③调用Servlet实例对象的init()方法进行初始化
  • ④创建一个用于封装HTTP请求消息的HttpServletResqurst对象和一个代表HTTP响应消息的HttpServletResponse对象。然后调用Servlet的service()方法向服务器发出请求,并将请求对象和响应对象作为参数传递进去
  • ⑤WEB应用在程序被停止或重新启动之前,Servlet引擎卸载Servlet。并在卸载之前调用Sevlet的destroy()方法释放资源

过程图示:

java重定向慢如何解决_java


java重定向慢如何解决_java_02


java重定向慢如何解决_java重定向慢如何解决_03


java重定向慢如何解决_html_04


Servlet调用图:

java重定向慢如何解决_重定向_05

3.Servlet实现类

Servlet接口有两个默认实现类:GenericServlet和HttpServlet,我们把实现了Servlet接口的类都称之为Servlet

  • GenericServlet
  • GenericServlet是 Servlet 接口和 ServletConfig 接口的实现类. 但是一个抽象类. 其中的 service 方法为抽象方法
  • 如果新建的 Servlet 程序直接继承 GenericSerlvet 会使开发更简洁
  • 具体实现:
    ①. 在 GenericServlet 中声明了一个 SerlvetConfig 类型的成员变量, 在 init(ServletConfig) 方法中对其进行了初始化
    ②. 利用 servletConfig 成员变量的方法实现了 ServletConfig 接口的方法
    ③. 还定义了一个 init() 方法, 在 init(SerlvetConfig) 方法中对其进行调用, 子类可以直接覆盖 init() 在其中实现对 Servlet 的初始化.
    ④. 不建议直接覆盖 init(ServletConfig), 因为如果忘记编写 super.init(config); 而还是用了 SerlvetConfig 接口的方法,
    则会出现空指针异常.
    ⑤. 新建的 init(){} 并非 Serlvet 的生命周期方法. 而 init(ServletConfig) 是生命周期相关的方法.
  • HttpServlet
  • HttpServlet是一个 Servlet, 继承自 GenericServlet. 针对于 HTTP 协议所定制.
  • 在 service() 方法中直接把 ServletReuqest 和 ServletResponse 转为 HttpServletRequest 和 HttpServletResponse.
    并调用了重载的 service(HttpServletRequest, HttpServletResponse)在service(HttpServletRequest, HttpServletResponse) 获取了请求方式: request.getMethod(). 根据请求方式有创建了doXxx() 方法(xxx 为具体的请求方式, 比如 doGet, doPost)
  • 实际开发中, 直接继承 HttpServlet, 并根据请求方式复写 doXxx() 方法即可.
  • 好处: 直接由针对性的覆盖 doXxx() 方法; 直接使用 HttpServletRequest 和 HttpServletResponse, 不再需要强转.
4.使用IDEA开发Servlet
  • ①新建WEB项目,并新建Servlet类
  • 在项目目录下新建lib目录并将servlet的jar包导入
  • java重定向慢如何解决_html_06

  • 编写Servlet类,继承Httpservlet类,重写doGet和doPost方法
  • 如果是post请求就在doPost方法里写代码,如果是get请求就在doGet方法里写代码.这里为了学习期间出错,我们在doGet请求里调用doPost方法
package com.muhan.servlet;

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

public class ServletTest01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //编写代码
    }
}
  • 配置web.xml
<servlet>
        <!--
        servlet-name:名称(任意,但必须与<servlet-mapping>中的servlet-name同名)
        servlet-class:servlet类的路径(包名+类名)
        -->
        <servlet-name>ServletTest01</servlet-name>
        <servlet-class>com.muhan.servlet.ServletTest01</servlet-class>
    </servlet>

        <!--
        servlet-name:与<servlet>中的servlet-name同名即可
        url-pattern:请求路径,格式为:/请求名
        -->
    <servlet-mapping>
        <servlet-name>ServletTest01</servlet-name>
        <url-pattern>/servlet.do</url-pattern>
    </servlet-mapping>
  • 当我们在网页上输入请求路径时是怎么知道是哪个Servlet呢:
  • 从< servlet-mapping>的< url-pattern>:/servlet.do找到< servlet-mapping>的< servlet-name>:ServletTest01
  • 再从< servlet-mapping>的< servlet-name>:ServletTest01找到< servlet>的< servlet-name>:ServletTest01
  • 最后从< servlet>的:ServletTest01找到:com.muhan.servlet.ServletTest01
5.Servlet——Reponse
①重定向

重定向(Redirect)就是通过各种方法将各种网络请求重新定个方向转到其它页面

  • 新建info.jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Hello Servlet</h1>
</body>
</html>
  • 在servlet中写入重定向代码:
resp.sendRedirect("info.jsp");

重定向的参数为页面的路径,但是默认路径是在web目录下,如果该文件在web目录下,就可以省略前面的路径,直接写问文件名

java重定向慢如何解决_java_07

  • 测试
    我们输入的是http://localhost:8080/WEB01/servlet.do但是却重定向到http://localhost:8080/WEB01/info.jsp页面去了
②ServletContext

ServletContext官方叫servlet上下文。服务器会为每一个工程创建一个对象,这个对象就是ServletContext对象。这个对象全局唯一,而且工程内部的所有servlet都共享这个对象。所以叫全局应用程序共享对象。

  • 1).ServletContext的目的就是为了让资源之间共享数据,因为Servlet之间是不嫩直接承诺书数据的,所以要依靠ServletContext对象
  • 2).案例:通过servletContext对象读取网站配置文件
  • 在src下创建resources目录,并在目录下新建一个jdbc.properties文件

java重定向慢如何解决_java重定向慢如何解决_08

driver=com.mysql.jdbc.Driver
username=root
password=123456
url=jdbc:mysql://localhost:3306/smbms
  • 编写Servlet
package com.muhan.servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.FileInputStream;
      import java.io.IOException;
      import java.util.Properties;
      
      public class ServletTest02 extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doPost(req,resp);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //1.获取配置文件路径
              String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/resources/database.properties");
      
              //2.新建Properties集合用来读取配置文件信息,Properties集合可以与流关联读取配置文件
              Properties properties = new Properties();
              properties.load(new FileInputStream(realPath));//将配置文件加载至集合
      
              String driver = properties.getProperty("driver");//获取driver的值
              String username = properties.getProperty("username");//获取username的值
              String password = properties.getProperty("password");//获取password的值
              String url = properties.getProperty("url");//获取url的值
      
              //3.将获取到的值相应到网页
              resp.getWriter().println(driver);
              resp.getWriter().println(username);
              resp.getWriter().println(password);
              resp.getWriter().println(url);
          }
      }
      ```
  • 配置web.xml
<servlet-mapping>
        <servlet-name>ServletTest01</servlet-name>
        <url-pattern>/servlet.do</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>ServletTest02</servlet-name>
        <url-pattern>/q1.do</url-pattern>
    </servlet-mapping>
  • 启动tomcat访问http://localhost:8080/WEB01/q1.do
③一些其他常用方法
  • response.setHeader(“Refresh”, “2;url=http://www.baidu.com”);两秒钟自动跳转到百度,可以跳到自身页面,用于刷新,可以带参数,若不写参数三则是刷新自身网页
  • resp.setContentType();设置响应类型,如:"image/jpg"为图片类型
  • resp.setCharacterEncoding(“utf-8”);设置响应编码格式为utf-8
6.Servlet——Request
① 一些常用方法
req.getContextPath(); //获得web项目路径
req.getRequestURI(); //请求的URL路径
req.getRemoteUser(); //获得远程的用户名
req.getRequestedSessionId(); //获SessionId;
req.getServletPath(); //请求servlet的url
req.getLocalAddr(); //获得本地地址  防火墙
req.getLocalName(); //获得本地名字
req.getLocalPort(); //获得访问的端口号

获取的结果:

/WEB01
/WEB01/q2.do
null
921A65357F41059EC6156E08E0D054CD
/q2.do
0:0:0:0:0:0:0:1
0:0:0:0:0:0:0:1
8080
②Request对象接收前端用户提交的参数
  • 写前端注册页面
  • 表单提交方式get/post
  • 表单提交的位置:服务器形目路径/servlet对应的请求url
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>注册</title>
</head>
<body>

<%--
Form表单
    action:代表要提交的路径,表单要提交到哪里 ,可以提交到一个Servlet
       ${pageContext.request.contextPath}为项目的路径名,
       /q3.do是请求Servlet的url
    method: 提交表单的方式
--%>
<h1>注册</h1>

<form action="${pageContext.request.contextPath}/q3.do" method="post">
  用户名:<input type="text" name="username"><br>
  密码:<input type="password" name="password"><br>
  <input type="submit">
  <input type="reset"><br>
</form>
</body>
</html>
  • 写处理前端请求的Servlet
package com.muhan.servlet;

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

public class ServleTest04 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置请求和响应字符编码
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("utf-8");

        //req.getParameter("控件的name");获取控件传来的值
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        //模拟匹配数据库
        if (username.equals("张三")&&password.equals("123456")){
            System.out.println("登陆成功,转到成功页面");
        }else {
            System.out.println("登陆失败,提示用户重新注册");
        }

        //打印一下从前端取来的数据,看是否取到
        System.out.println(username);
        System.out.println(password);
    }
}
  • 配置web.xml
<servlet>
     <servletname>ServletTest04</servlet-name>
     <servletclass>com.muhan.servlet.ServleTest04</servlet-class>
</servlet>
    
<servlet-mapping>
     <servlet-name>ServletTest01</servlet-name>
     <url-pattern>/servlet.do</url-pattern>
</servlet-mapping>
  • 测试
  • 看后台打印结果
登陆成功,转到成功页面
张三
123456
③Request实现请求转发
  • 前端页面1
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>注册</title>
</head>
<body>
    
<h1>注册</h1>

<form action="${pageContext.request.contextPath}/q4.do" method="post">
  用户名:<input type="text" name="username"><br>
  密码:<input type="password" name="password"><br>
  <input type="submit">
  <input type="reset"><br>
</form>
</body>
</html>
  • 前端页面2
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Success!!!</h1>
</body>
</html>
  • servlet代码
package com.muhan.servlet;

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

public class ServletTest05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //转发到成功页面
        req.getRequestDispatcher("/success.jsp").forward(req,resp);
    }
}
  • web.xml配置
<servlet>
    <servlet-name>ServletTest05</servlet-name>
    <servlet-class>com.muhan.servlet.ServletTest05</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ServletTest05</servlet-name>
    <url-pattern>/q4.do</url-pattern>
</servlet-mapping>
  • 测试
7.转发和重定向的区别
  • 重定向:服务器告诉客户端,你去请求另一个地址.
  • 属于客户端行为
  • resp.sendRedirect();响应的方法
  • 地址栏会变
  • 不可以携带参数
  • 转发:服务器自己转发到另一个请求
  • 属于服务器行为
  • req.getRequestDispatcher().forward(req,resp);请求的方法
  • 地址栏不会变
  • 可以携带参数