JavaWeb学习笔记(二):浅谈 request

好记性不如烂笔头,记录学习的过程和内容,望与君共勉!

HTTP

1、概述:Hyper Text Transfer Protocol 超文本传输协议,定义了客户端和服务器端通信时发送数据的格式。

2、特点:
① 基于 TCP/IP 的高级协议
② 默认端口号为 80
③ 基于请求/响应模型的:一次请求对应一次响应
④ 无状态的:每次请求之间相互独立,不能交互数据

3、请求消息的数据格式:
① 请求行:
格式→请求方式 请求url 请求协议/版本

请求方式:HTTP 协议有 7 种请求方式,常用的有 2 种,GET 和 POST。
GET:请求参数在请求行中,在 url 后,请求的 url 长度是有限制的。
POST:请求参数在请求体中,请求的 url 长度是没有限制的。

② 请求头:
客户端浏览器告诉服务器的一些信息
格式→请求头名称 : 请求头值

常见请求头:
1、User-Agent:浏览器告诉服务器,浏览器的版本信息。可以在服务器端获取该头的信息,解决浏览器的兼容性问题。
2、Accept:告诉服务器浏览器可以解析的响应的格式。
3、Referer:告诉服务器,当前请求从哪里来。

③ 请求空行:
一个空行,分割 POST请求 的请求头和请求体
④ 请求体(正文):
如果是 GET 方式的请求,没有请求体;如果是 POST 方式请求,实际上就是封装 POST 请求的一些请求参数。如 username=zhangsan

Request

Request对象 和 Response对象 的原理

原理图解

request对象 的继承体系结构

ServletRequest 是一个接口,HttpServletRequest 是 ServletRequest 的子接口,RequestFacade类实现了 HttpServletRequest 接口,由 tomcat 创建该类的对象。

request 的功能

1、获取请求消息

① 获取请求行数据
获取请求方式:String getMethod()
获取虚拟目录:String getContextPath()
获取 Servlet 路径:String getServletPath()
获取 get 方式请求参数:String getQueryPath()
获取请求 URL:getRequestURI()StringBuffer getRequestURL()
获取协议及版本:String getProtocol()
获取客户机的 IP 地址:String getRemoteAddr()

@WebServlet("/ServletDemo5")
public class ServletDemo5 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1 获取请求方式
        String method = req.getMethod();
        System.out.println(method);
        // 2 获取虚拟目录
        String contextPath = req.getContextPath();
        System.out.println(contextPath);
        // 3 获取 Servlet 路径
        String path = req.getServletPath();
        System.out.println(path);
        // 4 获取 get 方式请求参数
        String queryString = req.getQueryString();
        System.out.println(queryString);
        // 5 获取请求 URL
        String URI = req.getRequestURI();
        System.out.println(URI);
        StringBuffer URL = req.getRequestURL();
        System.out.println(URL);
        // 6 获取协议及版本
        String protocol = req.getProtocol();
        System.out.println(protocol);
        // 7 获取客户机的 IP 地址
        String addr = req.getRemoteAddr();
        System.out.println(addr);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

注:
URL:统一资源定位符 http://localhost:8080/xnlj/ServletDemo5
URI:统一资源标识符 /day15/ServletDemo5

② 获取请求头数据
String getHeader(String name):通过请求头的名称获取请求头的值
Enumeration<String> getHeaderNames():获取所有的请求头名称

@WebServlet("/RequestDemo1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求头
        String agent = req.getHeader("User-Agent");
        if (agent.contains("Chrome")) {
            System.out.println("google Chrome");
        } else if (agent.contains("Firefox")) {
            System.out.println("Firefox");
        } else {
            System.out.println("others");
        }

        // 获取所有的头信息
        Enumeration<String> headerNames = req.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            // 根据名称获取请求头的值
            String value = req.getHeader(name);
            System.out.println(name + ":" + value);
        }
        // 获取referer信息
        String referer = req.getHeader("referer");
        System.out.println(referer);
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

③ 获取请求体数据

只有 POST 请求方式才有请求体,在请求体中封装了 POST 请求的请求参数。

步骤:
a:获取流对象
BufferedReader getReader():获取字符输入流,只能操作字符数据
ServletInputStream getInputStream():获取字节输入流,可以
b:再从流对象中拿数据
写一个登录页面,以 post 方式提交表单:

<body>
    <form action="/day15/RequestDemo2" method="post">
        <input type="text" placeholder="请输入用户名" name="username">
        <input type="text" placeholder="请输入密码" name="pwd">
        <button type="submit">登录</button>
    </form>
</body>

Java 代码:

@WebServlet("/RequestDemo2")
public class RequestDemo2 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 {
        this.doPost(request, response);
    }
}

访问上面的登录页面,输入用户名和密码之后提交表单,可以看到在控制台打印出 username=zhangsan&pwd=123 的信息

2、其他功能

① 获取请求参数通用方式(GET 和 POST 请求方式都可用)
String getParameter(String name):根据参数名称获取参数值
String[] getParameterValues(String name):根据参数名称获取参数值的数组(通常用来获取复选框的参数值)
Enumeration<String> getParameterNames():获取所有请求的参数名称
Map<String, String[]> getParameterMap():获取所有参数的 map 集合
页面代码:

<body>
    <form action="/day15/RequestDemo3" method="post">
        <input type="text" placeholder="请输入用户名" name="username"><br>
        <input type="text" placeholder="请输入密码" name="pwd"><br>
        <input type="checkbox" name="hobby" value="study">学习
        <input type="checkbox" name="hobby" value="play">游戏
        <br>
        <button type="submit">提交</button>
    </form>
</body>

Java 代码:

@WebServlet("/RequestDemo3")
public class RequestDemo3 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求参数
        String username = req.getParameter("username");
        System.out.println(username);
        System.out.println("---------------------------------");
        // 根据参数名称获取参数值的数组
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
        System.out.println("---------------------------------");
        // 获取所有请求的参数名称
        Enumeration<String> enumeration = req.getParameterNames();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();
            System.out.println(name);
            String value = req.getParameter(name);
            System.out.println(value);
        }
        System.out.println("---------------------------------");
        // 获取所有参数的 map 集合
        Map<String, String[]> map = req.getParameterMap();
        Set<String> set = map.keySet();
        for (String name : set) {
            System.out.println(name);
            // 根据键获取值
            String[] values = map.get(name);
            for (String value : values) {
                System.out.println(value);
            }
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

中文乱码问题:
tomcat 8 已经将 get 方式的乱码问题解决了
而 post 方式如果输入中文或非法问题就会出现乱码问题,为了解决该问题,我们需要在获取参数之前,设置 request 的编码:
request.setCharacterEncoding("utf-8");

② 请求转发
一种在 服务器内部 的资源跳转方式。
步骤:
a:通过 request 对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
b:使用 RequestDispatcher 对象进行转发:forward(ServletRequest request, ServletResponse response)
特点:
a:浏览器地址栏路径不发生变化
b:只能转发到当前服务器内部资源中
c:转发是一次请求

@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("RequestDemo4 被访问了~~~");
        // 转发资源到 RequestDemo5
        req.getRequestDispatcher("/RequestDemo5").forward(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}

@WebServlet("/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("RequestDemo5 被访问了~~~");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}

创建两个 Servlet 对象,当通过浏览器访问 RequestDemo4 这个资源时,会在控制台打印出 RequestDemo4 被访问了~~~RequestDemo5 被访问了~~~ 这两句话,也就是浏览器通过一次请求间接的访问了两个资源。

③ 共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据
request 域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
a:void setAttribute(String name, Object obj):存储数据
b:Object getAttitude(String name):通过键获取值
c:void removeAttribute(String name):通过键移除键值对

@WebServlet("/RequestDemo4")
public class RequestDemo4 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        System.out.println("RequestDemo4 被访问了~~~");
        // 存储数据到 request 域中
        req.setAttribute("name", "zhangsan");
        // 转发资源到 RequestDemo5
        req.getRequestDispatcher("/RequestDemo5").forward(req, resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}
@WebServlet("/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Object obj = req.getAttribute("name");
        System.out.println(obj);
        System.out.println("RequestDemo5 被访问了~~~");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}

④ 获取 ServletContext
ServletContext getServletContext()

@WebServlet("/RequestDemo6")
public class RequestDemo6 extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = req.getServletContext();
        System.out.println(context); // org.apache.catalina.core.ApplicationContextFacade@51f99c81
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }
}

我是快斗,请多多指教!下篇不见不散!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值