作用:每次只要有请求进入Tomcat 服务器,Tomcat 服务器就会把请求过来的HTTP 协议信息解析好封装到Request 对象中。然后传递到service 方法(doGet 和doPost)中给我们使用。我们可以通过HttpServletRequest 对象,获取到所有请求的信息。
常用方法
方法名 | 方法作用 |
---|---|
getRequestURI() | 获取请求的资源路径 |
getRequestURL() | 获取请求的统一资源定位符(绝对路径) |
getRemoteHost() | 获取客户端的ip 地址 |
getHeader() | 获取请求头 |
getParameter() | 获取请求的参数 |
getParameterValues() | 获取请求的参数(多个值的时候使用) |
getMethod() | 获取请求的方式GET 或POST |
setAttribute(key, value) | 设置域数据 |
getAttribute(key) | 获取域数据 |
getRequestDispatcher() | 获取请求转发对象 |
public class RequestAPIServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//i. getRequestURI() 获取请求的资源路径
System.out.println("URI:" + req.getRequestURI());
//ii. getRequestURL() 获取请求的统一资源定位符(绝对路径)
System.out.println("URL:" + req.getRequestURL());
//iii. getRemoteHost() 获取客户端的ip 地址
/*
* 在IDEA中,使用localhost访问时,,得到的客户端ip地址是:127.0.0.1
* 在IDEA中,使用127.0.0.1访问时,,得到的客户端ip地址是:127.0.0.1
* 在IDEA中,使用真实ip访问时,,得到的客户端ip地址是:真实的ip地址
* */
System.out.println("客户端IP地址:" + req.getRemoteHost());
//iv. getHeader() 获取请求头
System.out.println("请求头User-Agent:" + req.getHeader("User-Agent"));
//vii. getMethod() 获取请求的方式GET 或POST
System.out.println("请求的方式:" + req.getMethod());
}
}
GET请求时的设置:
方式一:
在Tomcat服务器的web.xml中设置端口号的那一个标签上添加配置信息URIEncoding=“UTF-8”
<Connector URIEncoding="UTF-8" connectionTimeout="50000" port="8080" protocol="HTTP/1.1" redirectPort="8443" />
方式二:
说明: tomcat8以后默认URI编码格式是utf-8;7之前的都是iso8859-1
POST请求时的设置:
POST通过request body传递参数是实体内容解码方式,默认解码格式是request编码格式,与Tomcat8编码格式无关,默认以ISO8859-1的编码解析数据。
所以要用request的setCharacterEncoding(String env)方法设置编码字符集。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String password = req.getParameter("password");
//设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题
//要在获取请求参数之前调用才有效
req.setCharacterEncoding("UTF-8");
System.out.println("----Post---");
//获取请求的参数:
String username = req.getParameter("username");
String[] hobby = req.getParameterValues("hobby");
System.out.println("用户名:" + username);
System.out.println("密码:" + password);
System.out.println("爱好:" + Arrays.toString(hobby));
}
或者在web.xml用SpringMVC配置一个filter设置所有的post编码格式。
<!-- 字符编码的Filter:要在所有Filter之前,要不其他Filter可能获取了参数-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- encoding:指定解决POST请求乱码-->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<!-- forceEncoding:是否解决响应乱码,但是不指定文本类型-->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern> / *</url-pattern>
</filter-mapping>
请求转发的特点:
示例:页面1(实施请求转发)
public class Servlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求的参数
String username = request.getParameter("username");
System.out.println("在Servlet1中查看参数:" + username);
//给请求(材料)盖个章,并传递到Servlet2去查看
request.setAttribute("key","柜台1的章");
//问路:Servlet2怎么走
/*
* 请求转发必须要以/斜杠打头,/表示地址为:http://ip:port//工程名/,映射到IDEA代码的web目录
* */
// RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2");
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/form.html");//可行!
// RequestDispatcher requestDispatcher = request.getRequestDispatcher("/http://www.baidu.com");//不行这是在自己的工程下
//不行还是在自己工程下,请求转发访问不了外面的资源
// RequestDispatcher requestDispatcher = request.getRequestDispatcher("http://www.baidu.com");
//走向Servlet2
requestDispatcher.forward(request,response);
}
}
页面2(实际页面)
public class Servlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("在Servlet2中查看参数:" + username);
//查看柜台1是否有章
Object key = request.getAttribute("key");
System.out.println("是否是柜台1的章:是" + key);
//处理自己的业务
System.out.println("Servlet2处理自己的业务");
}
}
问题引入:
在浏览器显示的超链接地址中,所有相对路径在工作时候都会参照当前浏览器地址栏中的地址来进行跳转,从而导致可能得不到想要的路径。
base标签的作用:
可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转。
<!-- base标签,永远固定相对路径跳转的结果-->
<base href="http://localhost:8080/"/>
在web 中/ 斜杠是一种绝对路径。
情况1:
/ 斜杠如果被浏览器解析,得到的地址是:http://ip:port/
情况2:
/ 斜杠如果被服务器解析,得到的地址是:http://ip:port/工程路径
/servlet1 - servletContext.getRealPath(“/”);
- request.getRequestDispatcher(“/”);
特殊情况:
response.sendRediect(“/”); 把斜杠发送给浏览器解析。得到http://ip:port/
不以/斜杠开始是相对路径,以当前资源路径为基准,但是经常容易出问题。
概述:HttpServletResponse 类和HttpServletRequest 类一样。每次请求进来,Tomcat 服务器都会创建一个Response 对象传递给Servlet 程序去使用。
HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,我们如果需要设置返回给客户端的信息,可以通过HttpServletResponse 对象来进行设置。
HttpServletResponse的两个输出流:
字节流 | getOutputStream() | 常用于下载(传递二进制数据) |
---|---|---|
字符流 | getWriter() | 常用于回传字符串(常用) |
注:两个流同时只能使用一个。即使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
如下代码会报错:java.lang.IllegalStateException: getWriter() has already been called for this response
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writer = response.getWriter();
ServletOutputStream outputStream = response.getOutputStream();
}
方式一:(不推荐使用)
设置服务器字符集为UTF-8
resp.setCharacterEncoding(“UTF-8”);
通过响应头,设置浏览器也使用UTF-8 字符集
resp.setHeader(“Content-Type”, “text/html; charset=UTF-8”);
方式二:(推荐使用)
它会同时设置服务器和客户端都使用UTF-8 字符集,还设置了响应头
此方法一定要在获取流对象之前调用才有效
resp.setContentType(“text/html; charset=UTF-8”);
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println(response.getCharacterEncoding());//默认ISO-8859-1
// 设置服务器字符集为UTF-8
// response.setCharacterEncoding("UTF-8");
//通过响应头,设置浏览器也使用UTF-8字符集
// response.setHeader("content-Type","text/html;charset=utf-8");
//以下方法会同时设置服务器和客户端都是用utf-8字符集,还设置了响应头
//此方法一定要在获取流对象之前调用才有效
response.setContentType("text/html;charset=utf-8");
System.out.println(response.getCharacterEncoding());//utf-8
//要求:往客户端回传字符串数据
PrintWriter writer = response.getWriter();
writer.write("字符集编码设置成功");
}
概念:客户端给服务器发请求,然后服务器给客户端一些地址,让客户端去新地址访问,叫请求重定向(因为之前的地址可能已经被废弃)。
请求重定向的特点:
注:与请求转发的特点相反
方式一:(不推荐使用)
设置响应状态码302 ,表示重定向,(已搬迁)
resp.setStatus(302);
设置响应头,说明新的地址在哪里
resp.setHeader(“Location”, “http://localhost:8080”);
方式二:(推荐使用)
请求重定向的第二种方案(推荐使用):
resp.sendRedirect(“http://localhost:8080”);
代码示例:
旧地址
public class Response1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("曾到此一游——Response1");
//方式一:
//设置响应状态码302,表示重定向(已搬迁)
// response.setStatus(302);
request.setAttribute("key","keyValue");
//设置响应头说明新地址在哪里
// response.setHeader("Location","http://localhost:9999/07_servlet/response2");//可以
// response.setHeader("Location","http://localhost:9999/07_servlet/WEB-INF/form.html");//404
// response.setHeader("Location","http://baidu.com");//可以
//方式二:
response.sendRedirect("http://localhost:9999/07_servlet/response2");
}
}
新地址
public class Response2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("response2's result!");
response.getWriter().println("response2's result!");
System.out.println(request.getAttribute("key"));//null
}
}