Request
Request请求消息分四个部分:
- 请求行:
- 请求头:
- 请求空行:起分割作用
- 请求体:通过POST方式请求时,请求体中包含请求参数
各个部分说明:
1. 请求行:
请求行格式: 请求方式/请求url 请求协议/版本 如:GET /day14/demo3?username=liyan HTTP/1.1
请求方式: HTTP协议有7中请求方式,常用的有两种:
- GET: 请求参数在请求行中,如:GET /day14/demo3?username=liyan HTTP/1.1 请求的URL长度是有限制的 GET请求不太安全
- POST: 请求参数在请求体中,如:username=liyan 请求的URL长度没有限制 POST请求相对安全
2. 请求头:(浏览器告诉服务器的一些信息)
请求头格式:请求头名称:值,值,值... Host:主机 User-Agent:浏览器告诉服务器,我访问你使用的浏览器的版本信息
- 可以在服务器端获取该头信息,来解决浏览器的兼容性问题 Referer:http://localhost:8080/login.html 告诉服务器,当前请求从哪里来
- 防盗链
- 统计来源
... ...
图示:
3. 请求空行:
请求空行就是一个空行,起分割作用
4. 请求体(请求正文):封装POST请求消息的请求体的
- GET请求:没有请求体;
- POST请求:请求体中包含请求参数,如:username=liyan
图示:(在页面上写了两个输入框用来提交用户名和密码)
Servlet中的Request对象:
request对象和response对象的原理:
- request和response是由Tomcat服务器创建的,我们来使用;
- request对象是来获取请求消息的,response是来设置响应消息的。
request对象继承结构:
- Interface ServletRequest:是一个接口
- Interface HttpServletRequest:继承自ServletRequest
- org.apache.catalina.connector.RequestFacade:HttpServletRequest的实现类(Tomcat实现)
request获取功能:(获取请求数据)
1. 获取请求行数据:请求行数据的格式 (GET /day14/demo3?username=liyan HTTP/1.1)
- 获取请求方式:String getMethod();
- 获取虚拟目录:String getContextPath();
- 获取Servlet路径:String getServletPath();
- 获取get方式请求参数:String getQueryString();
- 获取请求URI:String getRequestURI();
- 获取请求URL:StringBuffer getRequestRUL(); URI:统一资源标识符 URL:统一资源定位符
- 获取连接协议和版本:String getProtocol();
- 获取客户机IP地址:String getRemoteAddr();
2. 获取请求头数据:
- String getHeader(String name); 通过请求头的名称获取请求头的值
- Enumeration getHeaderNames(); 获取所有请求头的名称
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
String s = names.nextElement();
System.out.println(s + "为:" + request.getHeader(s));
}
3. 获取请求体数据:
只有POST请求方式才有请求体,请求体中封装了POST请求的请求参数,获取步骤:
获取流对象:
BufferedReader getReader(); 获取字符输入流,只能操作字符数据。
BufferedReader对象可以通过调用readLine()方法返回字符串。
ServletInputStream getInputStream(); 获取字节输入流,可以操作所有类型的数据
在从流对象中拿数据:
BufferedReader bufferedReader = request.getReader();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
Request其他功能:
1. 获取请求参数(GET/POST通用方法):
1. String getParameter(String name); 根据参数名称获取参数值
2. String[] getParameterValues(String name); 根据参数名称获取参数值的数组
3. Enumeration<String> getParameterName(); 获取所有请求参数的名称
4. Map<String,String[]> getParameterMap();获取所有桉树的map集合
代码示例:
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;
@WebServlet("/requestDemo")
public class RequestDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如果是get方式请求,则调用post方法获取请求参数
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//post获取请求参数
//根据参数名称获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("post获取到的用户名:" + username + ",密码:" + password);
//根据参数名称获取参数,得到数据
String[] langs = req.getParameterValues("lang");
for (String lang : langs) {
System.out.println("获取到的lang:" + lang);
}
//获取所有请求参数的名称
Enumeration<String> parameterNames = req.getParameterNames();
System.out.println("所有请求参数名:");
while (parameterNames.hasMoreElements()) {
String name = parameterNames.nextElement();
String value = req.getParameter(name);
System.out.println("请求参数:" + name + ",值:" + value);
}
System.out.println("--------------------------------");
//获取所有参数,得到map集合
Map<String, String[]> parameterMap = req.getParameterMap();
for (String s : parameterMap.keySet()) {
System.out.print("请求参数:" + s +": ");
for (String val : parameterMap.get(s)) {
System.out.print(val+" ");
}
System.out.println();
}
}
}
中文乱码问题:
- get方式:Tomcat8已经解决了get方式的中文乱码问题
- post方式:在获取参数前,设置request的编码:req.setCharacterEncoding("utf-8");
2. 请求转发:一种在服务器内部资源跳转的方式
通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/demo2");// "/demo2"是要跳转到的Servlet类的urlPatterns
requestDispatcher.forward(request, response);
}
特点:
- 浏览器地址栏路径没有发生变化
- 只能转发到当前服务器的内部资源
- 转发是一次请求
3. 共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
- void setAttribute(String name,Object obj); 存储数据
- Object getAttribute(String name); 通过键获取值
- void removeAttribute(String name); 通过键移除数据
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo1被访问了~");
//存储数据到request域中,要在请求转发之前
request.setAttribute("msg","Hello");
//请求转发
request.getRequestDispatcher("/demo2").forward(request, response);
}
4. 获取ServletContext
ServletContext servletContext = request.getServletContext();
概念:ServletContext对象代表了整个Web应用,可以和程序的容器(服务器)来通信
获取:(在同一个Web应用中,无论哪种获取方式,获取到的ServletContext对象都是同一个)
- 通过request对象获取: request.getServletContext();
- 通过HttpServlet获取:this.getServletContext(); GenericServle()方式是其父类GenericServlet的方法
功能:
获取MIME类型:在互联网通信过程中定义的一种文件数据类型
格式:大类型/小类型,如:text/html image/jpeg
获取:String getMimeType(String file);
Mime类型是通过文件后缀获取到的,通过后缀映射到它对应的Mime类型,所有的映射关系都存储在Tomcat-->conf-->web.xml中。由于ServletContext对象能和Web容器通信,所以,可以访问到所有的映射关系,获取文件的Mime类型。
String mimeType = servletContext.getMimeType(fileName);
域对象:共享数据(ServletContext对象是域对象)
域对象有三个方法:
- void setAttribute(String name,Object obj); 存储数据
- Object getAttribute(String name); 通过键获取值
- void removeAttribute(String name); 通过键移除数据
ServletContext对象的范围:所有用户所有请求
获取文件的真实(服务器)路径
- 方法:String getRealPath(String path);
- 获取不同目录下文件的真是路径的获取方式:
String realPath1 = context.getRealPath("/WEB-INF/classes/1.txt");//src下的文件获取
String realPath2 = context.getRealPath("/2.txt");//web下的文件获取
String realPath3 = context.getRealPath("/WEB-INF/3.txt");//web->WEB-INF下的文件获取
扩展:BeanUtils工具类
可以把页面获取到的所有参数直接封装成JavaBean
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置编码
request.setCharacterEncoding("utf-8");
//2.获取所有参数
Map<String, String[]> parameterMap = request.getParameterMap();
//3.创建User对象
User loginUser = new User();
//使用BeanUtils封装
try {
BeanUtils.populate(loginUser,parameterMap);//使用BeanUtils中populate()
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//4.调用UserDao中login方法
UserDao dao = new UserDao();
User user = dao.login(loginUser);
//5.判断user
if(user==null){
request.getRequestDispatcher("/failServlet").forward(request,response);
}else {
request.setAttribute("user",user);
request.getRequestDispatcher("/successServlet").forward(request,response);
}
}
BeanUtils概述:
用于封装JavaBean,什么是JavaBean:
- JavaBean是表标准的Java类
- 类必须被public修饰
- 必须提供空参的构造器
- 成员变量必须使用private修饰
- 提供公共的setter/getter方法
概念:
- 成员变量:
- 属性:setter/getter方法截取后的产物
- 例如:getName()-->Name-->name
/**
*说明下属性的含义
*/
public class User {
private int id;
private String username;
private String password;
private String gender;//成员变量gender
public void setHehe(String gender){//setHehe来给成员变量gender赋值
this.gender = gender;
}
public String getHehe(){
return gender;
}
}
User user = new User();
BeanUtils.setProperty(user,"hehe","male");//设置属性hehe的值
String gender = BeanUtils.getProperty(user, "hehe");
上面说属性是setHehe()-->Hehe-->hehe后得到的这个hehe,通过hehe可以完成对JavaBean的赋值和取值。
- 方法:
- setProperty(); 设置属性值
- getProperty(); 获取属性值
- populate(); 封装JavaBean
注意:使用BeanUtils.populate()封装JavaBean时,请求参数的参数名(即页面中的name属性)要和实体类中的属性名一致,才能正常封装,不一致的话运行时会报错。