在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求头和请求体三部分,因此,在HttpServletRequest接口中定义了获取请求行、请求头和请求消息体的相关方法.
用自己的话来理解: Request就是服务器中的一个对象,该对象中封装了HTTP请求的请求行、请求头和请求体的内容
获取HTTP请求三部分内容(行,头,体)
进行请求转发跳转
作为请求域对象进行存取数据
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用request对象获取请求行的信息:
//1. 获取请求的方式(可能会用)
String method = request.getMethod();
//System.out.println("请求方式为:" + method);;
//2. 获取请求的url: 统一资源定位符 http://localhost:8080/requestDemo/demo01
String url = request.getRequestURL().toString();
//System.out.println("此次请求的url是:" + url);
//3. 获取请求的uri: 统一资源标识符,在url的基础上省略了服务器路径"http://loaclhost:8080"
String uri = request.getRequestURI();
System.out.println(uri);
}
}
public class ServletDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//根据请求头的name获取value
//目标:获取name为user-agent的请求头的信息
//user-agent请求头中包含的是客户端浏览器信息
String header = request.getHeader("user-agent");
System.out.println("获取的请求头agent为:" + header);
}
}
请求参数是客户端携带给服务器的由键值对组成的数据,例如"username=aobama&password=123456"这种类型的数据
URL地址后面附着的请求参数,例如http://localhost:8080/app/hellServlet?username=汤姆
表单携带请求参数
Ajax请求携带请求参数
| 方法名 | 返回值类型 | 方法描述 |
|---|---|---|
| request.getParameterMap() | Map | 获取当前请求的所有参数,以键值对的方式存储到Map中 |
| request.getParameter(“请求参数的名字”) | String | 根据一个参数名获取一个参数值 |
| request.getParameterValues(“请求参数的名字”) | String [] | 根据一个参数名获取多个参数值 |
| request.getParameterNames() | Enumeration | 获取当前请求的所有参数的参数名 |
HTML代码
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发送请求携带请求参数title>
head>
<body>
<a href="/webday0601/demo02?username=aobama&password=123456">访问ServletDemo02a><br/>
<form action="/webday0601/demo02" method="get">
用户名<input type="text" name="username"/><br/>
密码<input type="text" name="password"/><br/>
昵称<input type="text" name="nickname"/><br/>
邮箱<input type="text" name="email"/><br/>
兴趣爱好<input type="checkbox" name="hobby" value="basketball"/>篮球
<input type="checkbox" name="hobby" value="football"/>足球
<input type="checkbox" name="hobby" value="yumaoball"/>羽毛球
<input type="checkbox" name="hobby" value="pingpangball"/>乒乓球<br/>
<button type="submit">提交button>
form>
body>
html>
Java代码
package com.aqrlmy.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;
import java.util.Map;
/**
* @author Leevi
* 日期2021-06-08 09:09
* HttpServletRequest的作用三:
* 获取请求参数的信息:1. url地址后边通过"?"拼接的内容 2. 表单使用POST请求在请求体中提交请求参数
* 方式:
* 1. getParameter(name):根据一个参数名获取一个参数值
* 2. getParameterValues(name):根据一个参数名获取多个参数值
* 3. getParameterMap():获取这次请求中的所有请求参数,并且封装到Map中
*/
public class ServletDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. getParameter(name):根据一个参数名获取一个参数值
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("获取到的请求参数username=" + username + ",password=" + password);
//2. getParameterValues(name):根据一个参数名获取多个参数值
String[] hobbies = request.getParameterValues("hobby");
System.out.println(Arrays.toString(hobbies));
//3. 获取所有的请求参数,并且将那些请求参数封装到一个Map集合中,那么请求参数的参数名就是map的key,请求参数的参数值就是map的value
//该Map的key是String类型就对应请求参数的参数名,该Map的value是String[]类型就对应请求参数的参数值
Map<String, String[]> parameterMap = request.getParameterMap();
//遍历打印Map中的数据
parameterMap.forEach((k,v) -> {
System.out.println(k + ":" + Arrays.toString(v));
} );
}
}
因为客户端发送给请求参数给服务器的时候需要进行编码,将字符串编码成二进制才能够在网络中传输,而服务器在接收到二进制之后需要进行解码才能够获取真正的请求参数;在这个过程中如果保证客户端编码使用的字符集和服务器解码使用的字符集相同的话,基本上(只要采用正确的够用的字符集)就不会发生乱码了;而发生乱码的原因是因为使用了错误的字符集,或者是客户端与服务器端所采用的字符集不一致。
当前使用的Tomcat的版本是Tomcat8以上,所以不需要考虑GET方式乱码的问题,因为Tomcat8及以上版本已经在配置中解决了GET请求乱码的问题。只需要解决POST请求乱码问题
解决POST请求的参数乱码只需要在获取请求参数前调用request.setCharacterEncoding("UTF-8")就行了
请求转发是从一个资源跳转到另一个资源,在这个过程中客户端不会发起新的请求
从ServletDemo03使用请求转发的方式跳转到ServletDemo04
request.getRequestDispatcher("路径").forward(request,response);
ServletDemo03的代码
public class ServletDemo03 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo03执行了...")
//请求转发跳转到ServletDemo04
request.getRequestDispatcher("/demo04").forward(request, response);
}
}
ServletDemo04的代码
public class ServletDemo04 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo04执行了...")
}
}
之前学过全局域的范围,全局域是整个项目范围的所有动态资源都能够共享的一个范围;而请求域的范围只是在一次请求中的动态资源能够共享的一个范围
request.setAttribute(key,value)request.getAttribute(key)在ServletDemo03中往请求域中存入"username"作为key,"aobama"作为值的键值对;然后在ServletDemo04中从请求域中根据"username"取出对应的值
请求域对象一定要和请求转发一起使用,因为请求域的范围是一次请求范围内,所以要在两个动态资源中使用请求域必须要进行请求转发跳转
ServletDemo03的代码
public class ServletDemo03 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo03执行了...")
String username = "aobama";
//将username存储到request域对象中
request.setAttribute("username",username);
//请求转发跳转到ServletDemo04
request.getRequestDispatcher("/demo04").forward(request, response);
}
}
ServletDemo04的代码
public class ServletDemo04 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = (String)request.getAttribute("username");
System.out.println("在ServletDemo04中获取username:"+username)
}
}
JavaBean是使用Java语言编写的可重用组件,在项目中JavaBean主要用于存储内存中的数据,以及提供方法便于使用者获取数据
public class User {
private Integer id;
private String username;
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
'}';
}
}
优点:
缺点:
优点:
缺点:
代码量增多,需要花时间去封装JavaBean类
通常情况下,会选择使用JavaBean来存储内存中的数据,除非是非常简单的数据没有必要多编写一个JavaBean类的时候才会选择使用Map进行存储
将Map中的数据填充到JavaBean对象中
BeanUtils.populate(map对象,JavaBean.class);
在Servlet API中,定义了一个HttpServletResponse接口(doGet,doPost方法的参数),它继承自ServletResponse接口,专门用来封装HTTP响应消息。由于HTTP响应消息分为响应行、响应头、响应体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应头、响应体的方法
用自己的话说: Response就是服务器端一个对象,它里面可以封装要响应给客户端的响应行、头、体的信息
response.setStatus(状态码);
//1. 获取字符输出流
PrintWriter writer = response.getWriter();
//2. 输出内容
writer.write("hello world");
由于服务器端在输出内容的时候进行编码使用的字符集和客户端进行解码的时候使用的字符集不一致,所以会发生响应数据乱码问题。
解决响应数据乱码问题只需要在获取字符输出流之前,执行如下代码就可以了:
response.setContentType("text/html;charset=UTF-8");
ServletOutputStream os = response.getOutputStream();
在ServletDemo01中使用response向浏览器输出一张图片
package com.aqrlmy.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
/**
* @author Leevi
* 日期2021-06-08 14:16
* 使用response:
* 1. 设置响应状态码: setStatus(状态码)
* 常见的状态码:200请求成功、302重定向、403权限拒绝、404资源未找到、500服务器异常
* 2. 设置响应体的内容:
* 2.1 向浏览器输出超文本: response.getWriter().write("文本"),此时如果输出的是中文就会出现中文乱码问题
* 解决中文乱码问题: response.setContentType("text/html;charset=UTF-8")
* 2.2 向浏览器输出文件: response.getOutputStream();获取字节输出流,就可以向客户端输出文件
*/
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应状态码
//response.setStatus(403);
//使用response向浏览器输出一个超文本(字符串)
//解决输出中文文本时候的乱码问题
//response.setContentType("text/html;charset=UTF-8");
//response.getWriter().write("你好世界
");
//当用户访问ServletDemo01的时候,要向客户端输出一张图片:img/mm.jpg
//1. 使用字节输入流读取img里面的那张mm.jpg
//1.2 使用ServletContext对象的getRealPath()方法动态获取mm.jpg的部署目录下的路径
String realPath = getServletContext().getRealPath("img/mm.jpg");
FileInputStream is = new FileInputStream(realPath);
//2. 使用字节输出流将读取到的字节输出到浏览器
//2.1 定义一个缓冲区
byte[] buffer = new byte[1024];
//2.2 定义一个读取到的字节的长度
int len = 0;
//2.3 获取输出流
ServletOutputStream os = response.getOutputStream();
//2.4 使用while循环进行边读编写
while ((len = is.read(buffer)) != -1){
//写
os.write(buffer,0,len);
}
//关流
os.close();
is.close();
}
}
重定向是由项目中的一个资源跳转到另一个资源,在这个过程中客户端会发起新的请求
从ServletDemo02重定向跳转到ServletDemo03
response.sendRedirect("路径");
ServletDemo02的代码
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo02执行了...")
//请求转发跳转到ServletDemo02
response.sendRedirect("/webday0602/demo03");
}
}
ServletDemo03的代码
public class ServletDemo03 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("在ServletDemo03执行了.....")
}
}



如果Module中包含lib,则取消勾选lib,然后再点击Next

然后一直点Next,直到Finish,如果出现下面的弹框则按要求点击即可
在Project Structure面板选择Modules,找到当前Module,并且选择Dependencies面板,添加Tomcat依赖




