JavaWeb-Request讲解

本文详细介绍了JavaWeb中Request对象的使用,包括Request的概述、如何获取HTTP请求信息(如请求行、请求头、请求参数)、Request的其他功能如请求转发和作为域对象的角色。此外,还提供了相关API的演示、浏览器兼容性问题、BeanUtils工具类的使用以及请求转发的特点。文章以案例分析和使用技巧收尾,帮助读者深入理解和应用Request对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Request概述

2. reuqest获取请求消息内容
    请求行
    请求头
    请求参数(体)
3. request其他功能
    请求转发
    域对象

一.Request概述:

- 用户通过浏览器访问服务器时,Tomcat将HTTP请求中所有的信息都封装在Request对象中
- 作用:开发人员可以通过request对象方法,来获取浏览器发送的所有信息.

Web 服务器收到客户端的 http 请求,会针对每一次请求
分别创建一个用于代表请求的 request 对象和代表响应的 response 对象。

Request的体系结构

javax.servlet.http.HttpServletReuqest不是相关请求的顶级接口,它继承自 父接口javax.servlet.ServletRequest:

上图为继承关系:
 
HttpServletRequest 对象代表客户端的请求,当客户端通过 HTTP 协议访问服务器时, HTTP 请求中的所有信
息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。
 

在javaEE中我们是面向接口编程

通过以上分析:Request对象进行常用的操作为:

1) 获取请求数据
2)作为域对象
3)请求转发

二 Request获取Http请求信息

Api介绍

String getMethod() 获取请求方式的类型 如:GET或POST 
StringBuffer getRequestURL() 获取客户端发出请求完整URL 
String getRequestURI() 获取请求行中的资源名部分 
String getContextPath() 获取当前项目根路径 
String getProtocol() 获取当前协议的名称和版本 
String getRemoteAddr() 获取IP地址 
int getLocalPort() 获取端口
注:
uri: 统一资源标识符 , 用来标识一个资源 , 资源路径。 ( 相当于身份证 )
url: 统一资源定位符 , 是一种具体的 URI, 可以用来标识一个资源 . 并且指明了如何定位一个资源(相当于身份证的地址)
如:
http://localhost:8080/wsl/demo
url: http://localhost:8080/wsl/demo
uri: /wsl/demo

1。获取请求行信息

* 例如:
		GET /wsl_request/requestDemo1 HTTP/1.1

* 相关API:
	1. 获取请求方式 GET
			String getMethod()  
			
	2. 获取项目虚拟路径(项目名)/wsl_request
			String getContextPath()
			
	3. 获取URI /wsl_request/requestDemo1
			统一资源标识符(范围广)  共和国
			String getRequestURI() 
			
	4. 获取URL http://localhost:8080/wsl_request/requestDemo1
			统一资源定位符(确定某一个地址) 中华人民共和国
			StringBuffer getRequestURL()  
			
	5. 获取协议和版本号	HTTP/1.1
			String getProtocol()
			
	6. 获取客户端ip
			String getRemoteAddr()
@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // System.out.println(req);
        System.out.println("请求方式:" + req.getMethod());
        System.out.println("虚拟路径:" + req.getContextPath());
        System.out.println("URI:" + req.getRequestURI());
        System.out.println("URL:" + req.getRequestURL());
        System.out.println("协议和版本:" + req.getProtocol());
        System.out.println("客户端ip:" + req.getRemoteAddr());

    }

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

    }
}

2.获取请求头信息

* 例如:
        Host: localhost:8080
        
* 相关API:
    1. 获取知道请求头名称对应的值,注:名称不区分大小写
            String getHeader(String name)  
            
    2. 获取所有请求头的名称
            Enumeration<String> getHeaderNames()  
            注:是Iterator前身

@WebServlet("/requestDemo2")
public class RequestDemo2 extends HttpServlet {

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

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

    }
}

3.demo

请求头中参数有一个referer:请求来源

/*
    视频防盗链
 */
@WebServlet("/refererRequest")
public class RefererRequest extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        // 1.获取请求来源(如果是浏览器地址直接访问的话,referer就是null)
        String referer = req.getHeader("referer");
        // 2.判断是不是自家网站发起的请求
        if (referer != null && referer.startsWith("http://localhost:8080")) {
            resp.getWriter().write("正常播放视频...");
        }else{
            resp.getWriter().write("想看吗?来优酷吧....");
        }
    }

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

    }
}

4.浏览器兼容性问题

user-agen:浏览器版本信息

/*
    浏览器兼容性
 */
@WebServlet("/userAgentReqeust")
public class UserAgentReqeust extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");

        // 1.获取浏览器版本信息
        String userAgent = req.getHeader("user-agent");
        // 2.判断浏览器版本
        if (userAgent.contains("Chrome")) {
            resp.getWriter().write("浏览器:谷歌");
        } else if (userAgent.contains("Firefox")) {
            resp.getWriter().write("浏览器:火狐");
        } else {
            resp.getWriter().write("浏览器:其他");
        }
    }

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

    }
}

5.获取请求参数,请求体

  • 不论get还是post请求方式,都可以使用下列方法来获取请求参数

  • 在web阶段,get和post处理的业务逻辑都是一样的

* 参数
		username=wsl&password=123456&hobby=eat&hobby=perm
		
* API
	1. 获取指定参数名的值  username=wsl
			String getParameter(String name)
			
	2. 获取指定参数名的值数组  hobby=eat&hobby=perm
			String[] getParameterValues(String name)
	
	3. 获取所有参数名和对应值数组,参数名 name(key),值数组 value,封装map集合
			Map<String,String[]> getParameterMap()
			
			
* 中文乱码【重点】
	get:在tomcat8及以上版本,内部URL编码(UTF-8)
	post:编码解码不一致,造成乱码现象
		客户端(浏览器)编码:UTF-8
		服务器默认     解码:ISO-8859-1 拉丁文
		指定解码:void setCharacterEncoding(String env)
			注:必须在方法内,行首
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>form</title>

</head>
<body>
<h3>get方式:</h3>
<form action="/wsl_request/requestDemo3" method="get">
    用户:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    爱好:
        <input type="checkbox" name="hobby" value="eat"/>吃
        <input type="checkbox" name="hobby" value="drink"/>喝
        <input type="checkbox" name="hobby" value="perm"/>烫头
    <input type="submit" value="get提交...">
</form>
<h3>post方式:</h3>
<form action="/wsl_request/requestDemo3" method="post">
    用户:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    爱好:
    <input type="checkbox" name="hobby" value="eat"/>吃
    <input type="checkbox" name="hobby" value="drink"/>喝
    <input type="checkbox" name="hobby" value="perm"/>烫头
    <input type="submit" value="post提交...">
</form>
</body>
</html>
@WebServlet("/requestDemo3")
public class RequestDemo3 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("手动获取---------");
        String username = req.getParameter("username");
        System.out.println("用户:" + username);
        String password = req.getParameter("password");
        System.out.println("密码:" + password);
        String[] hobby = req.getParameterValues("hobby");
        System.out.println("爱好:" + Arrays.toString(hobby));
        System.out.println("自动获取---------");
        Map<String, String[]> parameterMap = req.getParameterMap();
        parameterMap.forEach((k, v) -> { //此处用了lamda表达式
            System.out.println(k + " = " + Arrays.toString(v));
        });
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 指定post的解码方式....
        req.setCharacterEncoding("UTF-8");
        System.out.println("post提交方法,再去调用get....");
        this.doGet(req, resp); 

    }
}

6.BeanUtils jar包

  • 是apache组织,提供一套工具类,简化参数的封装.....

  • 简单来说:将前端提交的数据,直接封装到你想要的JavaBean中

 (1)向项目中导入jar包

(2)使用工具类封装数据

<h3>BeanUtils测试:</h3>
<form action="/wsl_request/requestDemo4" method="post">
    用户:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    爱好:
    <input type="checkbox" name="hobby" value="eat"/>吃
    <input type="checkbox" name="hobby" value="drink"/>喝
    <input type="checkbox" name="hobby" value="perm"/>烫头
    <input type="submit" value="post提交...">
</form>

(3)数据封装:

@WebServlet("/requestDemo4")
public class RequestDemo4 extends HttpServlet {

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

    // 使用BeanUtils快速封装数据到 User对象中
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");// 指定解码方式
        // 1.获取所有参数的数据,map集合
        Map<String, String[]> parameterMap = request.getParameterMap();
        // 2.创建user对象
        User user = new User();
        // 3.调用工具类,实现快速封装
        try {
            BeanUtils.populate(user, parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        System.out.println(user);
    }

}

考虑问题:

 

三Request其他功能

1.请求转发

一种在服务器内部的资源跳转方式

* API
    1. 通过reqeust对象,获得转发器对象
            RequestDispatcher getRequestDispatcher(String path)
            
    2. 通过转发器对象,实现转发功能
            void forward(ServletRequest request, ServletResponse response)  
            
* 请求转发特点
    浏览器:发了一次请求
    地址栏:没有发生改变
    只能转发到服务器内部资源....
    
* 链式编程
        request.getRequestDispatcher("/bServlet").forward(reqeust,response)

2.域对象,(共享数据)

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

 API
	1. 设置数据
			void setAttribute(String name, Object o)
			
	2. 获取数据
			Object getAttribute(String name)
			
	3. 删除数据
			void removeAttribute(String name)
			
			
 生命周期
	1. 何时创建
			用户发送请求时,创建request
	2. 何时销毁
			服务器返回响应是,销毁request
	
	3. 作用范围
			一次请求,包含多次转发

coding:

@WebServlet("/aServlet")
public class AServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("aServlet处理功能上....");
        // 转发到BServlet
       /* // 1.获得转发器对象   path = @WebServlet("/bServlet")
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/bServlet");
        // 2.实现转发功能
        requestDispatcher.forward(request, response);*/

       // 存一个数据
        request.setAttribute("hanbao", "鸡腿堡");


        // 链式编程横
        request.getRequestDispatcher("bServlet").forward(request, response);
    }

}



@WebServlet("/bServlet")
public class BServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("bServlet处理功能下....");
        // 获取数据
        String hanbao = (String) request.getAttribute("hanbao");
        System.out.println("hanbao:" + hanbao);
    }

}

3.获取ServletContext对象

应用上下文对象,表示一个web项目

通过reuqest,可以获得ServletContext对象

public ServletContext  getServletContext();

四,案例

案例分析:

1.新建项目,并导入工具包,编写index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>index</title>

</head>
<body>
<h4>用户登录</h4>
<form action="/wsl_login/loginServlet" method="post">
    用户:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    <input type="submit" value="登录">
</form>

</body>
</html>

2.User实体类

// 用户对象
public class User {

    private String username;// 用户名

    private String password;// 密码

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

3.LoginServlet类, SuccessServlet类,FailServlet类

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.设置request解码方式
        request.setCharacterEncoding("UTF-8");
        // 2.获取浏览器请求参数,map集合
        Map<String, String[]> parameterMap = request.getParameterMap();

        // 3.使用BeanUtils工具类,封装user对象中
        User user = new User();
        try {
            BeanUtils.populate(user, parameterMap);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        // 4.判断
        if("wsl".equals(user.getUsername())&&"123".equals(user.getPassword())){
            // 正确
            request.setAttribute("user", user);
            request.getRequestDispatcher("/successServlet").forward(request,response);
        }else{
            // 错误
            request.getRequestDispatcher("/failServlet").forward(request,response);
        }
    }

}


@WebServlet("/successServlet")
public class SuccessServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.从request域获取user对象
        User user = (User) request.getAttribute("user");
        // 2.友情提示
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(user.getUsername() + ",登录成功");
    }

}



@WebServlet("/failServlet")
public class FailServlet extends HttpServlet {

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

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1.友情提示
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("用户名或密码错误..");
    }

}



问题总结:

请求转发与请求重定向的区别
 
通过上图,我们可以简单总结几点转发和重定向的区别:
1. 转发在一次请求中完成,重定向是两次请求
2. 转发操作发生在服务器内部,重定向是浏览器执行操作
3. 转发地址栏不变(只有一次请求,一个地址),重定向,地址栏变化(两次请求,两个地址)
4. 转发可以在一次请求中共享数据,重定向不行(重定向两次请求,每次都会创建新的 request 对象)。

 

使用技巧:

1.自定义Servlet模板

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
@javax.servlet.annotation.WebServlet("/${Class_Name}")
public class ${Class_Name} extends javax.servlet.http.HttpServlet {

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
        this.doPost(request,response);
    }

    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {

    }
 
}

2.IDEA 代码抛异常快捷方式

快捷方式一:(光标移到该代码行,Alt+Enter),可以异常外抛出,也可以try-catch:

快捷方式二:(光标移到该代码行,或者选中该行代码,Ctrl+Alt+T):

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值