动态开发核心-Servlet

 
 
ServletConfig

  1. ServletConfig类是为Servlet程序的配置信息的类
  2. Servlet程序和ServletConfig对象都是由Tomcat负责创建
  3. Servlet程序默认是第1次访问的时候创建,在Servlet程序创建时就创建一个对应的ServletConfig对象

 
ServletConfig类能干什么

  1. 获取Servlet程序的servlet-name的值
  2. 获取初始化参数init-param
  3. 获取ServletContext对象

 
初始化ServletConfig
Tomcat在创建Servlet时,也会创建一个ServletConfig对象

并且在初始化Servlet对象时,将ServletConfig对象(传给Servlet对象时的变量名:config)传给Servlet对象,Servlet对象的父类GenericServlet有一个私有属性:config,因此如果我们在Servlet中重写了init(ServletConfig config)方法,就需要super.init(config),最后父类调用init(ServletConfig config)方法,会将传进来的ServletConfig赋值给自身的config对象

如果在Servlet中只是重写了init()方法,或者没有重写,那么tomcat就会在GenericServlet中执行init(ServletConfig config)

我们在Servlet中使用getServletConfig(),就是继承了父类GenericServlet的方法,将父类的config对象提供给子类使用

API解释
getServletConfig();获取ServletConfig对象
servletConfig.getInitParameter(“xxx”);获取初始化参数xxx
servletConfig.getInitParameterNames();获取初始化参数列表
servletConfig.getServletName();获取ServletName
 
初始化参数配置
在web.xml 中 配置<init-param>
    <servlet>
        <servlet-name>DBServlet</servlet-name>
        <servlet-class>com.study.servlet.DBServlet</servlet-class>
        <!--配置信息,而不是硬编码到程序-->
        <init-param>
            <param-name>username</param-name> //内容名称
            <param-value>zs</param-value>  //内容
        </init-param>
        <init-param>
            <param-name>pwd</param-name>
            <param-value>123</param-value>
        </init-param>
    </servlet>

 
 
ServletContext
ServletContext的作用

  • 解决多个Servlet共享数据的问题,从而实现多个Servlet相互通信
    在这里插入图片描述

ServletContext基本介绍

  1. ServletContext是一个接口,它表示 Servlet 上下文对象(上下文对象:将一堆有用的东西放在一块,如环境变量)
  2. 一个web工程,只有一个ServletContext对象实例
  3. ServletContext对象是在 web工程启动的时候创建,在 web 工程停止时销毁
  4. ServletContext对象可以通过ServletConfig.getServletContext方法获得ServletContext对象,也可以通过this.getServletcontext()来获得其对象的引用。
  5. 由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现多个Servlet间通讯。ServletContext对象通常也被称之为域对象。
    在这里插入图片描述

ServletContext可以做什么

  1. 获取 web.xml中配置的上下文参数 context-param [信息和整个web应用相关,而不是属于某个Servlet]
  2. 获取当前的工程路径,格式: /工程路径
  3. 获取工程部署后在服务器硬盘上的绝对路径(out目录)
  4. 像 Map一样存取数据,多个Servlet共享数据
API解释
getServletContext();
request.getServletContext();
servletConfig.getServletContext();
获取ServletContext()对象
servletContext.getInitParameter(“xxx”);获取在web.xml中配置的上下文参数
servletContext.getContextPath();获取当前工程路径,后面不带 /
servletContext.getRealPath(“/”);获取工程部署后在服务器硬盘上的绝对路径(out目录)
servletContext.getAttribute(“k”);servletContext通过k获得value
servletContext.setAttribute(“k”, value);在servletContext存放k-v值

在web.xml配置 <context-param>

    <context-param>
        <param-name>website</param-name>
        <param-value>http://www.zs.com</param-value>
    </context-param>
    <context-param>
        <param-name>company</param-name>
        <param-value>张三公司</param-value>
    </context-param>

 
 
HttpServletRequest

  1. HttpServletRequest对象代表客户端的请求
  2. 当客户端/浏览器通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中
  3. 通过这个对象的方法,可以获得客户这些信息。

 
HttpServletRequest常用方法

API解释
getRequestURI()获取请求的资源路径
/servlet/loginServlet
getRequestURL()获取请求的统一资源定位符(绝对路径)
http://localhost:8080/servlet/loginServlet
getRemoteAddr()获取客户端的主机
setCharacterEncoding(“utf-8”)设置编码
getHeader()
获取请求头
getHeader(“Accept-Language”):获取浏览器支持的语言
可以使用正则表达式来取出请求头中想要的信息
getParameter()获取请求的参数(单选框)
如果没有该参数,返回空串
getParameterValues()获取请求的参数(多个值的时候使用),比如checkbox,返回的数组(多选框)
getMethod()获取请求的方式GET或POST
getContextPath();获取当前工程路径,后面不带 /
setAttribute(key, value)设置域数据
getAttribute(key)获取域数据
getRequestDispatcher(“/servlet名”)获取请求转发对象,请求转发的核心对象
/ 会被解析成http://ip:8080/项目名
 
HttpServletRequest使用细节
  • 获取doPost参数中文乱码解决方案,注意setCharacterEncoding(“utf-8”)要写在request.getParameter()前。

 

请求转发
一个业务需要多个servlet处理,就需要请求转发

请求转发说明

  1. 实现请求转发:请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理
  2. HttpServletRequest对象(也叫Request对象)提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatchet对象,调用这个对象的forward方法可以实现请求转发
  3. request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理
API解释
getAttribute(k)request中取出k对应的value
setAttribute(k,v)request中存放k-v
removeAttribute(k)request中删除对应的k-v
getAttributeNames()取出request所有k
 
实现请求转发
  1. 在servlet01中,处理完数据
  2. 获取分发器 requestDispatcher对象(request.getRequestDispatcher(“/下一个servletName”);
  3. 调用requestDispatcher.forward(request, response);(请求转发使用的都是同一个request和response,达到多个servlet数据共享的效果)
        //获取分发器
        //  1. /manageServlet写的是要转发的servlet的url
        //  2. / 会被解析成/servlet
        //  3. 3. forward(request, response)表示把当前servlet的request对象和response对象,传递给下一个Servlet使用
        RequestDispatcher requestDispatcher
                = request.getRequestDispatcher("/manageServlet");

        requestDispatcher.forward(request, response);
    }

 
请求转发流程

  1. 浏览器向tomcat发出请求
  2. tomcat接收到请求后,通过web.xml定位到访问的Servlet01
  3. 在Servlet01处理完数据后,会得到一个分发器,并返回到tomcat,告诉它需要请求转发
  4. tomcat会将未处理完的数据,继续通过web.xml查找下一个Servlet继续处理,直到数据处理结束
  5. 最后tomcat会将结果封装成http请求返回给浏览器(整个过程,浏览器只会有一次http请求,并且不会因为请求转发而跳转页面)
    在这里插入图片描述

请求转发注意事项

  1. 浏览器地址不会变化(地址会保留在第1个servlet的url)
  2. 在同一次HTTP请求中,进行多次转发,仍然是一次HTTP请求
  3. 在同一次HTTP请求中,进行多次转发,多个Servlet可以共享request域/对象的数据(因为始终是同一个request对象)
  4. 可以转发到WEB-INF目录下(始终都是在服务器由tomcat进行转发操作)
  5. 不能访问当前WEB工程外的资源
  6. 因为浏览器地址栏会停止在第一个servlet ,如果你刷新页面,会再次发出请求(并且会带数据)

 
 
HttpServletResponse

  1. 每次HTTP请求,Tomcat会创建一个HttpServletResponse对象传递给Servlet程序去使用。
  2. HttpServletRequest 表示请求过来的信息,HttpServletResponse表示所有响应的信息,如果需要设置返回给客户端的信息,通过HttpservletResponse对象来进行设置即可
API解释
setStatus设置状态值
setHeader设置响应头
getWriter获取字符流
getOutputStream获得字节流
response.setContentType( “text/ html; charset=utf-8”);设置响应头数据编码
Http会根据Content-Type来处理返回的数据
sendRedirect(“/工程名/servlet名”);请求重定向
/ 解析成 http://ip:8080/
 
向客户端返回数据方法
  1. 字节流getoutputStream();常用于下载(处理二进制数据)
  2. 字符流getWriter();常用于回传字符串
  3. 两个流同时只能使用一个。使用了字节流,就不能再使用字符流,反之亦然,否则就会报错

 
 
请求重定向

  1. 浏览器向tomcat发出http请求
  2. tomcat接收到请求后,通过web.xml发送给对应的Servlet01
  3. Servle01在处理完业务(也可能不处理),指定状态码302,以及重定向的location返回给tomcat
  4. tomcat将状态码和location封装成http请求发送给浏览器
  5. 浏览器再接收到状态码和location后,回再次访问location的地址(此时,浏览器访问的URL地址发生变化)
  6. tomcat接收到请求后,通过web.xml发送给对应的Servlet02
  7. Servle02在处理完业务,将结果返回给tomcat
  8. tomcat在把结果封装成http请求发送给浏览器
    在这里插入图片描述
        //完成自己的业务
        // 发出请求重定向->DownServletNew
        //1. sendRedirect本质就会返回302状态码 Location: /servlet/downServletNew/
        //2. 因此302和/servlet/downServletNew是浏览器解析,而不是服务器
        //3. 浏览器在解析  servlet/downServletNew => http://localhost:8080/servlet/downServletNew
        response.sendRedirect("/servlet/downServletNew");
    }

请求重定向细节

  1. 最佳应用场景:网站迁移
  2. 浏览器地址会发生变化,本质是两次http请求
  3. 不能共享Request域中的数据,木质是两次http请求,会生成两个HttpServletRequest对象
  4. 不能重定向到/WEB-INF下的资源 (WEB-INF是有一个安全机制校验的,浏览器/客户端是不能直接访问)
  5. 可以重定向到Web 工程以外的资源,比如到www.baidu.com
  6. 重定向有两种方式,推荐使用第1种.

重定向到百度

response.sendRedirect("http://www.baidu.com");

 
 

ServletConfig

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
Tomcat在创建Servlet时,也会创建一个ServletConfig对象

并且在初始化Servlet对象时,将ServletConfig对象(传给Servlet对象时的变量名:config)传给Servlet对象,Servlet对象的父类GenericServlet有一个私有属性:config,因此如果我们在Servlet中重写了init(ServletConfig config)方法,就需要super.init(config),最后父类调用init(ServletConfig config)方法,会将传进来的ServletConfig赋值给自身的config对象

如果在Servlet中只是重写了init()方法,或者没有重写,那么tomcat就会在GenericServlet中执行init(ServletConfig config)

我们在Servlet中使用getServletConfig(),就是继承了父类GenericServlet的方法,将父类的config对象提供给子类使用

    <!--配置DBServlet-->
    <servlet>
        <servlet-name>DBServlet</servlet-name>
        <servlet-class>com.study.servlet.DBServlet</servlet-class>
        <!--配置信息,而不是硬编码到程序-->
        <init-param>
            <param-name>username</param-name>
            <param-value>zs</param-value>
        </init-param>
        <init-param>
            <param-name>pwd</param-name>
            <param-value>123</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>DBServlet</servlet-name>
        <url-pattern>/db</url-pattern>
    </servlet-mapping>
package com.study.servlet;

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

/**
 * @author 珀筱
 */
public class DBServlet extends HttpServlet {
    /**
     *
     * 梳理ServletConfig config使用流程
     * 1.当DBServlet对象初始化时,tomcat会同时创建一个ServletConfig对象
     * 2.这时如果DBServlet init()方法中你调用super.init(config);
     * 3.调用父类GenericServlet
     * public void init(ServletConfig config) throws ServletException {
     *      this.config = config;
     *      this.init();
     *    }
     *    这时就会把Tomcat创建的ServletConfig对象赋给GenericServlet的属性 config:
     * 4. 因此如果你重写init()方法,记住如果你想在其它方法通过getServletConfig() 方法获取ServletConfig
     *    则一定要记住调用super.init(config);
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //在DBServlet执行 doGet()/doPost()时,可以获取到web .xml配置的用户名和密码
        //你是一个OOP程序员->现有的方法或对象来搞定
        //DBServlet的父类GenericServlet有getServletConfig()

        /**
         * 1. getServletconfig()方法是GenericServlet
         * 2. 返回的 servletConfig对象是GenericServlet private transient ServletConfig config;
         * 3. 当一个属性被 transient修饰,表示该属性不会被串行化(有些重要信息,不希望保存到文件)
         */
        ServletConfig servletConfig = getServletConfig();
        //获取初始化参数username
        String username = servletConfig.getInitParameter("username");
        //获取初始化参数pwd
        String pwd = servletConfig.getInitParameter("pwd");
        //获取ServletName
        String servletName = servletConfig.getServletName();
        //获取初始化参数列表
        Enumeration<String> initParameterNames = servletConfig.getInitParameterNames();
        System.out.println("初始化参数username: " + username);
        System.out.println("初始化参数pwd: " + pwd);
        while (initParameterNames.hasMoreElements()){
            System.out.println(initParameterNames.nextElement());
        }
        System.out.println("ServletName: " + servletName);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

在这里插入图片描述
 
 

ServletContext

ServletContext的作用

解决多一个Servlet共享数据的问题,从而实现多个Servlet相互通信
在这里插入图片描述

ServletContext基本介绍

在这里插入图片描述
在这里插入图片描述

ServletContext可以做什么

在这里插入图片描述
在这里插入图片描述

获取工程相关信息

在这里插入图片描述

    <servlet>
        <servlet-name>ServletContext_</servlet-name>
        <servlet-class>com.study.servlet.ServletContext.ServletContext_</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletContext_</servlet-name>
        <url-pattern>/servletContext_</url-pattern>
    </servlet-mapping>
    <context-param>
        <param-name>website</param-name>
        <param-value>http://www.zs.com</param-value>
    </context-param>
    <context-param>
        <param-name>company</param-name>
        <param-value>张三公司</param-value>
    </context-param>
package com.study.servlet.ServletContext;

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

/**
 * @author 珀筱
 */
public class ServletContext_ extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletContext servletContext = getServletContext();
        //1. 获取在web.xml中配置的上下文参数
        String website = servletContext.getInitParameter("website");
        Object company = servletContext.getAttribute("company");

        //2. 获取当前工程路径
        //获取项目发布后,真正的工作路径
        String contextPath = servletContext.getContextPath();

        //3.获取项目发布后,正在的工作路径
        // '/' 表示我们的项目(发布后)的根路径D:\idea\JavaWeb\servlet\out\artifacts\servlet_war_exploded\
        String realPath = servletContext.getRealPath("/");

        System.out.println("website= " + website);
        System.out.println("company= " + company);
        System.out.println(contextPath);
        System.out.println(realPath);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

在这里插入图片描述

网站访问次数计数器

在这里插入图片描述
写一个网站工具类

package com.study.servlet.ServletContext;

import javax.servlet.ServletContext;
import java.io.PrintWriter;

/**
 * @author 珀筱
 */
public class WebUtils {
    public static Integer visitCount(ServletContext servletContext) {
        //获取ServletContext
        //从servletContext获取visit_count属性k-v
        Object visit_count = servletContext.getAttribute("visit_count");
        //判断visit_count是否为null
        if (visit_count == null) {
            visit_count = 1;
            servletContext.setAttribute("visit_count", visit_count); //说明是第一个访问
        } else { //是第二次或以上
            //取出visit_count的值+1
            visit_count = Integer.parseInt(visit_count + "") + 1;
            //放回到servletContext
            servletContext.setAttribute("visit_count", visit_count);
        }
        return Integer.parseInt(visit_count + "");
    }
}

PayServlet

package com.study.servlet.ServletContext;

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

/**
 * @author 珀筱
 */
public class PayServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer visit_count = WebUtils.visitCount(getServletContext());
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print("<h1>网站的访问的次数是 " + visit_count + "</h1>");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

OrderServlet

package com.study.servlet.ServletContext;

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

/**
 * @author 珀筱
 */
public class OrderServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Integer visit_count = WebUtils.visitCount(getServletContext());
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print("<h1>网站的访问的次数是 " + visit_count + "</h1>");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

在这里插入图片描述
在这里插入图片描述

HttpServletRequest

HttpServletRequest介绍

在这里插入图片描述

HttpServletRequest常用方法

在这里插入图片描述

package com.study.servlet.request;

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

/**
 * @author 珀筱
 */
public class HttpServletRequestMethods extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //这里我们使用request对象,获取表单提交的各种数据
        System.out.println("HttpServletRequestMethods被调用...");

        /********************************
         * 获取利http请求头相关信息
         **********************************/
        System.out.println("请求的资源路径URI= " + request.getRequestURI());
        System.out.println("请求的统一资源定位符(绝对路径)URL= " + request.getRequestURL());
        System.out.println("请求的客户端ip 地址= " + request.getRemoteAddr());//本地就是127.0.0.1
        //获取http请求头的信息,可以指定其他,比如 User-Agent , Host等待老师就举一个例子
        System.out.println("http请求头HOST= " + request.getHeader("Host"));
        //主要是Get / Post
        System.out.println("http请求方式~= " + request.getMethod());
        //说明,如果我们希望得到请求的头的相关信息,可以使用request.getHeader("请求头字段")
        System.out.println("该请求的发起地址是=" + request.getHeader("Referer"));
        /***********************************
         *  获取和请求参数相关信息,注意要求在返回数据前,获取参数
         *****************************/
        //1.获取表单数据[单个数据]
        //username=zy&pwd=1&hobby=zq
        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        System.out.println(username);
        System.out.println(pwd);
        //2.获取表单一组数据
        String[] hobbies = request.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

HttpServletRequest使用细节

在这里插入图片描述
在这里插入图片描述

        //解决接收参数的中文乱码问题,写在getParameter前
        request.setCharacterEncoding("utf-8");

        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        //返回接收到的信息,给浏览器回复
        //本质就是在http响应头,加上 Content-Type: text/html;charset=utf-8
        //text/plain表示返回的数据,请浏览器使用文本方式解析
        //application/x-tar表示返回的是文件,浏览器就会以下载文件的方式处理
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print("你好世界");
        writer.flush();
        writer.close();

使用正则表达式可以拿到请求头中每个数据
取出用户使用的浏览器

        String user_Agent = request.getHeader("User-Agent");
        String[] s = user_Agent.split(" ");
        String s1 = s[s.length - 1].split("\\/")[0];
        System.out.println(s1);

在这里插入图片描述

package com.study.servlet.HomeWork;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 珀筱
 */
public class VersionServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String userAgent = request.getHeader("User-Agent");
        String regStr = "\\((.*)\\)";
        Pattern compile = Pattern.compile(regStr);
        Matcher matcher = compile.matcher(userAgent);
        matcher.find();//因为我们的userAgent只有一组()
        String group = matcher.group(1);// (Windows NT 10.0; Win64; x64; rv:97.0)system.out.println( "group= " +group);
        System.out.println(group);
        String[] operInfos = group.split("; ");
        System.out.println("操作系统=" + operInfos[0]);
        System.out.println("操作系统的位数=" + operInfos[1]);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

请求转发

一个业务需要多个servlet处理,就需要请求转发
在这里插入图片描述

请求转发说明

在这里插入图片描述

实现请求转发

  1. 浏览器向tomcat发出请求
  2. tomcat接收到请求后,通过web.xml定位到访问的Servlet01
  3. 在Servlet01处理完数据后,会得到一个分发器,并返回到tomcat,告诉它需要请求转发
  4. tomcat会将未处理完的数据,继续通过web.xml查找下一个Servlet继续处理,直到数据处理结束
  5. 最后tomcat会将结果封装成http请求返回给浏览器(整个过程,浏览器只会有一次http请求,并且不会因为请求转发而跳转页面)
    在这里插入图片描述

请求转发实例

在这里插入图片描述
CheckServlet

package com.study.servlet.request;

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

/**
 * @author 珀筱
 */
public class CheckServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("CheckServlet被调用...");
        //根据用户名来判断用户是什么身份
        String username = request.getParameter("username");
        //注意: 如果是同一个request对象(请求转发),那么可以在不同的servlet中,使用getParameter
        if ("tom".equals(username)) {
            //分配
            request.setAttribute("role", "管理员");
        } else {
            request.setAttribute("role", "普通用户");
        }
        //获取分发器
        //  1. /manageServlet写的是要转发的servlet的url
        //  2. / 会被解析成/servlet
        //  3. 3. forward(request, response)表示把当前servlet的request对象和response对象,传递给下一个Servlet使用
        RequestDispatcher requestDispatcher
                = request.getRequestDispatcher("/manageServlet");

        requestDispatcher.forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

ManageServlet

package com.study.servlet.request;

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

/**
 * @author 珀筱
 */
public class ManageServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("ManageServlet被调用...");

        String username = request.getParameter("username");
        String role = (String) request.getAttribute("role");

        //输出信息
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.print("用户名: " + username + "</br>");
        writer.print("角色: " + role);
        writer.flush();
        writer.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

请求转发注意事项

在这里插入图片描述

HttpServletResponse

在这里插入图片描述
在这里插入图片描述

向客户端返回数据注意事项和细节

在这里插入图片描述

请求重定向

  1. 浏览器向tomcat发出http请求
  2. tomcat接收到请求后,通过web.xml发送给对应的Servlet01
  3. Servle01在处理完业务(也可能不处理),指定状态码302,以及重定向的location返回给tomcat
  4. tomcat将状态码和location封装成http请求发送给浏览器
  5. 浏览器再接收到状态码和location后,回再次访问location的地址(此时,浏览器访问的URL地址发生变化)
  6. tomcat接收到请求后,通过web.xml发送给对应的Servlet02
  7. Servle02在处理完业务,将结果返回给tomcat
  8. tomcat在把结果封装成http请求发送给浏览器
    在这里插入图片描述

请求重定向实例

在这里插入图片描述
xml文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>下载文件</title>
</head>
<body>
<h1>下载文件</h1>
<a href="http://localhost:8080/servlet/downServlet">下载电影</a>
</body>
</html>

DownServlet

package com.study.servlet.response;

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

/**
 * @author 珀筱
 */
public class DownServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //完成自己的业务
        // 发出请求重定向->DownServletNew
        //1. sendRedirect本质就会返回302状态码 Location: /servlet/downServletNew/
        //2. 因此302和/servlet/downServletNew是浏览器解析,而不是服务器
        //3. 浏览器在解析  servlet/downServletNew => http://localhost:8080/servlet/downServletNew
        response.sendRedirect("/servlet/downServletNew");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

DownServletNew

package com.study.servlet.response;

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

/**
 * @author 珀筱
 */
public class DownServletNew extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();
        writer.print("hi");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

请求重定向细节

在这里插入图片描述
WEB-INF是有一个安全机制校验的,浏览器/客户端是不能直接访问
重定向到百度

response.sendRedirect("http://www.baidu.com");

动态获取appliaction context

String contextPath = getServletContext().getContextPath();
response.sendRedirect(contextPath + "/downServletNew");

练习

在这里插入图片描述
在这里插入图片描述
pay.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>支付</title>
</head>
<body>
<h1>支付页面</h1>
<!--注意:这里action="/servlet/myPayServlet"的第一/被浏览器解析从浏览器地址栏的主机-->
<form method="post" action="/servlet/myPayServlet">
用户编号: <input type="text" name="username"></br>
支付金额: <input type="text" name="money"></br>
<input type="submit" value="点击支付">
</form>
</body>
</html>

payok.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>支付成功~</h1>
</body>
</html>

webUtils.java

package com.study.servlet.HomeWork;

/**
 * @author 珀筱
 */
public class WebUtils {
    public static int ParseString(String str) {
        //在这里捕获异常,就不会交给tomcat处理(tomcat处理异常就是将异常信息发送给客户端,状态码为500)
        try {
            int num = Integer.parseInt(str);
            return num;
        } catch (NumberFormatException e) {
            return -1;
        }
    }
}

MyPayServlet

package com.study.servlet.HomeWork;

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

/**
 * @author 珀筱
 */
public class MyPayServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String money = request.getParameter("money"); //什么都不输入,返回空串""
        int iMoney = WebUtils.ParseString(money);
        String contextPath = getServletContext().getContextPath();
        if(iMoney >= 100){
            response.sendRedirect(contextPath + "/payok.html");
        } else {
            response.sendRedirect(contextPath + "/pay.html");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值