每次只要有请求进入 Tomcat 服务器,Tomcat服务器就会把请求过来的HTTP协议解析好封装到Request对象中。然后传递到 servlet方法(doGet 和 doPost)中给我们使用,我们可以通过 HttpServletRequest 对象,获取到所有请求的信息
getRequestURI() 获取请求的资源路径
getRequestURL() 获取请求的统一资源定位符(绝对路径)
getRemoteHost() 获取客户端 ip 地址
getHeader 获取请求头
getMethod() 获取请求方式 GET或POST
RequestAPIServlet:
package com.aiguigu.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RequestAPIServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //getRequestURI() System.out.println("URI =>" + req.getRequestURI()); //getRequestURL() 获取请求的统一资源定位符(绝对路径) System.out.println("URL =>" + req.getRequestURL()); //getRemoteHost() 获取客户端 ip 地址 System.out.println("客户端 ip =>" + req.getRemoteHost()); //getHeader 获取请求头 System.out.println("请求头 =>" + req.getHeader("User-Agent")); //getMethod() 获取请求方式 GET或POST System.out.println("请求的方式 =>" + req.getMethod()); } }
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>RequestAPIServlet</servlet-name> <servlet-class>com.aiguigu.servlet.RequestAPIServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RequestAPIServlet</servlet-name> <url-pattern>/requestAPIServlet</url-pattern> </servlet-mapping> </web-app>
运行效果:
请求的方式 =>GET URI =>/07_servlet/requestAPIServlet URL =>http://localhost:8080/07_servlet/requestAPIServlet 客户端 ip =>0:0:0:0:0:0:0:1 请求头 =>Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.43
ParameterServlet:
package com.aiguigu.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Arrays; public class ParameterServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); String password = req.getParameter("password"); String[] hobby = req.getParameterValues("hobby"); System.out.println("用户名:" + username); System.out.println("密码:" + password); System.out.println("兴趣爱好:" + Arrays.asList(hobby)); } }
form.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://localhost:8080/07_servlet/parameterServlet" method="get"> 用户名:<input type="text" name="username" ><br/> 密码:<input type="password" name="password" ><br/> 兴趣爱好: <input type="checkbox" name="hobby" value="cpp">C++ <input type="checkbox" name="hobby" value="java">Java <input type="checkbox" name="hobby" value="js">JavaScript<br/> <input type="submit" > </form> </body> </html>
运行结果:
用户名:qwe123 密码:qwe123 兴趣爱好:[cpp, java, js]
代码实现:
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置请求体的字符为 UTF-8 从而解决 post 请求乱码问题 //也要在获取请求参数之前调用才有效 req.setCharacterEncoding("UTF-8"); String username = req.getParameter("username"); String password = req.getParameter("password"); String[] hobby = req.getParameterValues("hobby"); System.out.println("用户名:" + username); System.out.println("密码:" + password); System.out.println("兴趣爱好:" + Arrays.asList(hobby)); }
运行效果:
什么是请求的转发?
请求转发是指,服务器收到请求后,从一个资源跳转到另一个资源的操作叫请求转发
Servlet1
package com.aiguigu.servlet; import javax.servlet.RequestDispatcher; 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; public class Servlet1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求的参数(办事的材料)查看 String username = req.getParameter("username"); System.out.println("在Servlet(柜台1) 中查看 参数(材料):" + username); //给材料 盖一个章 req.setAttribute("key1","柜台1的章"); //问路:S额rvlet(柜台2)怎么走 // RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2"); RequestDispatcher requestDispatcher = req.getRequestDispatcher("/WEB-INF/form.html"); //走向 Servlet2 (柜台2) requestDispatcher.forward(req,resp); } }
Servlet2
package com.aiguigu.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class Servlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求的参数(办事的材料)查看 String username = req.getParameter("username"); System.out.println("在Servlet(柜台1) 中查看 参数(材料)" + username); //查看 柜台1 是否有盖章 Object key1 = req.getAttribute("key1"); System.out.println("柜台1是否有章:" + key1); //处理自己的业务 System.out.println("Servlet2 处理自己的业务"); } }
运行结果:
在Servlet(柜台1) 中查看 参数(材料):null 在Servlet(柜台1) 中查看 参数(材料)null 柜台1是否有章:柜台1的章 Servlet2 处理自己的业务
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>首页</title> <!--base 标签设置页面相对路径工作时参照的地址 href 属性就是参数的地址值 --> </head> <body> 这是Web下的index.html <br/> <a href="a/b/c.html">a/b/c.html</a> <a href="http://localhost:8080/07_servlet/forwardC">请求转发:a/b/c.html</a> </body> </html>
c.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <base href="http://localhost:8080/07_servlet/a/b/"> </head> <body> 这是a下的b下的c.html页面<br/> <a href="../../index.html">跳回首页</a> </body> </html>
ForwardC
package com.aiguigu.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ForwardC extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("经过了 Forward 程序"); req.getRequestDispatcher("/a/b/c.html").forward(req,resp); } }
运行结果
点击上图任意一个超链接文本
分析:
在 web 中 / 斜杠 是一种绝对路径。
/ 斜杠 如果被浏览器解析,得到的地址是:http://ip:port/
/ 斜杠 如果被服务器解析,得到的地址是:http://ip:port/工程路径
1、/forwardC
2、servletContext.getRealPath("/");
3、request.getRequestDispatcher("/");
特殊情况:respone.sendRediect("/"); 把斜杠发生给浏览器解析。得到 http://ip:port/
HttpServletRespone 类 和HttpServletRequest 类一样。每次请求进来,Tomcat服务器都会创建一个 Respone 对象传递给 Servlet 程序去使用。HttpServletResquest 表示请求过来的信息,HttpServletRespone 表示所有响应的信息,
我们如果需要设置返回给客户端的信息,都可以通过 HttpServletRespone 对象进行设置
字节流 getOutputstream();
字符流 getWriter();
两个流同时只能使用一个。
使用了字节流,就不能使用字符流,反之亦然,否则就会报错
要求:往客户端回传 字符串 数据。
ResponseIOServlet
package com.aiguigu.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class ResponseIOServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.write("respone context!!!"); } }
运行结果:
输入中文会乱码:
解决响应乱码方案一:
ResponseIOServlet
package com.aiguigu.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class ResponseIOServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置服务器字符集为UTF-8 resp.setCharacterEncoding("UTF-8"); //通过响应头,设置浏览器也使用UTF-8字符集 resp.setHeader("Content-Type","text/html;charset=UTF-8 " ); // 要求:往客户端回传 字符串 数据 PrintWriter writer = resp.getWriter(); writer.write("这是中文"); } }
解决响应乱码方案二(推荐):
//它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头 //此方法一定要在获取流对象之前调用才有效 resp.setContentType("text/html;charset=UTF-8");
运行效果:
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端,我给你一些地址,你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃了)
tip:浏览器无法直接访问 WEB-INF 目录及其下的项目
代码实现:
Response1
package com.aiguigu.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class Response1 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("response1 到此一游"); req.setAttribute("key1","value1"); resp.setStatus(302); resp.setHeader("Location","http://localhost:8080/07_servlet/response2"); //resp.setHeader("Location","http://localhost:8080/07_servlet/WEB-INF/form.html"); } }
Response2
package com.aiguigu.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class Response2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write("response2 result"); System.out.println(req.getAttribute("key1")); } }
运行结果:
1、浏览器地址栏会发生变化
3、不共享域中数据
response1 到此一游 null
4、不能访问WEB-INF下的资源
第二种方式:
resp.sendRedirect("http://localhost:8080/07_servlet/response2");