Request对象及其API应用实操

用户的浏览器往服务器端发送数据的时候,把传送的数据都放在Request对象中进行封装,到服务器端的Servlet代码中就需要使用Request把数据提取出来

Request对象

在Java端通过Request对象获取用户浏览器传来的数据,负责获取客户端的请求数据。Request对象是客户端向服务器发出请求,包括客户端提供的信息和一些服务器的信息,比如说我们在客户端通过HTML网页或者网页地址超链接提供的一些键值对信息,通过Request就可以获取出来。

  • 以下是Request对象获取请求行
methodreturndescribe
getMethod()String获取提交的方式
getRequestURI()String获取请求的参数,请求服务器相对路径
getRequestURL()StringBuffer获取请求的参数,请求服务器绝对路径
getQueryString()String获取请求行 ?后面的参数 (GET)
getContextPath()String获取WEB应用名称

URI:统一资源标识符
URL:统一资源定位器

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;

/**
 * Request对象获取请求行
 *
 * @author 18147
 */
@WebServlet("/line")
public class LineServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //因为运行时调用的是doGet方法,所以所有演示代码都在doGet函数中编写
        //实际操作时,两种方法也是相互调用关系,只需写一个即可
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取提交的方式
        //getMethod()获取客户端的请求⽅式
        String method = request.getMethod();
        System.out.println("method = " + method);

        //获取请求的参数,获取请求的服务器路径
        String uri = request.getRequestURI();//uri是相对路径
        StringBuffer url = request.getRequestURL();//url是从http协议开始的绝对路径
        System.out.println("uri = " + uri);
        System.out.println("url = " + url);

        //获取请求行?之后的参数
        String queryString = request.getQueryString();
        System.out.println("queryString = " + queryString);

        //获取当前web项目访问地址
        String contextPath = request.getContextPath();
        System.out.println("contextPath = " + contextPath);

    }
}

在这里插入图片描述

修改方案:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
成功!!!

Request对象获取请求头

请求头数据格式键值对: k:v
在这里插入图片描述
用浏览器举例:每当用户发出一条请求的时候(例如说刷新界面),浏览器就会把请求头中所有的键值对信息通过Request对象传到Servlet中,然后在Servlet中再通过Request对象把所有请求头获取出来

methodreturndescription
getHeader(String name)String获得⼀个key对应⼀个value的请求头
getHeaderNames()enum获得所有请求头的键

测试上述两种API
在这里插入图片描述

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;

/**
 * @author 18147
 * 举例:用Host键值对来测试通过key值来返回指定value值
 * 举例:
 */
@WebServlet("/head")
public class HeadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //因为运行时调用的是doGet方法,所以所有演示代码都在doGet函数中编写
        //实际操作时,两种方法也是相互调用关系,只需写一个即可
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取指定key的请求头信息

        String header = request.getHeader("Host");
        System.out.println("Host : " + header);
        //获取所有请求头的key

    }
}

在这里插入图片描述

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.util.Enumeration;

/**
 * @author 18147
 */
@WebServlet("/head")
public class HeadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //因为运行时调用的是doGet方法,所以所有演示代码都在doGet函数中编写
        //实际操作时,两种方法也是相互调用关系,只需写一个即可
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取指定key的请求头信息
        String header = request.getHeader("Host");
        System.out.println("Host : " + header);
        //获取所有请求头的key(枚举类型)
        /*
* Enumeration getHeaderNames() 获取所有的请求头的键
* 返回值Enumeration接⼝ (向量枚举)
* 集合:1.0-1.1 Enumeration 集合1.2 迭代器
* Iterator迭代器接⼝: hasNext() next()
* Enumeration接⼝: hasMoreElement() nextElement()
*/
        Enumeration<String> headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()){//如果请求头中还有key
            String key = headerNames.nextElement();//获取键
            String values = request.getHeader(key);//通过当前的键来确定对应的值,和第一个API的效果一样
            System.out.println(key +" = "+values);//输出测试
        }
    }
}

在这里插入图片描述

😈Request获取请求参数

methodreturndescription
getParameter(表单中的name值)String获得提交的参数(⼀个name对应⼀个value)
getParameterValues(表单中的name值)String[]获得提交的参数(⼀个name对多个value)
getParameterMap()Map<String,String[]>获得提交的参数,将提交的参数名称和对应值存⼊到⼀个Map集合中

首先建立一个页面的框架,新建一个html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/param" method="get">
    ⽤户名:<input type="text" name="username"><br/>
    密 码:<input type="password" name="password"><br/>
    爱 好:<input type="checkbox" name="hobby" value="Basketball">篮球
    <input type="checkbox" name="hobby" value="football">⾜球
    <input type="checkbox" name="hobby" value="pingpang">乒乒球
    <br/>
    <input type="submit">
</form>
</body>
</html>
  1. getParameter()

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

  1. getParameterValues()

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

  1. getParameterMap()

在这里插入图片描述
总代码:

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.util.Arrays;
import java.util.Map;

@WebServlet("/param")
public class ParamsServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);//两个用同一套方式
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取浏览器提交的参数(一个name对应一个值的情况)
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println("username = "+username);
        System.out.println("password = "+password);

        //获取浏览器提交的参数(一个name对应多个值的情况)
        String[] hobbies = request.getParameterValues("hobby");//提供给的html界面只有hobby一项是对应多个值的
        System.out.println("hobby = "+ Arrays.toString(hobbies));

        //获取浏览器提交的参数(将提交的参数名称和参数值存入到一个Map集合当中)
        Map<String, String[]> map = request.getParameterMap();
        for (Map.Entry entry : map.entrySet()){
            Object key = entry.getKey();
            String[] value =(String[]) entry.getValue();
            System.out.println(key+"-----------"+Arrays.toString(value));
        }
    }
}

Request对象接收表单请求参数的中文乱码处理

method为get时就算输入中文也不会出现乱码的问题,但是当我们调用post方法的时候中文乱码的问题就出现了

  • 产生乱码的原因:
    post方式提交的数据是在请求体中,request对象接收到数据之后,放入request的缓冲区中。缓冲区默认编码格式为ISO-8859-1,不支持中文

下面是已经将method改为post的html
在这里插入图片描述
可以看到下面中文部分已经变成了乱码
在这里插入图片描述
处理办法就是在doGet函数获取参数之前写入下面这条语句(将request的缓冲区的编码修改了即可):

protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
//将request的缓冲区的编码修改
request.setCharacterEncoding("utf-8");
//获取请求参数
String user = request.getParameter("user");
System.out.println("user = " + user);
}

之后再进行其他操作

在这里插入图片描述
中文乱码问题已经解决!!!

get方法写入中文
Tomcat8.5以及之后的版本会自动解决中文乱码问题,但是以前的版本不确定,如果和post方法同样出现了中文乱码问题和上面一样办法解决

  • 生成乱码原因:
    get方式提交的数据在请求行的url后面,在地址栏上其实就已经进行了一次URL的编码了
  • 解决方案:
    将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
/*
get⽅式提交的数据在 请求⾏中
Tomcat8.5之后, Tomcat⾃动处理了get请求的中⽂乱码问题, 但在之前的Tomcat版本
中,get请求的中⽂乱码需要⾃⾏处理
⽼版本Tomcat中⽂乱码的解决:将存⼊到request缓冲区中的值以ISO-8859-1的⽅式获取
到,以UTF-8的⽅式进⾏解码。
*/
String user = request.getParameter("username");
//将存⼊到request缓冲区中的值以ISO-8859-1的⽅式获取到
//把给到的ISO-8859-1的数据拆开,按utf-8的格式拼装起来
byte[] bytes = user.getBytes("iso-8859-1");
//以UTF-8的⽅式进⾏解码
String value = new String(bytes, "utf-8");
System.out.println("user = " + user);
}

Request域对象

浏览器发送请求给服务器的Servlet,Servlet处理完Java代码后通过Response响应对象把结果返回给浏览器
在这里插入图片描述
Request作为域对象的API
Request对象就是从客户端浏览器向服务器发送的一次请求信息的封装,服务器端的Response响应对象将这些个对象返回给浏览器,实质上Request中所保存的数据有效期也是一次请求范围(从客户端浏览器服务器发送⼀次请求,服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,通过Response对象将处理后的数据返回给浏览器客户端响应,当用户响应了返回数据后,Request和Response对象就销毁了,保存在其中的数据就无效了),也就是一次请求响应的闭环区间。

methodreturndescription
setAttribute(String name, Object obj)void向Request域中保存数据
getAttribute(String name)Object从Request域中获取数据
removeAttribute(String name)void从Request域中移除数据

在一个包下创建两个Servlet,测试API使用

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;

/**
 * @author 18147
 */
@WebServlet("/my")
public class MyServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //存数据到Request域对象
        request.setAttribute("key","value");
        //从Request域对象中取出数据
        Object value = request.getAttribute("key");
        System.out.println("MyServlet == "+value);
    }
}
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;

/**
 * @author 18147
 */
@WebServlet("/my2")
public class My2Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //从Request域对象中取出数据
        Object value = request.getAttribute("key");
        System.out.println("MyServlet == "+value);
    }
}

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

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

Request域对象实际应用——请求、转发

首先从客户端浏览器发送一个请求到服务器中的Servlet1,在服务器内部进行转发,将请求的数据由Servlet1转发给Servlet2,最后给客户端浏览器响应回结果。

转发的作用:之前创建的两个Servlet文件
在这里插入图片描述
请求转发API了解

methodreturndescription
getRequestDispatcher(String path)RequestDispatcher通过ServletRequest对象获得RequestDispatcher对象
forward(ServletRequest request, ServletResponse response)void根据RequestDispatcher中的方法进行请求转发

在之前的代码基础上添加转发功能

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;

/**
 * @author 18147
 */
@WebServlet("/my")
public class MyServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //存数据到Request域对象
        request.setAttribute("key", "value");
        //从Request域对象中取出数据
        Object value = request.getAttribute("key");
        System.out.println("MyServlet == " + value);

        //请求转发给Servlet2
        request.getRequestDispatcher("/my2").forward(request, response);
    }
}

在这里插入图片描述
在这里插入图片描述
这里要强调的是:请求转发操作是不能跨项目操作的,其中forward()方法包含的两个参数实际上就是Myservlet中的,既然是同一个request和response,也没有响应到浏览器中销毁,所以能自动跳转到转发地址“/my2”,并调用其方法。

转发和重定向

在这里插入图片描述
区别总结

  • 请求转发是一次请求一次响应,而重定向是两次请求两次响应。
  • 请求转发地址栏不会变化的,重定向地址栏发生变化。
  • 请求转发路径不带工程名,重定向需要带工程名路径。
  • 请求转发只能在本网站内部,重定向可以定向到任何网站。

如果需要使用request进行值传递,需要通过请求转发完成。
如果页面需要跳转到其他网站上必须使用重定向, 不能使用request进行值传递。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值