Servlet_Request(请求)

Strvlet_Request

什么是HttpServletRequest对象

这是一个接口,有Tomcat去实现,由Tomcat去实例化,并且通过doGet方法或doPost方法传入,就代表请求对象

请求的方法:与请求行有关的方法

需求:

创建一个RequestLineServlet,用于获取请求行中相关信息的方法,并且输出到网页上。

代码
package com.itheima.demo1;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
//@WebServlet可以直接指定Servlet的访问地址
@WebServlet("/demo2")
public class Demo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
//        out.print("<h1>你好,我是注解Servlet</h1>");
        //获取是GET请求还是POST请求
        String method = request.getMethod();
        out.print("请求方式:"+method+"<br/>");
        //获取访问地址URI
        String requestURI = request.getRequestURI();
        out.print("URI的地址:"+requestURI+"<br/>");
        //获取URL的地址
        StringBuffer requestURL = request.getRequestURL();
        out.print("URL地址"+requestURL+"<br/>");
        //获取协议和版本
        String protocol = request.getProtocol();
        out.print("协议和版本"+protocol+"<br/>");
        //获取地址栏?后面的内容
        String queryString = request.getQueryString();
        out.print("地址栏后面的参数"+queryString+"<br/>");
        //获取当前服务器项目的访问地址 (重点掌握)
        String contextPath = request.getContextPath();
        out.print("服务访问地址:"+contextPath+"<br/>");
        //回去当前项目的访问地址 (重点掌握)
        String servletPath = request.getServletPath();
        out.print("当前servlet的访问地址:"+servletPath);
    }

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

效果:

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fueoNArQ-1593331102887)(img\Snipaste_2020-06-24_13-21-55.png)]

小结:
HttpServletRequest对象的方法功能描述
String getMethod()获取请求的方式
String getRequestURI()得到URI,短
StringBuffer getRequestURL()得到URL,长
String getProtocol()得到协议和版本
String getQueryString()获得查询字符串
String getContextPath()获取当前服务器真实路径(重点)
String getServletPath()获取当前Servlet的方位地址(重点掌握)

请求的方法:与请求头有关的方法

请求头是由多个键值对组成:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rsdFTKe7-1593331102888)(C:\Users\wucn\Desktop\每日学习总结\线下\java_web\Servlet\img\Snipaste_2020-06-24_14-35-21.png)]

Enumeration接口的方法

在这里插入图片描述

需求
  1. 得到user-agent请求头的值
  2. 得到所有的请求头信息,并输出所有的请求值信息
代码
package com.itheima.demo1;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

@WebServlet("/demo03")
public class Demo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        //获取请求头中host的值
        String host = request.getHeader("Host");
        out.print("host的值是:"+host+"<br/>");
        //获取素有请求头中的值
        Enumeration<String> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String s = headerNames.nextElement();//获取的键
            String header = request.getHeader(s);//通过键获取值
            out.print("请求头中的键是:"+s+" 值是:"+header+"<br/>");
        }
    }

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

效果

在这里插入图片描述

请求方法功能
String getHeader(String headName)通过请求头中的键,获取请求头的值
Stirng getHeader(“referer”)可以获取上一次访问地址
Enumeration<String> getHeaderNames()获取请求头中所有的键 (类似迭代器)
Enumeration接口方法说明
boolean hasMoreElements()判断是否还有下一个元素,如果有返回true
String nextElement1.获取当前元素 2.向下移动一个元素

请求头案例:防盗链

流程

原理:获取上一个页面的地址,如果是我们自己网站的指定网页,就可以下载,否则不允许下载。

  1. 如何获取上一个页面的地址,使用请求头:referer
  2. 判断这个页面是不是我们指定的下载页面,如果是正常下载,否则不允许下载

在这里插入图片描述

代码
package com.itheima.servlet;

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

/**
 * 检查下载前的来源地址
 */
@WebServlet("/demo3")
public class Demo3CheckServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        //1.获取上一个页面地址
        String referer = request.getHeader("referer");
        //2.判断这个地址是否是指定的页面
        if(referer.equals("http://localhost:8080/day09_request_war_exploded/demo01.html")) {
            out.print("可以下载");
        }
        //3.如果是就可以下载,否则就不能下载
        else {
            out.print("您是非法的用户不能下载");
        }
    }

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

在这里插入图片描述

请求的方法:得到浏览器提交的参数值

方法名描述
String getParameter(String name)通过参数名获取一个参数值
String[] getParameterValues(String name)通过参数名得到一组参数值,并且返回字符串数组
Map<String,String[]> getParameterMap()获取所有的参数名和值,返回Map对象 键是参数名,值是字符串数组
案例

需求:

  1. 通过上面的方法得到注册页面的用户名和性别,输出到浏览器
  2. 得到所有的爱好,输出到浏览器
  3. 得到所有表单的名字和值,输出到浏览器
  4. 得到封装好的表单数据Map对象,输出到浏览器

注:页面上name是给服务器使用的,id是给浏览器使用的,服务器通过name属性获取参数值

代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>这是登录页面</title>
</head>
<body>
<h2>用户注册</h2>
<form action="demo5" method="get">
    <!--页面上name是给服务器使用的,id是给浏览器使用的,服务器通过name属性获取参数值 -->
    用户名: <input type="text" name="user"><br/>
    性别: <input type="radio" name="gender" value="" checked="checked"/><input type="radio" name="gender" value=""/><br/>
    城市:
    <select name="city">
        <option value="广州">广州</option>
        <option value="深圳">深圳</option>
        <option value="珠海">珠海</option>
    </select>
    <br/>
    爱好:
    <input type="checkbox" name="hobby" value="上网"/>上网
    <input type="checkbox" name="hobby" value="上学"/>上学
    <input type="checkbox" name="hobby" value="上车"/>上车
    <input type="checkbox" name="hobby" value="上吊"/>上吊
    <br/>
    <input type="submit" value="注册"/>
</form>
</body>
</html>

Servlet代码

package com.itheima.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Map;

/**
 * 得到POST请求体或GET地址栏上参数
 */
@WebServlet("/demo5")
public class Demo5ParamServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        out.print("您的注册信息如下:<hr/>");
        //获取姓名和性别,参数字符串常量是表单项的name属性值。这个方法只能通过参数名得到一个参数值
        String name = request.getParameter("user");
        String gender = request.getParameter("gender");
        out.print("用户名:" + name + "<br/>");
        out.print("性别:" + gender + "<br/>");

        //得到所有的爱好,输出到浏览器。如果想通过一个参数名得到一组参数值,使用以下方法。返回字符串数组
        String[] hobbies = request.getParameterValues("hobby");
        out.print("爱好是:" + Arrays.toString(hobbies) + "<hr/>");  //将数组转成字符串

        //一次得到所有的参数名和值(键和值),返回的是map对象,键是参数名,值就是值,值是一个String数组
        Map<String, String[]> parameterMap = request.getParameterMap();
        //输出map的键和值
        parameterMap.forEach((k, v) -> out.print("键:" + k + ",值:" + Arrays.toString(v) + "<br/>"));
    }

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

在这里插入图片描述

请求域有关的方法

什么是作用域

用户不同的Servlet之间或不同请求或不同的用户之间共享数据。数据结构是Map结构:键和值组成

键是字符串类型,值是Object类型

作用域分类
作用域范围
请求域(request)范围最小,一次请求结束就丢失
会话域(Session)一个用户的所有请求都可以使用
上下文域(Context)所有用户所有的请求都可以使用
增删该查的方法
方法作用
void setAttribute(“key”,value);往作用域中添加一个数据
如果数据不存在就是添加,如果数据存在就是修改
Object getAttribute(“key”);根据key获取value,返回的是Object类型
void removeAttribute(“key”);根据key删除value
图解

在这里插入图片描述

代码
package com.itheima.demo1;

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

@WebServlet("/one")
public class Demo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //往请求域中添加一个user
        request.setAttribute("user","张三");
        request.setAttribute("age",18);

        //修改user的名字为李四
        request.setAttribute("user","李四");
        //获取出姓名和年龄的数据
        String user = (String)request.getAttribute("user");
        int age = (int)request.getAttribute("age");
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("姓名: "+user+" 年龄:"+age);

    }

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

在这里插入图片描述

页面跳转:转发

疑问
  • 能否在OneServlet中保存值到请求域中,在另一个TwoServlet中打印出来?
不能,应为访问oneServlet是一次请求,访问twoServlet又是另外一个请求,不是同一个请求,所以不能访问
可以通过转发的方式,让一次请求同时经过多个Servlet,从而可以在第二个Servlet中获取请求域中的数据
转发与重定向的作用

它们在浏览器端看到功能是相同的,都可以实现页面跳转。

转发:是在服务器内部进行页面的跳转,浏览器地址栏是不会发生改变

重新向:是在浏览器端进行页面跳转的,浏览器地址栏是会发生改变

什么是转发

原理图:
在这里插入图片描述
转发的方法

//往请求域中添加一个user
        request.setAttribute("user","张三");
        request.setAttribute("age",18);
       //转发   request.getRequestDispatcher("two")获得转发器,forward(request,response);进行转发将请求对象和响应对象传给two
        request.getRequestDispatcher("two").forward(request,response);
案例
需求

​ 实现从OneServlet中转发到TwoServlet

步骤
  1. OneServlet向请求域中添加了一个键和值,转发给TwoServlet
  2. TwoServlet就从请求域中取出键和值,打印到浏览器上。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dB1KDqex-1593331102898)(img\Snipaste_2020-06-24_17-04-56.png)]

oneServlet代码
package com.itheima.demo1;

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

@WebServlet("/one")
public class Demo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //往请求域中添加一个user
        request.setAttribute("user","张三");
        request.setAttribute("age",18);
       //转发
        request.getRequestDispatcher("two").forward(request,response);


    }

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

twoServlet代码
package com.itheima.demo1;

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

@WebServlet("/two")
public class Demo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        //从请求域中获取内容
        String user =(String) request.getAttribute("user");
        int age = (int) request.getAttribute("age");
        //打印到浏览器中
        out.print("姓名:"+user+" 年龄:"+age);

    }

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

效果

在这里插入图片描述

转发特点:
  1. 地址栏:不会发生变化,显示的还是上一个Servlet的地址
  2. 请求次数:只有1次请求
  3. 请求域中数据没有丢失的

转发使用的方法:

request.getRequestDisPacher("要转发到的页面或服务器").forward(request,response)

页面跳转:重定向

什么是重定向

由浏览器进行的页面跳转,称为重定向,功能与js中的location.href相同

原理图

在这里插入图片描述

重定向的方法
//重定向
response.sendRedirect(request.getContextPath()+"/two");
重定向案例
需求

从OneServlet重定向到TwoServlet

步骤
  1. 在OneServlet中向请求域中添加键和值
  2. 使用重定向到TwoServlet,在TwoServlet中看能否取出请求域的值
oneServlet代码
package com.itheima.demo1;

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

@WebServlet("/one")
public class Demo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //往请求域中添加一个user
        request.setAttribute("user","张三");
        request.setAttribute("age",18);
       //转发
       // request.getRequestDispatcher("two").forward(request,response);
        response.sendRedirect(request.getContextPath()+"/two");

    }

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

twoServlet代码
package com.itheima.demo1;

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

@WebServlet("/two")
public class Demo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        //从请求域中获取内容
        String user =(String) request.getAttribute("user");
        //打印到浏览器中
        out.print("姓名:"+user);

    }

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

效果

在这里插入图片描述

重定向的特点:
  1. 地址栏:发生了变化,显示的是新的地址
  2. 请求次数:2次请求

在这里插入图片描述

  1. 请求域中的数据:丢失了,因为不是同一次请求
小结:重定向和转发的区别
区别转发forward()重定向sendRedirect()
哪个对象requestresponse
地址栏是否发生变化不变变化
哪一端进行的跳转服务器端浏览器端
请求域中数据是否会丢失不会
几次请求1次2次请求
根目录地址http://localhost:8080/项目地址/ 包含了项目访问地址http://localhost:8080/ 不包含项目访问地址
跳转的网站只能跳转到同一个项目的地址可以跳转到其它任意的地址
//写成一句,地址:http://localhost:8080/day09_request_war_exploded/two
//request.getRequestDispatcher("/two").forward(request, response);

//使用重定向,地址:http://localhost:8080/two
response.sendRedirect(request.getContextPath() + "/two");  //加上项目访问地址
//写成一句,地址:http://localhost:8080/day09_request_war_exploded/two
//request.getRequestDispatcher("/two").forward(request, response);

//使用重定向,地址:http://localhost:8080/two
response.sendRedirect(request.getContextPath() + "/two");  //加上项目访问地址
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值