Request(获取请求数据)
@Override
_protected void doGet(HttpServletRequest _req, HttpServletResponse resp) throws ServletException, IOException {
// 使用HttpServletRequest获取请求数据
final String name = req.getParameter(“name”);
// 使用HttpServletResponse发送响应数据<br /> _resp_.setHeader**(**"content-type","text/html;charset=utf-8"**)**;<br /> _resp_.getWriter**()**.write**(**"<h1>"+ name+" + 欢迎您!</h1>"**)**;<br />**}**
Request 继承体系
Request 获取请求数据
请求行
@Override
_protected void doGet(HttpServletRequest _req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求方式 GET
final String method = req.getMethod();
System.out.println(method);
// 获取虚拟目录 默认包名
final String contextPath = req.getContextPath();
System.out.println(contextPath);
// 获取请求统一路径(全路径) http://localhost:8088/ser
final StringBuffer requestURL = req.getRequestURL();
System.out.println(requestURL);
// 获取请求当前请求路径(短路径) /ser
final String requestURI = req.getRequestURI();
System.out.println(requestURI);
// 获取请求参数 没有参数默认null
final String queryString = req.getQueryString();
System.out.println(queryString);
// 获取请求头 设置参数(user-agent) Mozilla/5.0 (Windows NT 10.0; Win64; x64)
final String header = req.getHeader(“user-agent”);
System.out.println(header);
}
请求头
// 获取请求头 设置参数(user-agent)Mozilla/5.0 (Windows NT 10.0; Win64; x64)
final String header = req.getHeader(“user-agent”);
System.out.println(header);
请求体 — POST
@Override
_protected void doPost(HttpServletRequest _req, HttpServletResponse resp) throws ServletException, IOException {
// 获取Post请求体
// 获取字符输入流使用BufferedReader
final BufferedReader reader = req.getReader();
// 读取数据
final String line = reader.readLine();
System.out.println(line);
}
Request 通用方式获取参数
POST—getReader()
GET—getQueryString()
GET 获取请求行使用获取参数
因为GET获取参数和POST获取参数一致都是使用getParameterValues()所以doPost可以直接调用doGet()
@WebServlet(“/ser1”)
public class RequestDemo1 extends HttpServlet {
@Override
_protected void doGet(HttpServletRequest _req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(“get…”);
// 获取所有参数的Map集合
final Map<String, String[]> map = req.getParameterMap();
for (String key : map.keySet()) {
// 获取值 因为value是数组在遍历数组
final String[] value = map.get(key);
for (String s : value) {
System.out.println(key + “:” + s);
}
}
System.out.println(“——-参数数组——“);
// 获取对应的参数值(数组)
final String[] hobbits = req.getParameterValues(“hobbit”);
for (String s : hobbits) {
System.out.println(s + “”);
}
System.out.println(“——-单个参数——-“);
// 获取对应的单个参数的值
final String username = req.getParameter(“username”);
System.out.println(“username:” + username);
final String password = req.getParameter(“password”);
System.out.println(“password:” + password);
**}
**_@Override<br /> _protected void doPost**(**HttpServletRequest _req_, HttpServletResponse _resp_**) **throws ServletException, IOException **{<br /> **System.out.println**(**"post..."**)**;<br /> // 调用get方法<br /> this.doGet**(**_req_, _resp_**)**;<br /> **}<br />}**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/12745457/1646040498781-6e6f4154-4de2-4ab7-bf2a-20886bd9749e.png#clientId=u9821b0aa-2113-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=209&id=u84ea7cbf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=314&originWidth=462&originalType=binary&ratio=1&rotation=0&showTitle=false&size=170766&status=done&style=none&taskId=uf340e168-7d97-408e-86e1-b154f7dc766&title=&width=308)
Idea 快速创建Servlet
- 右键项目新建Servlet文件
- 更改路径名称
@WebServlet(“/ser2”)
public class RequestServlet2 extends HttpServlet {
@Override
_protected void doGet(HttpServletRequest _request, HttpServletResponse response) throws ServletException, IOException **{ }
**_@Override<br /> _protected void doPost**(**HttpServletRequest _request_, HttpServletResponse _response_**) **throws ServletException, IOException **{<br /> **this.doGet**(**_request_,_response_**)**; **} }**
Request请求参数中文乱码
POST getReader()字符流获取参数
可以直接使用字节转码setCharacterEncoding(UTF-8)解决参数中文乱码问题:
request.setCharacterEncoding(“UTF-8”);
GET使用getQueryString()获取请求行
- 字节数组转换为字符串解码
String name = “张三”;
// URL编码 使用URLEncoder.encode
final String encode = URLEncoder.encode(name, “UTF-8”);
// %E6%9D%8E%E7%95%85
System.out.println(encode);
// URL解码 使用URLDecoder.decode
// final String decode = URLDecoder.decode(encode, “UTF-8”);
// Tomcat URL解码
final String decode = URLDecoder.decode(encode,”ISO-8859-1”);
System.out.println(decode);
// 转换为字节数据
final byte[] bytes = decode.getBytes(“ISO-8859-1”);
// -27 -68 -96 -28 -72 -119
for (byte b : bytes) {
System.out.println(b + “ “);
**}
// 将字节数组转换为字符串解码
String string = new String(bytes,”UTF-8”);
System.out.println(string); //张三
先编码后解码,并且通用
username = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
System.out.println(“解码后:” + username);**
Request 请求转发
@Override
_protected void doGet(HttpServletRequest _request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(“ser3…”);
// 请求转发getRequestDispatcher(路径).forward(request,response)
request.getRequestDispatcher(“/ser4”).forward(request,response); }
@WebServlet(“/ser3”)
public class RequestServlet3 extends HttpServlet {
@Override
_protected void doGet(HttpServletRequest _request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(“ser3…”);
// 存储数据
request.setAttribute(“msg”,”hello”);
// 请求转发getRequestDispatcher(路径).forward(request,response)<br /> _request_.getRequestDispatcher**(**"/ser4"**)**.forward**(**_request_,_response_**)**; **} }**<br />**---------------------------------------------------**<br /> _@WebServlet_**(**"/ser4"**)<br />**public class RequestServlet4 extends HttpServlet **{<br /> **_@Override<br /> _protected void doGet**(**HttpServletRequest _request_, HttpServletResponse _response_**) **throws ServletException, IOException **{<br /> **System.out.println**(**"ser4..."**)**;<br /> // 获取数据<br /> Object msg = _request_.getAttribute**(**"msg"**)**;<br /> System.out.println**(**msg**)**; **}** **}**<br />**---------------------------------**<br />**访问ser3**![image.png](https://cdn.nlark.com/yuque/0/2022/png/12745457/1646104639617-5cbc01f1-dac3-4e6f-970f-f154462ced57.png#clientId=uadaab92a-bd2e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=65&id=ubeed644a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=98&originWidth=135&originalType=binary&ratio=1&rotation=0&showTitle=false&size=4265&status=done&style=none&taskId=ua13d5acd-8009-41ba-8f2e-deb76ffb26b&title=&width=90)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/12745457/1646105107429-4625c281-5369-41c3-824b-c7df5ecaef5a.png#clientId=uadaab92a-bd2e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=105&id=u58a74a8c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=158&originWidth=554&originalType=binary&ratio=1&rotation=0&showTitle=false&size=53290&status=done&style=none&taskId=u9ec39623-1073-4332-a590-686762b14bf&title=&width=369.3333333333333)
Response(设置响应数据)
Request是getXxxx()方法
Reponse是setXxxx()方法
Response 设置响应数据功能
Response 重定向
@WebServlet(“/resp”)
public class ResponseServlet extends HttpServlet {
@Override
_protected void doGet(HttpServletRequest _request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(“resp…”);
// 重定向
// 1. 设置响应状态码
response.setStatus(302);
// 2. 设置响应头Location
response.setHeader(“location”,”/resp1”); } }
————————————————————-
// 简化重定向
response.sendRedirect(“/resp1”);
Response 重定向和Request 转发
- Request转发地址栏路径不变,但是Reponse重定向改变
- 转发只能内部资源。重定向可以内外部跳转
- 转发是一次请求在request共享数据。重定向两次请求数据不共享
路径问题
动态获取虚拟目录
// 动态获取虚拟目录
String contextPath = request.getContextPath();
response.sendRedirect(contextPath + “/resp1”);
Response 响应字符数据
@Override
_protected void doGet(HttpServletRequest _request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(“resp…”);
// 1. 获取字符输出流
final PrintWriter writer = response.getWriter();
// 获取响应信息content-type
// 让浏览器识别信息类型 (text/html)
response.setHeader(“content-type”, “text/html”);
writer.write(“
abc
“);}———————————————————————————-
// 使用setContentType不仅可以让浏览器识别信息类型也可以添加字符编码
// 让浏览器识别信息类型 (text/html)以及字符编码类型(“UTF-8”)
response.setContentType(“text/html;charset=utf-8”);
// 1. 获取字符输出流
final PrintWriter writer = response.getWriter();
writer.write(“
abc
“);// 细节:输出流不需要关闭
writer.write(“李畅”);
Response 响应字节数据
@Override
_protected void doGet(HttpServletRequest _request, HttpServletResponse response) throws ServletException, IOException {
// 1. 读取文件
FileInputStream file = new FileInputStream(“C:\Users\李畅\Desktop\avatar.png”);
// 2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
// 3. 完成流的copy
// 3.1 定义数组和长度
byte[] bytes = new byte[1024];
int len = 0;
// 3.2 循环写入
while ((len = file.read(bytes))!=-1) {
os.write(bytes, 0, len);
}
file.close(); }
————————————————
使用commons-io 依赖
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
——————————————————
// 1. 读取文件
FileInputStream file = new FileInputStream(“C:\Users\李畅\Desktop\avatar.png”);
// 2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
// 3. 完成流的copy
// 使用commons-io替换传统输入输出流 ,添加文件参数,以及字节输出流参数
IOUtils.copy(file,os);
file.close();
案例: 用户登录&注册
用户登录
- 准备静态环境
- 页面模板
- 页面样式
- 创建实体类
- User类
- 对应数据库字段
- 导入MyBatis坐标,MySQL驱动坐标
- 引入MyBatis依赖
- 引入MySQL依赖
- 准备MyBatis核心配置文件
typeAliases 用于resultMap简化包名
数据库链接url中&是用转换符&使用
后端逻辑编写
- 创建UserMapper 接口
- 并在resource目录下同源创建com/mapper包下创建对应UserMapper.xml 配置文件
- 在UserMapper接口定义方法
- 定义Servlet创建接口
用户注册
- 在UserMapper接口添加方法
- 创建RegiterServlet调用Mapper方法
- 在静态页面设置action路由位置
- 测试页面是否可以注册,数据库添加成功
代码优化
- 提取重复代码
- 创建Util工具类
- 调用工具类方法优化代码
Tips:
- 创建SqlSessionFactory获取方法
- 工具类创建静态代码块,工厂类只加载一次
- 提取静态代码块的成员变量作用域,并返回给方法
- 对外可以直接调用getSqlSessionFactory()获取SqlSessionFactory对象