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,结果为:
获取请求参数
- 方法
- 示例
// 获取指定名称的参数,返回字符串
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);
}
}