学会Request请求,吃透这篇足够

前言

备注:该技术博客的内容是我根据技术视频整理与总结的(并非复制粘贴)。原视频源于黑马JavaWeb课程

一、Request原理

首先,我们要掌握request和response对象的原理

 1.request和response对象是由服务器创建的。我们来使用他们呢
 2.request对象是来获取请求消息,response对象是来设置响应消息

这样才能更好地指导这两个对象怎么去学习,他们是做什么的。我们通过画图的方式来讲解:
学会Request请求,吃透这篇足够_第1张图片

首先,请求会携带请求消息找demo1资源,可以找到
因为我们在服务器端有一个Servlet配置的urlpatten是/demo1 	(@WebServlet(“/demo1”))
所以找到了这个类,然后Tomcat会自动执行service方法

我们聊聊这个过程:
1.Tomcat服务器会根据请求url中的资源路径(/demo1)去创建对应的SerlvetDemo1对象
2.Tomcat服务器会创建两个对象,分别是request和response对象。request对象中封装请求消息数据
3.tomcat将request和response两个对象传递service方法,并且去调用service方法
4.我们可以来操作通过request对象获取请求消息数据,可以通过response对象设置响应消息数据
5.服务器在给浏览器做出响应之前会从response对象中去拿程序员设置的响应消息数据

接下来,我们来学request对象获取请求消息
但是学习它之前我们先说一说request继承体系结构

二、Request继承体系结构

ServletRequest				--接口
		|	继承关系
HttpServlet Request			--接口
		|	实现关系
org.apache.catalina.connector.RequestFacade

org.apache.catalina.connector.RequestFacade是一个类,实现了HTTPServlet接口
这个类是Tomcat编写的,Tomcat将来通过这个类来创建Request对象,并且传递给service方法。

三、Request对象的功能

获取请求消息数据

  1. 获取请求行数据
请求行:
GET /day14/demo1?name=zhangsan HTTP/1.1

获取数据方法:
1.获取请求方式:GET
String getMehtod()

2.获取虚拟目录(重点掌握):/day14
String getContextPath()

3.获取Servlet路径:/demo1
String getServletPath()

4.获取get方式的请求参数:name=zhangsan
String getQueryString()

5.获取请求的URI(重点掌握):/day14/demo1
String getRequestURI(): /day14/demo1
StringBuffer getRequestURL(): http://localhost/day14/demo1

URL:统一资源定位符	http://localhost/day14/demo1  (相当于中华人民共和国)
URI:统一资源标识符	/day14/demo1	(相当于共和国)

6.获取协议及版本: HTTP/1.1
String getProtocol()

7.获取客户机的IP地址:
String getRemoteAddr()

代码演示:

package cn.itcast.web.request;

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 javax.swing.*;
import java.io.IOException;

/**
 * 演示Request对象获取请求行数据
 */

@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

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

        //1.获取请求方式:
        String method = request.getMethod();
        System.out.println(method);
        //2.获取虚拟目录(重点掌握):
        String contextPath = request.getContextPath();
        System.out.println(contextPath);
        //3.获取Servlet路径:
        String servletPath = request.getServletPath();
        System.out.println(servletPath);
        //4.获取get方式的请求参数:
        String queryString = request.getQueryString();
        System.out.println(queryString);
        //5.获取请求的URI(重点掌握):
        String requestURI = request.getRequestURI();
        StringBuffer requestURL = request.getRequestURL();
        System.out.println(requestURI);
        System.out.println(requestURL);
        //6.获取协议及版本:
        String protocol = request.getProtocol();
        System.out.println(protocol);
        //7.获取客户机的IP地址:
        String remoteAddr = request.getRemoteAddr();
        System.out.println(remoteAddr);
    }
}

输出结果如下:

GET
/day14
/requestDemo1
name=zhangsan
/day14/requestDemo1
http://localhost/day14/requestDemo1
HTTP/1.1
0:0:0:0:0:0:0:1
  1. 获取请求头数据
获取方法:
1.(重点掌握)String getHeader(String name):通过请求头的名称获取请求头的值
2.Enumeration getHeaderNames():获取所有的请求头名称

代码演示:

package cn.itcast.web.request;

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;

@WebServlet("/requestDemo4")
public class RequestDemo4 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //演示获取请求头数据:referer
        String referer = request.getHeader("referer");
        System.out.println(referer);//http://localhost/day14/login.html

        //防盗链
        if (referer != null){
            if (referer.contains("/day14")){
                //正常访问
                System.out.println("播放电影...");
            }else{
                //盗链
                System.out.println("想看电影吗?来优酷吧....");
            }
        }
    }
}


  1. 获取请求体数据
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数

获取请求体步骤:
1.获取流对象
BufferedReader getReader():获取字符输入流,只能操作字符数据 (此博客演示这个方法)
ServletInputSream getInputStream():获取字节输入流,可以操作任何类型数据(在文件上传知识点后讲解)

2.再从流对象中拿数据

代码展示:

package cn.itcast.web.request;

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.BufferedReader;
import java.io.IOException;

@WebServlet("/requestDemo5")
public class RequestDemo5 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取请求消息体--请求参数
        //1.获取字符流
        BufferedReader br = request.getReader();
        //2.读取数据
        String line = null;
        while ((line = br.readLine()) != null){
            System.out.println(line);
        }
    }

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

    }
}

四、其他功能

  1. 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方式方法来获取请求参数。
1.String getParameter(String name):根据参数名称获取参数值	(常用)
2.String[] getParameterValues(String name):根据参数名称获取数值的数组 
3.Enumeration getParameterNames():获取所有请求的参数名称
4.Map getParameterMap():获取所有参数的map集合	(常用)

代码演示这四个方法:

第一个方法:

@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //post 获取请求参数
        //根据参数名称获取参数值
        String username = request.getParameter("username");
        System.out.println("post");
        System.out.println(username);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //get 获取请求参数
        /*//根据参数名称获取参数值
        String username = request.getParameter("username");
        System.out.println("get");
        System.out.println(username);*/
        this.doPost(request,response);
    }
}


================================================================================
第二个方法:

@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //post 获取请求参数
        //根据参数名称获取参数值
        String username = request.getParameter("username");
       /*System.out.println("post");
        System.out.println(username);*/

        //根据参数获取参数值的数组
        String[] hobbies = request.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //get 获取请求参数
        /*//根据参数名称获取参数值
        String username = request.getParameter("username");
        System.out.println("get");
        System.out.println(username);*/
        this.doPost(request,response);
    }
}


================================================================================
第三个方法:

@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //post 获取请求参数
        //根据参数名称获取参数值
        String username = request.getParameter("username");
       /*System.out.println("post");
        System.out.println(username);*/

        //根据参数获取参数值的数组
        String[] hobbies = request.getParameterValues("hobby");
        /*for (String hobby : hobbies) {
            System.out.println(hobby);
        }*/

        //获取所有请求的参数名称
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            System.out.println(name);
            String value = request.getParameter(name);
            System.out.println(value);
            System.out.println("------------------------------------");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //get 获取请求参数
        /*//根据参数名称获取参数值
        String username = request.getParameter("username");
        System.out.println("get");
        System.out.println(username);*/
        this.doPost(request,response);
    }
}


================================================================================
第四个方法:

@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //post 获取请求参数
        //根据参数名称获取参数值
        String username = request.getParameter("username");
       /*System.out.println("post");
        System.out.println(username);*/

        //根据参数获取参数值的数组
        String[] hobbies = request.getParameterValues("hobby");
        /*for (String hobby : hobbies) {
            System.out.println(hobby);
        }*/

        //获取所有请求的参数名称
        Enumeration<String> parameterNames = request.getParameterNames();
        /*while (parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            System.out.println(name);
            String value = request.getParameter(name);
            System.out.println(value);
            System.out.println("------------------------------------");*/

        //获取所有参数的map集合
        Map<String, String[]> parameterMap = request.getParameterMap();
        //遍历
        Set<String> keyset = parameterMap.keySet();
        for (String name : keyset) {
            //根据键获取值
            String[] values = parameterMap.get(name);
            System.out.println(name);
            for (String value : values) {
                System.out.println(value);
            }
            System.out.println("-----------------------");
        }
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //get 获取请求参数
        /*//根据参数名称获取参数值
        String username = request.getParameter("username");
        System.out.println("get");
        System.out.println(username);*/
        this.doPost(request,response);
    }
}

  1. 请求转发:一种在服务器内部的资源跳转方式
1.步骤:
	1.通过request对象来获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
	2.使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)

2.特点:
	1.浏览器地址栏路径不发生变化
	2.只能转发到当前的服务器内部资源中
	3.转发是一次请求

代码演示:

//RequestDemo8类
@WebServlet("/requestDemo8")
public class RequestDemo8 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo8888被访问了...");
        //转发到demo9资源
        /*RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestDemo9");
        requestDispatcher.forward(request,response);*/

        request.getRequestDispatcher("/requestDemo9").forward(request,response);
    }


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

        this.doPost(request,response);
    }
}
=========================================================================================
//RequestDemo9类
@WebServlet("/requestDemo9")
public class RequestDemo9 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo9999被访问了...");
    }


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

        this.doPost(request,response);
    }
}

  1. 共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据。
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据

方法:
	1.void setAttribute(String name,Object obj):存储数据
	2.Object getAttribute(String name):通过键获取值
	3.void remove Attribute(String name):通过键移除键值对

代码演示:

//RequestDemo8类
@WebServlet("/requestDemo8")
public class RequestDemo8 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo8888被访问了...");
        //转发到demo9资源
        /*RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestDemo9");
        requestDispatcher.forward(request,response);*/

        //存储数据到request域中
        request.setAttribute("msg","hello");

        request.getRequestDispatcher("/requestDemo9").forward(request,response);
        /*request.getRequestDispatcher("http://www.itcast.cn").forward(request,response);*/
    }


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

        this.doPost(request,response);
    }
}
=========================================================================================
//RequestDemo9类
@WebServlet("/requestDemo9")
public class RequestDemo9 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取数据
        Object msg = request.getAttribute("msg");
        System.out.println(msg);

        System.out.println("demo9999被访问了...");
    }


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

        this.doPost(request,response);
    }
}

  1. 获取ServletContext对象(有个印象即可)
1.ServletContext getServletContext()

代码如下:

@WebServlet("/requestDemo10")
public class RequestDemo10 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        ServletContext servletContext = request.getServletContext();
        System.out.println(servletContext);
    }


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

        this.doPost(request,response);
    }
}

五、解决中文乱码问题:

get方式:tomcat8以上的版本已经将get方式乱码问题解决了

post方式:会乱码
解决:在获取参数前,设置request的编码		request.setCharacterEncoding("urf-8");

代码演示如下:


@WebServlet("/requestDemo7")
public class RequestDemo7 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.设置流的编码
        request.setCharacterEncoding("utf-8");


        //获取请求参数username
        String username = request.getParameter("username");
        System.out.println(username);

    }


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

        this.doPost(request,response);
    }
}

你可能感兴趣的:(java,servlet,http,tomcat,httpwebrequest)