1.请求对象
获取资源,发送请求
请求对象获取路径常用方法 代码如下:
//获取请求参数信息的方法
@WebServlet("/requestDemo01")
public class requestDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//根据名称获取数据
String username = req.getParameter("username");
System.out.println(username);
String age = req.getParameter("age");
System.out.println(age);
System.out.println("_____________________");
//根据名称获取所有数据
String[] hobbies = req.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
System.out.println("_____________________");
//获取所有名称
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);
for (String value : values) {
System.out.println(value);
}
}
System.out.println("________________________");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
手动封装对象 代码如下:
//手动封装对象
@WebServlet("/requestDemo02")
public class requestDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
Student stu = new Student(username,password,hobbies);
System.out.println(stu);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
使用工具类封装对象 代码如下:
//工具类封装对象
@WebServlet("/requestDemo03")
public class requestDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取所有数据键值对
Map<String, String[]> map = req.getParameterMap();
//创建学生对象
Student stu = new Student();
/**
* 用工具类封装对象
* 工具类的底层是通过对象的属性描述器
* new PropertyDescriptor(name,stu.getClass()); 得到类的字节码文件
* 再来获取setxxx方法和getxxx方法 getWriteMethod();
* 然后通过invoke()方法执行
* */
try {
BeanUtils.populate(stu,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//输出对象
System.out.println(stu);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
请求中文乱码问题:
req.setCharacterEncoding(“UTF-8”);
请求转发 代码如下:
//请求转发
@WebServlet("/requestDemo05")
public class requestDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置共享数据
req.setAttribute("username","zhangsan");
//获取请求参数对象
RequestDispatcher bak = req.getRequestDispatcher("requestDemo05bak");
//转发 req和resp向下传递
bak.forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
//获取共享数据
@WebServlet("/requestDemo05bak")
public class requestDemo05bak extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object username = req.getAttribute("username");
System.out.println(username);
System.out.println("requestDemo05bak执行啦...");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
当Demo05发起请求,并设置了请求域共享数据,通过请求参数对象,可以在Demo05bak中获取到域中数据
请求域
是什么?
可以再一次请求范围内进行共享数据
一般用于请求转发的多个资源中共享数据
请求转发
一次请求
客户端的一次请求到达后,发现需要借助其他的Servlet来实现功能
特点:
浏览器地址栏不变
域对象中数据不会丢失
负责转发的Servlet转发后响应正文会丢失
由转发的目的地来响应客户端
getRequestDispatcher(String name)获取请求调度对象
forward(ServletRequest req, ServletResponse resp)转发
2.响应对象
回馈结果,服务器给客户端浏览器反馈结果
响应对象:就是在项目中用于发送响应的对象
常见状态码:
200成功
302重定向
304请求资源未改变,使用缓存
400:请求错误
404:请求资源未找到
405:请求方式不支持
500:服务器错误
字节流响应和乱码问题 代码如下:
//字节流响应消息和解决响应乱码问题
@WebServlet("/responseDemo01")
public class responseDemo01 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("UTF-8"));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
响应图片 代码如下:
@WebServlet("/responseDemo02")
public class responseDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取项目发布在tomcat的真实路径
String realPath = getServletContext().getRealPath("/img/hm.png");
//获取输入流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath));
//获取servlet输出流对象
ServletOutputStream os = resp.getOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
os.write(bytes,0,len);
}
bis.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
设置定时刷新
@WebServlet("/responseDemo03")
public class responseDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String str = "您的用户名或密码有误,三秒后跳转...";
//设置编码格式
resp.setContentType("text/html;charset=UTF-8");
//响应出数据
resp.getWriter().write(str);
//设置定时刷新
resp.setHeader("Refresh","3,URL=/aaa/login.html");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
重定向
@WebServlet("/responseDemo04")
public class responseDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置请求域共享数据
req.setAttribute("username","zhangsan");
//设置重定向 动态获取虚拟路径
resp.sendRedirect(req.getContextPath()+"/responseDemo04bak");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
@WebServlet("/responseDemo04bak")
public class responseDemo04bak extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//因为重定向是两次请求,所以获取不到数据
String usernmae = req.getParameter("usernmae");
System.out.println(usernmae);
System.out.println("responseDemo04bak执行啦....");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
当Demo04发起请求,并设置共享数据,Demo04bak并不会获取到域中数据,因为重定向是两次请求,地址栏发生了变化
文件下载 代码如下:
@WebServlet("/responseDemo05")
public class responseDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取ServletContext对象
ServletContext context = req.getServletContext();
//获取文件在tomcat的真实路径
String path = context.getRealPath("/img/hm.png");
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
//设置随机id
UUID uuid = UUID.randomUUID();
//告诉浏览器以下载的方式打开
resp.setHeader("content-disposition", "attachment;filename=" + uuid + ".png");
//获取响应输出流
ServletOutputStream os = resp.getOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
os.write(bytes,0,len);
}
bis.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.转发和重定向区别
请求是只发起一次请求,并且是在站点内资源的跳转,需要其他Servlet实现功能,地址栏不会发生变化
可以理解为 你来找我借钱------>>我没有------->>我找别人借------>>然后给你
重定向是多次请求,可以跳转到别的站点内,需要其他Servlet实现功能,地址栏会发生变化
可以理解为 苍老师来找你-------->>你说你不行,你没有,我给你个地址你找我好兄弟---------->>苍老师按照地址找到了我
4.结合以上知识 综合案例
流程分析:
index.html---------添加学生------>>addStudentServlet.html------保存(跳转)---->>addStudentServlet(获取数据,赋值,保存到文件中)-------响应跳转到首页-----查看学生---------->>listStudentServlet(读取本地文件,封装到Student对象中,讲对象保存到集合中,遍历通过输出流响应给客户端浏览器)
代码如下:
(1)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生管理系统</title>
</head>
<body>
<a href="/aaa/addStudentServlet.html">添加学生</a>
<a href="/aaa/listStudentServlet">查看学生</a>
</body>
</html>
(2)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加学生</title>
</head>
<body>
<form action="/aaa/addStudentServlet" method="post" autocomplete="off">
学生姓名:<input type="text" name="username"><br>
学生年龄:<input type="number" name="age"><br>
学生成绩:<input type="number" name="score"><br>
<button type="submit">保存</button>
</form>
</body>
</html>
(3)
@WebServlet("/addStudentServlet")
public class addStudnetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取表单数据
String username = req.getParameter("username");
String age = req.getParameter("age");
String score = req.getParameter("score");
//创建学生对象并赋值
Student stu = new Student();
stu.setUsername(username);
stu.setAge(Integer.parseInt(age));
stu.setScore(Integer.parseInt(score));
//将学生对象保存到文件中
BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\stu.txt", true));
bw.write(stu.getUsername()+","+stu.getAge()+","+stu.getScore());
bw.newLine();
bw.close();
//通过定时刷新功能响应给浏览器
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("两秒后跳转到首页...");
//定时刷新
resp.setHeader("Refresh","2;URL=/aaa/index.html");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
(4) 代码(1)
(5)
@WebServlet("/listStudentServlet")
public class listStudentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建字节输入流读取文件
BufferedReader br = new BufferedReader(new FileReader("d:\\stu.txt"));
//创建集合对象保存Studnet对象
ArrayList<Student> list = new ArrayList();
//循环读取文件中的数据,将对象封装到Studnet对象中,再将多个学生对象保存到集合中
String len;
while ((len = br.readLine()) != null) {
Student stu = new Student();
String[] arr = len.split(",");
stu.setUsername(arr[0]);
stu.setAge(Integer.parseInt(arr[1]));
stu.setScore(Integer.parseInt(arr[2]));
list.add(stu);
}
//遍历集合,将数据展示给浏览器
//设置响应乱码
resp.setContentType("text/html;charset=UTF-8");
//获取响应输出流对象
PrintWriter pw = resp.getWriter();
for (Student s : list) {
System.out.println(s.getUsername()+","+s.getAge()+","+s.getScore());
System.out.println("
");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}