文章目录
Request 的学习
1. Request 对象和 Response 对象的原理
- Request 和 Response 对象是由服务器创建的。我们来使用它们
- Request 对象是来获取请求消息,Response 对象是来设置响应消息
2. Request 对象继承体系结构
从上到下依次为 继承、实现 关系
ServletRequest – 接口
HttpservletRequest – 接口
org.apache.cataline.connector.RequestFacade 类(tomcat)
3. request 功能
3.1. 获取请求消息数据
-
获取请求行数据
- GET / day04/login.html?name=zhangsan HTTP / 1.1
- 方法:
- 获取请求方法:GET
- String getMethod()
- 获取虚拟目录:/ day04
- String getContextPath()
- 获取 Servlet 路径:/login.html
- String SrevletPath()
- 获取 get 方式请求参数:name=zhangsan
- String getQueryString()
- 获取请求 URI :/ day04/login.html
- String getRequestURI() : / day04/login.html
- StringBuffer getRequestURL() : http://localhost/day04/login.html
- URL : 统一资源定位符: http://localhost/day04/login.html (表示的范围小) 中华人民共和国
- URI :统一资源标识符:/ day04/login.html (表示的范围大) 共和国
- 获取协议及版本:HTTP / 1.1
- String getProtocol()
- 获取客户机的 IP 地址:
- String getRemoteAddr()
package cn.cehcloud.web.request; 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; @WebServlet("*.com") public class RequestDemo01 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1.获取请求方法 String method = req.getMethod(); System.out.println(method); // 2.获取虚拟目录 String contextPath = req.getContextPath(); System.out.println(contextPath); // 3.获取 Servlet 路径 String servletPath = req.getServletPath(); System.out.println(servletPath); // 4.获取 get 方式请求参数 String queryString = req.getQueryString(); System.out.println(queryString); // 5.获取请求 URI String requestURI = req.getRequestURI(); System.out.println(requestURI); StringBuffer requestURL = req.getRequestURL(); System.out.println(requestURL); // 6.获取协议及版本 String protocol = req.getProtocol(); System.out.println(protocol); // 7.获取客户机的 IP 地址 String remoteAddr = req.getRemoteAddr(); System.out.println(remoteAddr); } }
-
获取请求头数据
- 方法:
- String getHeader(String name) : 通过请求头的名称获取请求头的值
- Enumeration getHeaderNames() :获取所有的请求头名称
package cn.cehcloud.web.request; 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; import java.util.Enumeration; @WebServlet("/requestDemo02") public class RequestDemo02 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 演示获取请求头数据 /*// 1.获取所有请求头名称 Enumeration<String> headerNames = req.getHeaderNames(); // 2.遍历 while (headerNames.hasMoreElements()){ String s = headerNames.nextElement(); // 根据名称获取请求头值 String header = req.getHeader(s); System.out.println(s + "---" + header); }*/ /*String agent = req.getHeader("user-agent"); // 判断agent的版本 if (agent.contains("Chrome")){ System.out.println("是谷歌没错啦!"); }else if (agent.contains("Firefox")){ System.out.println("是火狐没错啦!"); }*/ // 演示获取请求头数据:referer String referer = req.getHeader("referer"); System.out.println(referer); // 防盗链 if (referer != null){ if (referer.contains("/zlp")){ // 正常访问 System.out.println("正常的访问"); }else { // 盗链 System.out.println("非正常的访问"); } } } }
- 方法:
-
获取请求体数据:
-
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
-
步骤:
- 获取流对象
BffferedReader getReader():获取字符输入流,只能操作字符数据
ServletInputStream getInputStream():获取字节输入流,可以操作所有类型数据
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>regist</title> </head> <body> <form action="/requestDemo03" method="post"> <input type="text" name="username"><br> <input type="text" name="password"><br> <input type="submit" value="注册"> </form> </body> </html>
package cn.cehcloud.web.request; 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.BufferedReader; import java.io.IOException; @WebServlet("/requestDemo03") public class RequestDemo03 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取请求消息体--请求参数 // 1.获取字符流 BufferedReader reader = req.getReader(); // 2.读取数据 String line = null; while ((line = reader.readLine()) != null){ System.out.println(line); } } }
- 再从流对象中拿数据
-
3.2 其他功能
-
获取请求参数通用方法
- String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
- String[ ] getParametervalues(String name):根据参数名称获取参数值的数组 hobby=xxx&hobby=game
-
Enumeration<String[ ]> getParameternames():获取所有请求的参数名称
- Map<String,String[ ]> getParameterMap():获取所有参数的map集合
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>regist</title> </head> <body> <form action="/requestDemo04" method="post"> <input type="text" placeholder="请输入用户名" name="username"><br> <input type="text" placeholder="请输入密码" name="password"><br> <input type="checkbox" value="volleyball" name="hobby">排球 <input type="checkbox" value="guitar" name="hobby">吉他 <br> <input type="submit" value="注册"> </form> </body> </html>
package cn.cehcloud.web.request; 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; import java.util.Enumeration; import java.util.Map; import java.util.Set; @WebServlet("/requestDemo04") public class RequestDemo04 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("get"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // POST获取请求参数 // 根据参数名称获取参数值 String username = req.getParameter("username"); /* System.out.println("post"); System.out.println(username);*/ // 根据参数名称来获取参数值的数组 String[] hobbies = req.getParameterValues("hobby"); /*for (String hobby : hobbies){ System.out.println(hobby); }*/ // 获取所有请求的参数名称 Enumeration<String> parameterNames = req.getParameterNames(); /* while (parameterNames.hasMoreElements()){ String s = parameterNames.nextElement(); System.out.println(s); String parameter = req.getParameter(s); System.out.println(parameter); System.out.println("--------------"); }*/ // 获取所有参数的map集合 Map<String, String[]> parameterMap = req.getParameterMap(); // 遍历 Set<String> keySet = parameterMap.keySet(); for (String name: keySet) { // 获取键获取值 String[] values = parameterMap.get(name); System.out.println(name); for (String value : values){ System.out.println(value); } System.out.println("-------------"); } } }
- 中文乱码问题:
- get方式:tomcat 8 已经将get方式乱码问题解决了
- post方式:会乱码
- 解决:在获取参数前,设置 request 的编码 request.setCharacterEncoding(“utf-8”);
-
请求转发:一种在服务器内部的资源跳转方式
- 步骤:
- 通过 request 对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
- 使用 RequestDispatcher 对象来进行转发:forward(ServletRequest request,ServletResponse response)
- 特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中
- 转发是一次请求
package cn.cehcloud.web.request; 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 javax.xml.ws.WebFault; import java.io.IOException; @WebServlet("/requestDemo05") public class RequestDemo05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("demo5被访问了。。。"); // 转发到 demo04 资源 /*RequestDispatcher requestDispatcher = req.getRequestDispatcher("/requestDemo04"); requestDispatcher.forward(req,resp);*/ req.getRequestDispatcher("/requestDemo04").forward(req,resp); } }
-
共享数据
-
域对象:一个有作用范围的对象,可以在范围内共享数据
-
request 域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
-
方法:
- void setAttribute(String name,Object obj):存储数据
- Object getAttribute(String name):通过键获取值
- void removeAttribute(String name):通过键移除键值对
-
-
获取ServletContext
- ServletContext getServletContext()
小案例
要求:
-
编写 login.HTML 登录页面
username & password 两个输入框
-
使用 Druid 数据库连接池技术,操作 MySQL,test 数据库中的 user表
-
使用 JdbcTemplate 技术封装 JDBC
-
登录成功跳转到 SuccessServlet 展示:登录成功!用户名,欢迎你
-
登录失败跳转到 FailServlet 展示:登录失败,用户名或密码错误
-
- 分析 开发步骤:
- 创建项目,导入到 html 页面,配置文件,jar包
- 创建数据库环境
- 创建包 cn.cehcloud.domain,创建类User
- 创建包 cn.cehcloud.dao,创建类 UserDao,提供 login 方法
- 创建包 cn.cehcloud.dao,创建类 UserDao,提供 login 方法
- 编写 cn.cehcloud.web.servlet.loginServlet 类
- login.html 中 form 表单的 action 路径的写法
- 虚拟目录 + Servlet 的资源路径