目录
- 1 请求对象
- 1.1 请求对象介绍
- 1.2 请求对象常用方法-获取各自路径
- 1.3 请求对象常用方法-获取请求头信息
- 1.4 请求对象常用方法-请求参数信息
- 1.5 获取请求参数并封装对象
- 1.5.1 手动封装方式
- 1.5.2 反射封装方式
- 1.5.3 工具类封装方式
- 1.6 流对象获取请求信息
- 1.7 中文乱码问题
- 1.8 请求域
- 1.9 请求转发
- 1.10 请求包含
- 2 响应对象
- 2.1 响应对象介绍
- 2.2 常见状态码
- 2.3 字节流响应消息
- 2.4 字符流响应消息
- 2.5 响应图片
- 2.6 设置缓存
- 2.7 定时刷新
- 2.8 请求重定向
- 2.9 文件下载
1 请求对象
1.1 请求对象介绍
- 请求:获取资源。在 BS 架构中,就是客户端浏览器想服务器端发出询问
- 请求对象:就是在项目中用于发送请求的对象
1.2 请求对象常用方法-获取各自路径
- 代码演示
package com.txt.servlet;
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("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取虚拟目录名称
String contextPath = req.getContextPath();
System.out.println(contextPath);
//2.获取Servlet映射路径
String servletPath = req.getServletPath();
System.out.println(servletPath);
//3.获取访问者ip
String ip = req.getRemoteAddr();
System.out.println(ip);
//4.获取请求消息数据
String queryString = req.getQueryString();
System.out.println(queryString);
//5.获取统一资源标识符
String requestURI = req.getRequestURI();
System.out.println(requestURI);
//6.获取统一资源定位符
StringBuffer requestURL = req.getRequestURL();
System.out.println(requestURL);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 演示效果:
1.3 请求对象常用方法-获取请求头信息
- 代码演示:
package com.txt.servlet;
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("/servletDemo02")
public class ServletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//根据请求头名称获取一个值
String connection = req.getHeader("connection");
System.out.println(connection);
System.out.println("-----------------------");
//根据请求头的名称获取多个值
Enumeration<String> headers = req.getHeaders("accept-encoding");
while(headers.hasMoreElements()){
String header = headers.nextElement();
System.out.println(header);
}
System.out.println("-----------------------");
//获取所有的请求头名称
Enumeration<String> names = req.getHeaderNames();
while (names.hasMoreElements()){
String name = names.nextElement();
String value = req.getHeader(name);
System.out.println(name + ":" +value);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 效果如下:
1.4 请求对象常用方法-请求参数信息
- 代码演示
package com.txt.servlet;
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("/servletDemo03")
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 根据名称获取数据
String username = req.getParameter("username");
System.out.println(username);
String pwd = req.getParameter("pwd");
System.out.println(pwd);
System.out.println("---------------------------------");
//2.根据名称获取所有数据
String[] hobbies = req.getParameterValues("hobby");
for (String hobby : hobbies){
System.out.println(hobby);
}
System.out.println("---------------------------------");
//3.获取所有名称
Enumeration<String> names = req.getParameterNames();
while(names.hasMoreElements()){
String name = names.nextElement();
System.out.println(name);
}
System.out.println("---------------------------------");
//获取所有参数的键值对
Map<String, String[]> map = req.getParameterMap();
for (String key : map.keySet()){
String[] values = map.get(key);
System.out.print(key + ":");
for (String value : values){
System.out.print(value + " ");
}
System.out.println();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 效果如下
1.5 获取请求参数并封装对象
- 手动封装方式
- 反射封装方式
- 工具类封装方式
1.5.1 手动封装方式
- 代码演示
package com.txt.servlet;
import com.txt.bean.Student;
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("/servletDemo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
String[] hobbies = req.getParameterValues("hobby");
//2.封装学生对象
Student stu = new Student(username,pwd,hobbies);
//输出对象
System.out.println(stu);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
//学生类
package com.txt.bean;
import java.util.Arrays;
public class Student {
private String username;
private String pwd;
private String[] hobby;
public Student() {
}
public Student(String username, String pwd, String[] hobby) {
this.username = username;
this.pwd = pwd;
this.hobby = hobby;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
@Override
public String toString() {
return "Student{" +
"username='" + username + '\'' +
", pwd='" + pwd + '\'' +
", hobby=" + Arrays.toString(hobby) +
'}';
}
}
- 效果如下:
1.5.2 反射封装方式
- 代码演示
package com.txt.servlet;
import com.txt.bean.Student;
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.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
//反射封装方式
@WebServlet("/servletDemo05")
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
Map<String, String[]> map = req.getParameterMap();
//2.封装学生对象
Student stu = new Student();
//2.1 遍历集合
for (String name : map.keySet()){
String[] value = map.get(name);
//2.2 获取 Student对象的属性描述器
try {
PropertyDescriptor pd = new PropertyDescriptor(name,stu.getClass());
//2.3 获取对应的setXxx方法
Method writeMethod = pd.getWriteMethod();
//执行方法
if (value.length > 1){
writeMethod.invoke(stu,(Object) value);
}else {
writeMethod.invoke(stu,value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//输出对象
System.out.println(stu);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.5.3 工具类封装方式
我们需要引入jar包
- 代码演示
package com.txt.servlet;
import com.txt.bean.Student;
import org.apache.commons.beanutils.BeanUtils;
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.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
//工具类封装方式
@WebServlet("/servletDemo06")
public class ServletDemo06 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取所有的数据
Map<String, String[]> map = req.getParameterMap();
//2.封装学生对象
Student stu = new Student();
try {
BeanUtils.populate(stu,map);
} catch (Exception e) {
throw new RuntimeException(e);
}
//输出对象
System.out.println(stu);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.6 流对象获取请求信息
- 代码演示
package com.txt.servlet;
import com.txt.bean.Student;
import org.apache.commons.beanutils.BeanUtils;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
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;
import java.util.Map;
@WebServlet("/servletDemo07")
public class ServletDemo07 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//字符流(必须是post方式)
/*BufferedReader br = req.getReader();
String line;
while ((line = br.readLine()) != null){
System.out.println(line);
}*/
//字节流
ServletInputStream is = req.getInputStream();
byte[] arr = new byte[1024];
int len;
while ((len = is.read(arr)) != -1){
System.out.println(new String(arr,0,len));
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 效果如下
1.7 中文乱码问题
- GET 方式
没有乱码问题,在 Tomcat 8 版本后已经解决 - POST 方式
有乱码问题。可以通过 setCharacterEncoding() 方法来解决- 代码演示
package com.txt.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
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("/servletDemo08")
public class ServletDemo08 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
System.out.println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.8 请求域
- 请求域(request 域):可以再一次请求范围内进行共享数据
- 一般用于请求转发的多个资源中共享数据
- 请求对象操作共享数据方法
1.9 请求转发
- 请求转发:客户端的一次请求到达后,发现需要借助其他 Servlet 来实现功能
- 特点
- 浏览器地址栏不变
- 域对象中的数据不丢失
- 负责转发的 Servlet 转发前后的响应正文会丢失
- 由转发的目的地来响应客户端
- 代码演示
servletDemo09:
package com.txt.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;
//工具类封装方式
@WebServlet("/servletDemo09")
public class ServletDemo09 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置共享数据
req.setAttribute("encoding","gbk");
//获取请求调度对象
RequestDispatcher rd = req.getRequestDispatcher("/servletDemo10");
//实现转发功能
rd.forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
servletDemo10:
package com.txt.servlet;
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("/servletDemo10")
public class ServletDemo10 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取共享数据
Object encoding = req.getAttribute("encoding");
System.out.println(encoding);
System.out.println("servletDemo10 执行了...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
1.10 请求包含
- 请求包含:可以合并其他 Servlet 中的功能一起响应给客户端
- 特点:
- 浏览器地址栏不变
- 域对象中的数据不会丢失
- 被包含的 Servlet 的响应头会丢失
2 响应对象
2.1 响应对象介绍
- 响应:回馈结果。在 BS 架构中,就是服务器给客户端浏览器反馈结果。
- 响应对象:就是在项目中用于发送响应的对象
2.2 常见状态码
2.3 字节流响应消息
- 代码演示
package com.txt.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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.nio.charset.StandardCharsets;
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setContentType("text/html;charset=UTF-8");
//获取字节流输出对象
ServletOutputStream os = resp.getOutputStream();
//定义一个消息
String str = "你好";
//通过字节流对象输出
os.write(str.getBytes(StandardCharsets.UTF_8));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.4 字符流响应消息
- 代码演示
package com.txt.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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.io.PrintWriter;
import java.nio.charset.StandardCharsets;
//字符流响应消息
@WebServlet("/servletDemo02")
public class ServletDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setContentType("text/html;charset=UTF-8");
//获取字符输出流对象
PrintWriter pw = resp.getWriter();
//准备一个消息
String str = "你好";
//通过字符输出流输出
pw.write(str);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.5 响应图片
- 创建字节输入流对象,关联读取的图片路径
- 通过响应对象获取字节输出流对象
- 循环读取和写出图片
package com.txt.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
//响应图片
@WebServlet("/servletDemo03")
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过文件相对路径获取绝对路径
String realPath = getServletContext().getRealPath("/img/qiu.jpg");
// 1. 创建字节输入流对象,关联读取的图片路径
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));
// 2. 通过响应对象获取字节输出流对象
ServletOutputStream os = resp.getOutputStream();
// 3. 循环读取和写出图片
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1){
os.write(bys,0,len);
}
//释放资源
bis.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.6 设置缓存
- 缓存:对于不经常变化的数据,我们可以设置合理缓存时间,以避免浏览器频繁请求服务器,以此来提高效率!
- 代码演示
package com.txt.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
//设置缓存
@WebServlet("/servletDemo04")
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String news = "这是一条很火爆的新闻";
//设置缓存 1小时的缓存时间
resp.setDateHeader("Expires",System.currentTimeMillis() + 60 * 60 * 1000);
//设置编码
resp.setContentType("text/html;charset=UTF-8");
//写出数据
resp.getWriter().write(news);
System.out.println("aaa");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.7 定时刷新
- 定时刷新:过了指定时间后,页面自动进行跳转
- 代码演示
package com.txt.servlet;
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("/servletDemo05")
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = "您的用户名和密码有误,3秒后自动跳转到登录页面";
//设置编码格式
resp.setContentType("text/html;charset=UTF-8");
//写数据
resp.getWriter().write(str);
resp.setHeader("Refresh","3;URL=/response/login.html");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
2.8 请求重定向
- 请求重定向:客户端的一次请求到达后,发现需要借助其他 Servlet 来实现功能
- 特点:浏览器地址栏会发生改变,两次请求、请求域对象中不能共享数据,可以重定向到其他服务器
- 响应对象重定向方法
- 代码演示
ServletDemo06
package com.txt.servlet;
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("/servletDemo06")
public class ServletDemo06 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo06 执行了...");
//设置共享数据
req.setAttribute("username","zhangsan");
//请求重定向
resp.sendRedirect(req.getContextPath() + "/servletDemo07");
// resp.sendRedirect("https://www.baidu.com");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
ServletDemo07
package com.txt.servlet;
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("/servletDemo07")
public class ServletDemo07 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("servletDemo07 执行了...");
//获取共享数据
Object username = req.getAttribute("username");
System.out.println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 运行效果
2.9 文件下载
- 创建字节输入流,关联读取文件
- 设置响应消息头支持的类型
- 设置响应消息头以下载方式打开资源
- 通过响应对象获取字节输出流对象
- 循环读写
- 释放资源
- 代码演示
package com.txt.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
//文件下载
@WebServlet("/servletDemo08")
public class ServletDemo08 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 创建字节输入流,关联读取文件
String realPath = getServletContext().getRealPath("/img/qiu.jpg");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));
// 2. 设置响应消息头支持的类型
resp.setHeader("Content-Type","application/octet-stream");
// 3. 设置响应消息头以下载方式打开资源
resp.setHeader("Content-Disposition","attachment;filename=qiu.jpg");
// 4. 通过响应对象获取字节输出流对象
ServletOutputStream os = resp.getOutputStream();
// 5. 循环读写
byte[] bys = new byte[1024];
int len;
while ((len = bis.read(bys)) != -1){
os.write(bys,0,len);
}
// 6. 释放资源
bis.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}