7、HttpServletRequest对象

HttpServletRequest 对象:主要作用是用来接收客户端发送过来的请求信息,例如:请求的参数,发送的头信息等都属于客户端发来的信息,service()方法中形参接收的是 HttpServletRequest 接口的实例化对象,表示该对象主要应用在 HTTP 协议上,该对象是由 Tomcat 封装好传递过来。一切请求都围绕HttpServletRequest 对象。

​ HttpServletRequest 是 ServletRequest 的子接口,ServletRequest 只有一个子接口,就是 HttpServletRequest。既然只有一个子接口为什么不将两个接口合并为一个?

​ 从长远上讲:现在主要用的协议是 HTTP 协议,但以后可能出现更多新的协议。若以后想要支持这种新协议,只需要直接继承 ServletRequest 接口就行了。

​ 在 HttpServletRequest 接口中,定义的方法很多,但都是围绕接收客户端参数的。但是怎么拿到该对象呢?不需要,直接在 Service 方法中由容器传入过来,而我们需要做的就是取出对象中的数据,进行分析、处理。

接收请求

常用方法

1、方法
在这里插入图片描述
2、示例

// 获取客户端请求的完整URL (从http开始,到?前面结束)
String url = request.getRequestURL().toString();
System.out.println("获取客户端请求的完整URL:" + url);
//  获取客户端请求的部分URL (从站点名开始,到?前面结束)
String uri = request.getRequestURI();
System.out.println("获取客户端请求的部分URL:" + uri);
// 获取请求行中的参数部分
String queryString = request.getQueryString();
System.out.println("获取请求行中的参数部分:" + queryString);
// 获取客户端的请求方式
String method = request.getMethod();
System.out.println("获取客户端的请求方式:" + method);
// 获取HTTP版本号
String protocol = request.getProtocol();
System.out.println("获取HTTP版本号:" + protocol);
// 获取webapp名字 (站点名)
String webapp = request.getContextPath();
System.out.println("获取webapp名字:" + webapp);

结果,如果客户端未传递参数http://localhost:8888/s/sr01,结果为:
在这里插入图片描述
如果传递了参数http://localhost:8888/s/sr01?uname=lili&pwd=123123,结果为:
在这里插入图片描述

获取请求参数
  1. 方法
    在这里插入图片描述
  2. 示例
// 获取指定名称的参数,返回字符串
String uname = request.getParameter("uname");
System.out.println("uname的参数值:" + uname);
// 获取指定名称参数的所有参数值,返回数组
String[] hobbys = request.getParameterValues("hobby");
System.out.println("获取指定名称参数的所有参数值:" + Arrays.toString(hobbys));

访问http://localhost:8888/s/sr01?uname=lili&pwd=123123&hobby=sing&hobby=dance,结果为:
在这里插入图片描述

请求乱码问题

案例:

(1)先将服务器改为tomcat7
在这里插入图片描述
(2)编写login.jsp和servlet,从login.jsp请求到servlet:

package com.msb.testrequest;

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: zhaoss
 */
@WebServlet("/sr02")
public class ServletRequest02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uname = req.getParameter("uname");
        System.out.println("接收到的uname参数为:" + uname);
    }
}
<%--
  Created by IntelliJ IDEA.
  User: zss
  Date: 2022/12/29
  Time: 12:56
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="sr02" method="get">
        用户名:<input type="text" name="uname">
        <input type="submit" value="提交">
    </form>
</body>
</html>

action中servlet地址,不用加/,直接写sr02即可。因为src目录和web目录都属于根目录,可以理解为平级的,所以从jsp中请求servlet不需要加/。
分别修改method为post和get,请求:http://localhost:8888/ServletDemo01_war_exploded/login.jsp:
在这里插入图片描述
点击提交后,后台结果:
在这里插入图片描述
发现问题:无论get方式还是post方式提交,后台均会出现乱码。出现乱码的原因:
在这里插入图片描述
如何解决呢?

new String(request.getParameter(name).getBytes("ISO-8859-1"),"UTF-8");

request.getParameter(name).getBytes(“ISO-8859-1”) -----> 先将字符串用ISO-8859-1码转为字节

new String(request.getParameter(name).getBytes(“ISO-8859-1”),“UTF-8”); -----> 然后将该字节以UTF-8转成字符

测试,无论get方式和post方式都不会出现乱码了:
在这里插入图片描述
但是上面方式有缺点:

假如表单中有uname,password,hobby等等多个元素,那么在后台解决的话每个都要这样转一下 ,太麻烦了!那有没有更快速的方式呢?

上面的问题就是出在传过来的字节转字符串默认的解码方式为ISO-8859-1,那么我们直接将这个码改为UTF-8就可以了:

request.setCharacterEncoding("UTF-8");

再次测试:

发现get方式依然乱码,但是post方式乱码问题得到了解决。

原因:这种方式只针对 POST 有效(必须在接收所有的数据之前设定)

请求转发

请求转发,是一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的 URL 地址不会改变,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出

实现方式如下,达到多个资源协同响应的效果。

request.getRequestDispatcher(url).forward(request,response);

案例:

(1)编写一个页面login.jsp:

<%--
  Created by IntelliJ IDEA.
  User: zss
  Date: 2022/12/29
  Time: 13:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  <form action="sr03" method="post">
    用户名:<input type="text" name="uname">
    <input type="submit" value="登录">
  </form>
</body>
</html>

(2)因为请求转发是一种服务器的行为,当客户端请求到达后,服务器进行转发,所以定义两个Servlet,从第一个Servlet请求转发到第二个Servlet:

package com.msb.testrequest;

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: zhaoss
 */
@WebServlet("/sr03")
public class ServletRequest03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取前台的表单传递过来的数据:
        String uname = req.getParameter("uname");
        System.out.println("浏览器传过来的数据uname的值:" + uname);
        // 请求转发到另一个Servlet:
        req.getRequestDispatcher("sr04").forward(req,resp);
        // 请求转发后输出一句话:
        System.out.println("------sr03");
    }
}
package com.msb.testrequest;

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: zhaoss
 */
@WebServlet("/sr04")
public class ServletRequest04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取上一个Servlet传过来的数据:
        String uname = req.getParameter("uname");
        System.out.println("上一个Servlet传过来的数据uname的值:" + uname);
    }
}

启动服务器,浏览器发送请求:http://localhost:8888/s/login.jsp
在这里插入图片描述
后台结果:
在这里插入图片描述
前台浏览器地址栏:
在这里插入图片描述
原理:
在这里插入图片描述
除了可以请求转发到Servlet,还可以请求转发到jsp中:

package com.msb.testrequest;

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: zhaoss
 */
@WebServlet("/sr03")
public class ServletRequest03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取前台的表单传递过来的数据:
        String uname = req.getParameter("uname");
        System.out.println("浏览器传过来的数据uname的值:" + uname);
        // 请求转发到另一个Servlet:
        req.getRequestDispatcher("index.jsp").forward(req,resp);
        // 请求转发后输出一句话:
        System.out.println("------sr03");
    }
}

地址栏依旧是请求的第一个Servlet:
在这里插入图片描述
是否可以请求转发到服务器外部资源?比如百度首页:

package com.msb.testrequest;

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: zhaoss
 */
@WebServlet("/sr03")
public class ServletRequest03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取前台的表单传递过来的数据:
        String uname = req.getParameter("uname");
        System.out.println("浏览器传过来的数据uname的值:" + uname);
        // 请求转发到另一个Servlet:
        //req.getRequestDispatcher("sr04").forward(req,resp);
        //req.getRequestDispatcher("index.jsp").forward(req,resp);
        req.getRequestDispatcher("http://www.baidu.com").forward(req,resp);
        // 请求转发后输出一句话:
        System.out.println("------sr03");
    }
}

结果:
在这里插入图片描述
错误描述信息 :/s/https://www.baidu.com
因为是服务器跳转,会去当前的项目下找,但是找不到,报404错误,所以没法完成向服务器外部资源请求转发。

HttpServletRequest对象的使用

HttpServletRequest可以作为一个域对象(request域对象)使用,通过该对象可以在一个请求中传递数据,作用范围:在一次请求中有效,即服务器跳转有效。

// 设置域对象内容
request.setAttribute(String name, String value);
// 获取域对象内容
request.getAttribute(String name); 
// 删除域对象内容
request.removeAttribute(String name);

request 域对象中的数据在一次请求中有效,则经过请求转发,request 域中的数据依然存在,则在请求转发的过程中可以通过 request 来传输/共享数据。

案例:请求转发后request 域对象中的数据可以共享。

package com.msb.testrequest;

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: zhaoss
 */
@WebServlet("/msb/sr03")
public class ServletRequest03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取前台传过来的数据:
        String uname = req.getParameter("uname");
        System.out.println("前台传到sr03-Servlet中的uname的数值为:" + uname);
        // 域对象数据的共享:
        req.setAttribute("age","18");
        String age = (String)req.getAttribute("age");
        System.out.println("servlet03---age:" + age);
        // 请求转发:
        req.getRequestDispatcher("/sr04").forward(req,resp);
        // 在请求转发以后输出一句话:
        System.out.println("-----sr03");
    }
}

package com.msb.testrequest;

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: zhaoss
 */
@WebServlet("/sr04")
public class ServletRequest04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取请求数据:
        String uname = req.getParameter("uname");
        // 获取域对象中数据:
        String age = (String)req.getAttribute("age");
        System.out.println("servlet04---age:" + age);
        System.out.println("sr04-Servlet中获取uname的数值为:" + uname);
    }
}

### 回答1: 创建HttpServletRequest对象的方法有多种,以下是其中一种: 1. 在Servlet中,可以通过doGet()或doPost()方法的参数HttpServletRequest request来获取HttpServletRequest对象。 例如: protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取HttpServletRequest对象 HttpServletRequest req = request; // 其他操作 } 2. 在JSP中,可以通过内置对象request来获取HttpServletRequest对象。 例如: <% // 获取HttpServletRequest对象 HttpServletRequest req = request; // 其他操作 %> 3. 在普通Java类中,可以通过ServletActionContext.getRequest()方法来获取HttpServletRequest对象。 例如: import org.apache.struts2.ServletActionContext; public class Test { public void test() { // 获取HttpServletRequest对象 HttpServletRequest req = ServletActionContext.getRequest(); // 其他操作 } } ### 回答2: HTTPServletRequest对象ServletAPI中的一个重要接口,它提供了客户端发送的HTTP请求相关信息。创建HTTPServletRequest对象可以通过以下步骤: 1. 在JSP或Servlet的doGet()或doPost()方法中声明HttpServletRequest变量: ``` HttpServletRequest request; ``` 2. 通过Servlet的service()方法直接调用 HttpServletRequest 对象: ``` public void doGet(HttpServletRequest request, HttpServletResponse response) ``` 3. 利用ServletConfig对象调用 getServletContext() 方法获取ServletContext对象,从而获取HttpServletRequest对象: ``` ServletConfig config = getServletConfig(); ServletContext context = config.getServletContext(); HttpServletRequest request = (HttpServletRequest) context.getAttribute(“javax.servlet.request”); ``` 4. 调用HttpServletRequest的getSession()方法获取HTTPSession对象: ``` HttpSession session = request.getSession(true); ``` 5. 利用HttpServletRequest的getParameter()方法获取客户端发送的参数值: ``` String parameter = request.getParameter("paramName"); ``` 总之,创建HttpServletRequest对象主要是利用ServletAPI提供的方法和接口,通过获取ServletContext和HTTPSession对象,并使用其方法获取需要的数据。 ### 回答3: 在Java Web开发中,我们经常需要创建HttpServletRequest对象,来获取客户端请求的信息。HttpServletRequest对象代表了客户端HTTP请求。通过HttpServletRequest对象,我们可以获取客户端请求的URL、请求参数、请求头等信息。在下面,我将简单介绍一下如何创建HttpServletRequest对象HttpServletRequest对象的创建是由Web服务器完成的,我们在Servlet中只需要从方法参数中获取HttpServletRequest对象即可。Web服务器在客户端请求时,会根据请求信息创建一个HttpServletRequest对象,并将其传递给Servlet的service()方法。 例如,在一个Servlet中,我们可以重写doGet()或doPost()方法,获取HttpServletRequest对象。实例代码如下: ``` protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取HttpServletRequest对象 HttpServletRequest httpServletRequest = request; // 获取请求参数的值 String username = request.getParameter("username"); String password = request.getParameter("password"); // 处理业务逻辑 // ... // 发送响应到客户端 } ``` 在上面的示例代码中,我们重写了doGet()方法,并从方法参数中获取了HttpServletRequest对象。接下来,我们通过HttpServletRequest对象获取了HTTP请求的参数值,并处理了业务逻辑。 除了从方法参数中获取HttpServletRequest对象外,还可以使用HttpServletRequestWrapper类来创建HttpServletRequest对象HttpServletRequestWrapper是HttpServletRequest的子类,它重写了HttpServletRequest中的所有方法。我们可以通过继承HttpServletRequestWrapper类,实现自己的HttpServletRequest对象,同时保留HttpServletRequest原有的方法。实例代码如下: ``` public class MyHttpServletRequest extends HttpServletRequestWrapper { public MyHttpServletRequest(HttpServletRequest request) { super(request); } // 重写HttpServletRequest中的方法 // ... } ``` 在上面的代码中,我们创建了一个自定义的HttpServletRequest对象MyHttpServletRequest,并重写了HttpServletRequest中的方法。我们可以通过重写这些方法,在不改变原HttpServletRequest行为的情况下,为我们的应用程序添加一些新的特性。 在Java Web开发中,HttpServletRequest对象是非常重要的一个对象。通过HttpServletRequest对象,我们可以获取客户端请求的信息,实现业务逻辑,并生成HTTP响应。无论是从方法参数中获取HttpServletRequest对象,还是通过HttpServletRequestWrapper类来创建HttpServletRequest对象,我们都可以灵活地应用在实际的开发中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值