请求:获取资源。在 BS 架构中,就是客户端浏览器向服务器端发出询问,请求获取资源html
请求对象:就是在项目当中用于发送请求的对象java
咱们经常使用的对象就是ServletRequest和HttpServletRequest,它们的区别就是是否和HTTP协议有关web
先了解便可,接下来咱们会一步一步介绍apache
获取路径方法windows
getQueryString,获取请求的数据,好比url问号后边的数据数组
URI是以一种抽象的,高层次概念定义统一资源标识,而URL则是具体的资源标识的方式浏览器
URI比URL范围大,URL是URI的一种缓存
url?后边的请求参数,也能够叫作查询字符串 (请求动做是查询,把请求参数做为查询关键字)tomcat
重点方法:getContextPath,getQueryString,getRequestURI服务器
案例:新建项目request_demo,新建类com.itheima.servlet.ServletDemo01
这里的项目须要是java ee 8 ,咱们要用注解注册Servlet
package com.itheima.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;
/*
获取路径的相关方法
*/
访问
获取请求头
有的请求头是有多个值,因此能够经过getHeaders方法获取
好比:accept-encoding,他的值就有多个:gzip,deflate,br
案例:新建ServletDemo02
package com.itheima.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;
/*
获取请求头信息的相关方法
*/
访问
获取请求头参数
若是请求参数只有一个值,经过getParameter获取,好比:text
若是请求参数有多个值,经过getParameterValues获取,好比:checkbox
重点掌握:getParameter,getParameterMap
案例:新建web/register.html
新建ServletDemo03
package com.itheima.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;
/*
获取请求参数信息的相关方法
*/
访问
咱们经过上面的方法能够获取到请求参数,可是若是参数过多,在进行传递时,方法的形参定义将会变得很是难看
此时咱们应该用一个对象来描述这些参数,它就是实体类。这种类的定义,从基础阶段咱们就开始使用了
在基础阶段,咱们作过一个学生管理系统,用到了一个Student的类,它就是用于描述一个学生的实体类
咱们如今要作的就是把表单中提交过来的数据填充到实体类中
案例:新建com.itheima.bean.Student
package com.itheima.bean;
import java.util.Arrays;
public class Student {
private String username;
private String password;
private String[] hobby;
public Student() {
}
public Student(String username, String password, String[] hobby) {
this.username = username;
this.password = password;
this.hobby = hobby;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
新建ServletDemo04
package com.itheima.servlet;
import com.itheima.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;
/*
封装对象-手动方式
*/
修改register.html
<form action="/request/servletDemo04">
访问
问题:若是获取的参数有10个,那么就须要写十次String xx= req.getParameter("xx");
,这样太麻烦
那咱们就能够采用反射封装对象方式
此种封装的使用要求是,表单<input>
标签的name属性取值,必须和实体类中定义的属性名称一致
案例:新建ServletDemo05
package com.itheima.servlet;
import com.itheima.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.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
/*
封装对象-反射方式(使用反射+内省实现数据模型的封装)
* 内省:是sun公司推出的一套简化反射操做的规范。把javabean中的属性都封装成一个属性描述器。
* 属性描述器中会有字段信息,get和set方法(取值或存值)
*/
修改register.html
<form action="/request/servletDemo05" >
访问
上述的操做仍是都太麻烦,能不能直接调用现成的工具呢?
能够,使用apache的beanutils包
copy jar包
“day03_请求响应\资料\beanutils的jar包”下全部的包,copy到“项目/web/WEB-INF/libs”下
而后添加到项目引用库
案例:新建ServletDemo06
package com.itheima.servlet;
import com.itheima.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.io.IOException;
import java.util.Map;
/*
封装对象-工具类方式
*/
修改register.html
<form action="/request/servletDemo06">
访问 : 经过register.html点击注册以后,跳转过去发现报错
报错信息说是,找不到BeanUtils
咱们刚刚不是添加到项目引用库中了么?注意咱们如今的项目是须要部署到tomcat的,项目中有了,可是部署到tomcat的war包中尚未,因此须要特殊处理一下:
File - Project Structure
访问
除了上述方式能够获取请求信息,还能够经过流来获取
BufferedReader了解便可
ServletInputStream经常使用于获取图片,文件 ***
案例:新建ServletDemo07
package com.itheima.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;
/*
流对象获取数据
*/
修改 register.html
<!--若是是字符流,post请求方式-->
<form action="/request/servletDemo07" method="post">
访问
流方式获取到的中文,会进行编码,因此看到的姓名是编码后的
GET 方式
没有乱码问题。在 Tomcat 8.5 版本后已经解决
POST 方式
有乱码问题。能够经过 setCharacterEncoding() 方法来解决
案例:ServletDemo08
package com.itheima.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;
/*
中文乱码
*/
修改register.html
<form action="/request/servletDemo08" method="post" >
访问
解决乱码,修改
//设置编码格式
req.setCharacterEncoding("UTF-8");
GET方式请求的正文是在地址栏中,在Tomcat8.5版本及之后,Tomcat服务器已经帮咱们解决了,因此不会有乱码问题了。
而若是咱们使用的不是Tomcat服务器,或者Tomcat的版本是8.5之前,那么GET方式仍然会有乱码问题,解决方式以下:(如下代码了解便可,由于咱们如今使用的是Tomcat9.xx版本)
/** * 在Servlet的doGet方法中添加以下代码 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * GET方式:正文在地址栏 * username=%D5%C5%C8%FD * %D5%C5%C8%FD是已经被编过一次码了 * * 解决办法: * 使用正确的码表对已经编过码的数据进行解码。 * 就是把取出的内容转成一个字节数组,可是要使用正确的码表。(ISO-8859-1) * 再使用正确的码表进行编码 * 把字节数组再转成一个字符串,须要使用正确的码表,是看浏览器当时用的是什么码表 */ String username = request.getParameter("username"); byte[] by = username.getBytes("ISO-8859-1"); username = new String(by,"GBK"); //输出到浏览器:注意响应的乱码问题已经解决了 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.write(username); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
请求到ServletA,实现的功能,须要用到ServletB,那这时候就能够在ServletA将请求转发到ServletB
那ServletB中可能会用到ServletA中的数据,那这时候就涉及到数据共享了
在这里若是使用应用域来共享数据,就有点浪费了,由于咱们只是在此次请求中须要共享数据,不是整个应用
因此就用到了请求域
请求转发:客户端的一次请求到达后,发现须要借助其余 Servlet 来实现功能
特色:
浏览器地址栏不变
域对象中的数据不丢失
负责转发的 Servlet 转发先后的响应正文会丢失 (ServletA的响应正文会丢失,由ServletB响应客户端)
由转发的目的地来响应客户端
应用场景:若是一次请求中这个servlet没法单独完成任务,这时会将这个请求转发给另外一个servlet
若是这两个servlet须要共享数据,咱们通常使用请求域
请求转发,不会丢失请求域数据,因此共享数据,都使用请求域
请求转发API
dispatcher:[dɪˈspætʃə(r)].调度
forward:向前,(按新地址)转寄; 发送
getRequestDispatcher('转发的url')
案例:新建ServletDemo09
package com.itheima.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.itheima.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); } }
访问
响应:回馈结果。在 BS 架构中,就是服务器给客户端浏览器反馈结果
响应对象:就是在项目中用于发送响应的对象
响应对象也是是Servlet规范中定义的,它包括了协议无关的和协议相关的
协议无关的对象标准是:ServletResponse接口
协议相关的对象标准是:HttpServletResponse接口
咱们课程中涉及的响应对象都是和HTTP协议相关的。即便用的是HttpServletResponse接口的实现类
405:请求方式不支持,例如:通常是后台只支持post请求,而发起的请求确实get请求,这时候就会提示405
状态码首位含义:
状态码 | 说明 |
---|---|
1xx | 消息 |
2xx | 成功 |
3xx | 重定向 |
4xx | 客户端错误 |
5xx | 服务器错误 |
在HttpServletResponse接口中提供了不少方法,接下来咱们经过API文档,来了解一下这些方法
先了解便可,接下来咱们会一步一步介绍
字节流响应API
字节流,经常使用于处理图片,文件
新建项目:response_demo,设置虚拟路径/response
新建类:com.itheima.servlet.ServletDemo01
package com.itheima.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; /* 字节流响应消息及乱码的解决 */ @WebServlet("/servletDemo01") public class ServletDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /* 项目中经常使用的编码格式是u8,而浏览器默认使用的编码是gbk。致使乱码! */ //1. 获取字节流输出对象 ServletOutputStream sos = resp.getOutputStream(); //2. 定义一个消息 String str = "你好"; //经过字节流对象输出 sos.write(str.getBytes());//getBytes不带参数,默认获取操做系统的编码集(咱们安装的都是中文windows,因此系统编码集是gbk) //sos.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
访问
谷歌浏览器,没有乱码(这是由于谷歌浏览器的默认编码是gbk)
可是谷歌浏览器想查看编码,须要安装插件,因此咱们再来看ie(发现默认是gb2312(gbk))
但其实,咱们的代码都应该是utf-8编码格式,只不过是getBytes默认处理了,才没有出现乱码
代码格式是utf-8,可是到浏览器gbk上为啥不是乱码,这是由于getBytes方法默认处理了,getBytes默认与操做系统的编码格式一致,而操做系统编码是gbk,因此getBytes处理成gbk了
那如何出现乱码呢?修改代码:
sos.write(str.getBytes("UTF-8"));
访问
解决乱码
/* 项目中经常使用的编码格式是u8,而浏览器默认使用的编码是gbk。致使乱码! 解决方式一:修改浏览器的编码格式(不推荐,不能让用户作修改的动做) 解决方式二:经过输出流写出一个标签:<meta http-equiv='content-type' content='text/html;charset=UTF-8'> 解决方式三:response.setHeader("Content-Type","text/html;charset=UTF-8"); 指定响应头信息 解决方式四:response.setContentType("text/html;charset=UTF-8"); */ //sos.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes()); //resp.setHeader("Content-Type","text/html;charset=UTF-8"); resp.setContentType("text/html;charset=UTF-8");//经常使用第四种,告知浏览器采用utf-8编码方式
访问
字符流API
字符流,经常使用于处理文字
案例:新建ServletDemo02
package com.itheima.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.io.PrintWriter; /* 字符流响应消息及乱码的解决 */ @WebServlet("/servletDemo02") public class ServletDemo02 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 准备一个消息 String str = "你好"; //2. 获取字符流对象 PrintWriter pw = resp.getWriter(); //3. 经过字符流输出 pw.write(str); //pw.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
访问
解决
//解决中文乱码 resp.setContentType("text/html;charset=UTF-8");
访问
解决乱码总结
若是是响应解决乱码问题,通常思路就是让浏览器与代码中的编码风格保持一致(utf-8)
resp.setContentType("text/html;charset=UTF-8");
若是请求中解决乱码,将gbk编码的中文信息转换为utf-8
//设置编码格式 (将浏览器默认编码gbk的中文信息,转换为utf-8的信息) req.setCharacterEncoding("UTF-8");
建立字节输入流对象,关联读取的图片路径
经过响应对象获取字节输出流对象
循环读取和写出图片
案例:新建ServletDemo03
package com.itheima.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("/servletDemo03") public class ServletDemo03 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 建立字节输入流对象,关联图片路径 String realPath = getServletContext().getRealPath("/img/hm.png"); System.out.println(realPath); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath)); //注意:不能直接指定图片路径,须要同getRealPath获取,由于项目还要发布,咱们须要获取到发布以后的图片路径 //BufferedInputStream bis = new BufferedInputStream(new FileInputStream(/img/hm.png)); //2. 获取字节输出流对象 ServletOutputStream sos = resp.getOutputStream(); //3. 循环读写 byte[] arr = new byte[1024]; int len; while((len = bis.read(arr)) != -1) { sos.write(arr,0,len); } bis.close(); sos.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
将今天资料“\day03_请求响应\资料\img”这个文件夹,copy到web目录下
访问
缓存:对于不常常变化的数据,咱们能够设置合理缓存时间,以免浏览器频繁请求服务器。以此来提升效率
缓存API
案例:新建ServletDemo04
package com.itheima.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("/servletDemo04") public class ServletDemo04 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String news = "这是一条很火爆的新闻~~"; //设置缓存时间:1小时的缓存时间 //参数1:Expires : 失效的意思 //参数2:当前时间+1小时毫秒值(意思就是在1小时以后过时) resp.setDateHeader("Expires",(System.currentTimeMillis()+1*60*60*1000L)); //设置编码格式 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); } }
第一次访问:发现执行了Servlet,而且打印了aaa
此时,这个Servlet已经被缓存下来了
第二次访问
而且控制台没有打印aaa
定时刷新:过了指定时间后,页面自动进行跳转
定时刷新API
案例:新建ServletDemo05
package com.itheima.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 news = "您的用户名或密码错误,3秒后自动跳转到登陆页面..."; //设置编码格式 resp.setContentType("text/html;charset=UTF-8"); //写出数据 resp.getWriter().write(news); //设置响应消息头定时刷新 //Refresh:刷新 //第二个参数第一部分:3,3设以后 //第二个参数第二部分:跳转到哪一个路径 //resp.setHeader("Refresh","3;URL=/response/login.html"); resp.setHeader("Refresh","3;URL="+req.getContextPath()+"/login.html"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
将以前的login.html复制到这个项目:web/login.html
访问:3s以后自动跳转到login.html
案例:新建ServletDemo06
package com.itheima.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 { //设置请求域数据 req.setAttribute("username","zhangsan"); //设置重定向 resp.sendRedirect(req.getContextPath() + "/servletDemo07"); //resp.sendRedirect("/response/servletDemo07"); // resp.sendRedirect("https://www.baidu.com"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
新建ServletDemo07,获取共享数据
package com.itheima.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); } }
访问:没法获取共享数据打印null
两次请求验证
重定向与转发的区别
重定向:
两次请求
地址栏发生变化
不可使用request域共享数据 (既然是两次请求,那确定不能使用请求域中共享的数据)
能够重定向到其余服务器的url
转发:
一次请求
地址栏不发生变化
可使用request域共享数据
只能转发到本身服务器内部的url
案例:新建ServletDemo08
package com.itheima.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/hm.png"); //建立字节输出流对象 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(realPath)); //2.设置响应头支持的类型 应用支持的类型为字节流 /* Content-Type 消息头名称 支持的类型 application/octet-stream 消息头参数 应用类型为字节流 */ resp.setHeader("Content-Type","application/octet-stream"); //3.设置响应头如下载方式打开 以附件形式处理内容 /* Content-Disposition 消息头名称 处理的形式 attachment;filename= 消息头参数 附件形式进行处理;指定下载文件名称 */ resp.setHeader("Content-Disposition","attachment;filename=hm.png"); //4.获取字节输出流对象 ServletOutputStream sos = resp.getOutputStream(); //5.循环读写文件 byte[] arr = new byte[1024]; int len; while((len = bis.read(arr)) != -1) { sos.write(arr,0,len); } //6.释放资源 bis.close(); //sos.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
访问
建立一个 web 项目 : reqresp_test,虚拟目录/stu
在 web 目录下建立一个 index.html,包含两个超连接标签(添加学生、查看学生)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>学生管理系统首页</title> </head> <body> <a href="/stu/addStudent.html">添加学生</a> <a href="/stu/listStudentServlet">查看学生</a> </body> </html>
在 web 目录下建立一个 addStudent.html,用于实现添加功能的表单页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加学生</title> </head> <body> <form action="/stu/addStudentServlet" method="get" 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>
在 src 下建立一个 com.itheima.bean.Student 类,用于封装学生信息
package com.itheima.bean; public class Student { private String username; private int age; private int score; public Student() { } public Student(String username, int age, int score) { this.username = username; this.age = age; this.score = score; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } }
实现步骤
建立 AddStudentServlet 类。继承 HttpServlet
重写 doGet 和 doPost 方法
获取表单中的数据
将获取到的数据封装成 Student 对象
将 Student 对象中的数据保存到 d:\stu.txt 文件中
经过定时刷新功能完成对浏览器的响应
新建:AddStudentServlet
package com.itheima.servlet; import com.itheima.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.BufferedWriter; import java.io.FileWriter; import java.io.IOException; /* 实现添加功能 */ @WebServlet("/addStudentServlet") public class AddStudentServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.获取表单中的数据 String username = req.getParameter("username"); String age = req.getParameter("age"); String score = req.getParameter("score"); //2.建立学生对象并赋值 Student stu = new Student(); stu.setUsername(username); stu.setAge(Integer.parseInt(age)); stu.setScore(Integer.parseInt(score)); //3.将学生对象的数据保存到d:\\stu.txt文件中 BufferedWriter bw = new BufferedWriter(new FileWriter("d:\\stu.txt",true)); bw.write(stu.getUsername() + "," + stu.getAge() + "," + stu.getScore()); bw.newLine(); bw.close(); //4.经过定时刷新功能响应给浏览器 resp.setContentType("text/html;charset=UTF-8"); resp.getWriter().write("添加成功。2秒后自动跳转到首页..."); resp.setHeader("Refresh","2;URL=/stu/index.html"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
访问
实现步骤
建立 ListStudentServlet 类。继承 HttpServlet
重写 doGet 和 doPost 方法
经过字符输入流读取 d:\stu.txt 文件中的数据
将读到的数据封装到 Student 对象中
将多个 Student 对象保存到集合中
遍历集合,将数据响应到浏览器
新建ListStudentServlet
package com.itheima.servlet; import com.itheima.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.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; /* 实现查看功能 */ @WebServlet("/listStudentServlet") public class ListStudentServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1.建立字符输入流对象,关联读取的文件 BufferedReader br = new BufferedReader(new FileReader("d:\\stu.txt")); //2.建立集合对象,用于保存Student对象 ArrayList<Student> list = new ArrayList<>(); //3.循环读取文件中的数据,将数据封装到Student对象中。再把多个学生对象添加到集合中 String line; while((line = br.readLine()) != null) { //张三,23,95 Student stu = new Student(); String[] arr = line.split(","); stu.setUsername(arr[0]); stu.setAge(Integer.parseInt(arr[1])); stu.setScore(Integer.parseInt(arr[2])); list.add(stu); } //4.遍历集合,将数据响应给浏览器 resp.setContentType("text/html;charset=UTF-8"); //获取输出流对象 PrintWriter pw = resp.getWriter(); for(Student s : list) { pw.write(s.getUsername() + "," + s.getAge() + "," + s.getScore()); pw.write("<br>"); } // 注意:其实这个代码写复杂了。文本中的数据,与最终输出到浏览器的数据如出一辙 // 因此彻底能够读出来的line,经过pw直接写便可,不须要封装List<student> } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
访问