JavaWeb入门4.0

  • 1. Request(请求)& Response (响应)
  • 2. Request
    • 2.1 Request 继承体系
    • 2.2 Request 获取请求数据
      • 2.2.1 通用方式获取请求参数
      • 2.2.2 IDEA模板创建Servlet
      • 2.2.3 请求参数中文乱码处理
        • 2.2.3 – I POST解决方案
        • 2.2.3 – II GET解决方案
    • 2.3 Request 请求转发
  • 3. Response
    • 3.1 Response 设置响应数据功能
    • 3.2 Response 完成重定向
      • 3.2.1 资源路径问题
    • 3.3 Response 响应字符数据
    • 3.4 Response 响应字节数据
  • 4. Request与Response 案例
    • 4.1 用户登录
      • 4.1.1 环境准备
      • 4.1.2 代码实现
    • 4.2 用户注册
    • 4.3 SqlSessionFactory 工具类提取

1. Request(请求)& Response (响应)

2. Request

2.1 Request 继承体系

  1. Tomcat需要解析请求数据,封装为request对象,并且创建request对象传递到service方法中
  2. 使用request对象,查阅JavaEE API文档的 HttpServletRequest 接口

2.2 Request 获取请求数据

请求数据分为3部分:

1、请求行:

  • String getMethod():获取请求方式:GET
  • String getContextPath():获取虚拟目录(项目访问路径):/request-demo
  • StringBuffer getRequestURL():获取URL(统一资源定位符):http://localhost:8080/request-demo/req1
  • String getRequestURI():获取URI(统一资源标识符): /request-demo/req1
  • String getQueryString():获取请求参数(GET方式): username=zhangsan&password=123

案例:

@WebServlet("/req1")public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();System.out.println(method);String contextPath = req.getContextPath();System.out.println(contextPath);StringBuffer url = req.getRequestURL();System.out.println(url);String uri = req.getRequestURI();System.out.println(uri);String queryString = req.getQueryString();System.out.println(queryString);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}}


2、请求头:

  • String getHeader(String name):根据请求头名称,获取值
@WebServlet("/req1")public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();System.out.println(method);String contextPath = req.getContextPath();System.out.println(contextPath);StringBuffer url = req.getRequestURL();System.out.println(url);String uri = req.getRequestURI();System.out.println(uri);String queryString = req.getQueryString();System.out.println(queryString);//获取请求头:uer-getHeader:浏览器的版本信息String agent = req.getHeader("user-agent");System.out.println(agent);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}}

3、请求体:

  • ServletInoutStream getInputStream():获取字节输入流
  • BufferedReader getReader():获取字符输入流

案例:
RequestDemo1类:

@WebServlet("/req1")public class RequestDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();System.out.println(method);String contextPath = req.getContextPath();System.out.println(contextPath);StringBuffer url = req.getRequestURL();System.out.println(url);String uri = req.getRequestURI();System.out.println(uri);String queryString = req.getQueryString();System.out.println(queryString);//获取请求头:uer-getHeader:浏览器的版本信息String agent = req.getHeader("user-agent");System.out.println(agent);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取post 请求体:请求参数//1.获取字符输入流BufferedReader br = req.getReader();//该流会自动关闭//2.读取数据String line = br.readLine();System.out.println(line);}}

req.html:

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><form action="/request_demo_war/req1" method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit"></form></body></html>



2.2.1 通用方式获取请求参数

请求参数获取方式:

  • GET 方式:
String getQueryString()
  • POST 方式:
BufferedReader getReader()

思考:
GET请求方式和POST请求方式区别主要在于获取请求参数的方式不一样,是否可以提供一种统一获取请求参数的方式,从而统一doGet和doPost方法内的代码?

  • Map getParameterMap():获取所有参数Map集合
  • String[ ] getParameterValues(String name)︰根据名称获取参数值(数组)
  • String getParameter(String name):根据名称获取参数值(单个值)

案例:
RequestDemo2类:

package com.itheima.web;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.IOException;import java.util.Map;@WebServlet("/req2")public class RequestDemo2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//get请求逻辑//System.out.println("get....");//1.获取所有参数的map集合Map<String, String[]> map = req.getParameterMap();for (String key : map.keySet()) {//比如:username:zhangsanSystem.out.print(key+":");//获取value值String[] values = map.get(key);for (String value : values) {System.out.print(value+" ");}System.out.println();}System.out.println("----------------------------");//2.根据key获取参赛值,数组String[] hobbies = req.getParameterValues("hobby");for (String hobby : hobbies) {System.out.println(hobby);}//3.根据key 获取单个参数值String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取post 请求体:请求参数this.doGet(req,resp);//一样法典复用即可//System.out.println("post....");//////1.获取所有参数的map集合//Map map = req.getParameterMap();//for (String key : map.keySet()) {////比如:username:zhangsan//System.out.print(key+":");//////获取value值//String[] values = map.get(key);//for (String value : values) {//System.out.print(value+" ");//}//System.out.println();//}//System.out.println("----------------------------");//////2.根据key获取参赛值,数组//String[] hobbies = req.getParameterValues("hobby");//for (String hobby : hobbies) {//System.out.println(hobby);//}//////3.根据key 获取单个参数值//String username = req.getParameter("username");//String password = req.getParameter("password");//System.out.println(username);//System.out.println(password);}}

html:

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><form action="/request_demo_war/req2" method="get"><input type="text" name="username"><br><input type="password" name="password"><br><input type="checkbox" name="hobby" value="1">游水<input type="checkbox" name="hobby" value="2">开冲<br><input type="submit"></form></body></html>


2.2.2 IDEA模板创建Servlet

  1. 便捷创建

  2. 在设置里面的代码样式下>文件和代码模板:自定义快捷修改

2.2.3 请求参数中文乱码处理

URL编码

  1. 将字符串按照编码方式转为二进制
  2. 每个字节转为2个16进制数并在前边加上%

演示UTF编码转换:

public class URLDemo {public static void main(String[] args) throws UnsupportedEncodingException {String username = "张三";//1.URL编码String encode = URLEncoder.encode(username, "utf-8");System.out.println(encode);//2.URL编码String decode = URLDecoder.decode(encode, "utf-8");String decode2 = URLDecoder.decode(encode, "ISO-8859-1");//å¼ ä¸‰System.out.println(decode);}}

解决思路:

package com.itheima.web;import java.io.UnsupportedEncodingException;import java.net.URLDecoder;import java.net.URLEncoder;import java.nio.charset.StandardCharsets;public class URLDemo {public static void main(String[] args) throws UnsupportedEncodingException {String username = "张三";//1.URL编码String encode = URLEncoder.encode(username, "utf-8");System.out.println(encode);//2.URL编码String decode = URLDecoder.decode(encode, "ISO-8859-1");//å¼ ä¸‰System.out.println(decode);//3.转换为字节数据,编码过程byte[] bytes = decode.getBytes("ISO-8859-1");//4.将字节数组转换为字符串,解码过程String s = new String(bytes, "utf-8");System.out.println(s);}}

2.2.3 – I POST解决方案

请求参数如果存在中文数据,则会乱码
解决方案:

  • POST:设置输入流的编码
request.setCharacterEncoding("UTF-8");

案例:

@WebServlet("/req4")public class RequestDemo4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.解决乱码:POST getReader()request.setCharacterEncoding("UTF-8");//设置字符输入流的参数//2.获取usernameString username = request.getParameter("username");System.out.println(username);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}


2.2.3 – II GET解决方案

@WebServlet("/req4")public class RequestDemo4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.解决乱码:POST getReader()request.setCharacterEncoding("UTF-8");//设置字符输入流的参数//2.获取usernameString username = request.getParameter("username");System.out.println("解决乱码前:"+username);//3.GET 获取参数的方式:getQueryString//乱码原因:tomcat进行URL解码时,默认的字符集ISO-8859-1//3.1 先对乱码数据进行解码:转为字节数组//byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);//3.2 字节数组解码username = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);System.out.println("解决乱码后:"+username);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}

小结:

2.3 Request 请求转发

请求转发(forward):一种在服务器内部的资源跳转方式

  • 实现方式:
req.getRequestDispatcher("资源B路径").forward(req,resp);

案例:
RequestDemo5类:

@WebServlet("/req5")public class RequestDemo5 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("demo5...");//请求转发request.getRequestDispatcher("/req6").forward(request,response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}

RequestDemo6类:

@WebServlet("/req6")public class RequestDemo6 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("Demo6....");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}


请求转发资源共享数据:使用Request对象

    • void setAttribute(String name, Object o):存储数据到request域中
    • Object getAttribute(String name):根据key,获取值
    • void removeAttribute(String name):根据key,删除该键值对

案例:

@WebServlet("/req5")public class RequestDemo5 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("demo5...");//存储数据request.setAttribute("msg","helloworld");//请求转发request.getRequestDispatcher("/req6").forward(request,response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}
@WebServlet("/req6")public class RequestDemo6 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("Demo6....");//获取数据Object msg = request.getAttribute("msg");System.out.println(msg);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}

请求转发的特点:

  • 浏览器地址栏路径不发生变化
  • 只能转发到当前服务器的内部资源
  • 一次请求,可以在转发的资源间使用request共享数据

3. Response

3.1 Response 设置响应数据功能

响应数据分为3部分:
1、响应行:HTTP/1.1 200 oK

  • void setStatus(int sc)∶设置响应状态码

2、响应头: Content-Type: text/html

  • void setHeader(String name,String value)∶设置响应头键值对

3、响应体: head>

  • PrintWriter getWriter():获取字符输出流
  • ServletOutputStream getOutputStream():获取字节输出流

3.2 Response 完成重定向

重定向(Redirect):一种资源跳转方式

案例:
ResponseDemo1类:

@WebServlet("/resp1")public class ResponseDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("resp1......");//重定向//1.设置响应状态码302response.setStatus(302);//2.设置响应头 Location//response.setHeader("Location","/request_demo_war/resp2"); request_demo_war为自己的启动目录//简化方式完成重定向response.sendRedirect("/request_demo_war/resp2");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}

ResponseDemo2类:

@WebServlet("/resp2")public class ResponseDemo2 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("resp2......");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}
  • 重定向特点:
    • 浏览器地址栏路径发生变化
    • 可以重定向到在意位置的资源(服务器内部、外部均可)
    • 两次请求,不能在多个资源使用request共享数据

对比:

3.2.1 资源路径问题

明确路径谁使用” />

例如:

@WebServlet("/resp1")public class ResponseDemo1 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println("resp1......");//重定向//1.设置响应状态码302response.setStatus(302);//2.设置响应头 Location//response.setHeader("Location","/request_demo_war/resp2"); request_demo_war为自己的启动目录//简化方式完成重定向//动态获取虚拟目录String contextPath = request.getContextPath();response.sendRedirect(contextPath+"/resp2");}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}

3.3 Response 响应字符数据

使用:

  1. 通过Response对象获取字符输出流
PrintWriter writer = resp.getWriter();
  1. 写数据
writer.write("aaa");

例子:

@WebServlet("/resp3")public class ResponseDemo3 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//设置流中文编码response.setContentType("text/html;charset=utf-8");//1.获取字符输入流PrintWriter writer = response.getWriter();//content-type 识别html标签//response.setHeader("content-type","text/html");writer.write("你吗的");writer.write("

aaaa

"
);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}

注意:

  • 该流不需要关闭,随着响应结束,response对象销毁,由服务器关闭
  • 中文数据乱码:原因通过Response获取的字符输出流默认编码:ISO-8859-1
resp.setContentType("text/html;charset=utf-8");

3.4 Response 响应字节数据

使用:

  1. 通过Response对象获取字符输出流
ServletOutputStream outputStream = resp.getOutputStream();
  1. 写数据
outputStream.write(字节数据);

例子:

@WebServlet("/resp4")public class ResponseDemo4 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.读取文件FileInputStream fis = new FileInputStream("F://常用文件夹//图片//Saved Pictures//1.jpg");//2.获取response字节输出流ServletOutputStream os = response.getOutputStream();//3.完成流的copybyte[] buff = new byte[1024];int len = 0;while ((len = fis.read(buff))!=-1){os.write(buff,0,len);}fis.close();}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}

但是将来不用写完成copy流的步骤了,太麻烦,一般会采用工具类

  • lOUtils工具类使用
    导入坐标
<dependency><groupld>commons-io</groupld><artifactld>commons-io</artifactld><versign>2.6</version></dependency>

使用:

IOUtils.copy(输入流,输出流);

例如:

4. Request与Response 案例

4.1 用户登录

4.1.1 环境准备

环境准备

静态页面:

  • css代码:
    • login
* {margin: 0;padding: 0;}html {height: 100%;width: 100%;overflow: hidden;margin: 0;padding: 0;background: url(../imgs/Desert.jpg) no-repeat 0px 0px;background-repeat: no-repeat;background-size: 100% 100%;-moz-background-size: 100% 100%;}body {display: flex;align-items: center;justify-content: center;height: 100%;}#loginDiv {width: 37%;display: flex;justify-content: center;align-items: center;height: 300px;background-color: rgba(75, 81, 95, 0.3);box-shadow: 7px 7px 17px rgba(52, 56, 66, 0.5);border-radius: 5px;}#name_trip {margin-left: 50px;color: red;}p {margin-top: 30px;margin-left: 20px;color: azure;}input {margin-left: 15px;border-radius: 5px;border-style: hidden;height: 30px;width: 140px;background-color: rgba(216, 191, 216, 0.5);outline: none;color: #f0edf3;padding-left: 10px;}#username{width: 200px;}#password{width: 202px;}.button {border-color: cornsilk;background-color: rgba(100, 149, 237, .7);color: aliceblue;border-style: hidden;border-radius: 5px;width: 100px;height: 31px;font-size: 16px;}#subDiv {text-align: center;margin-top: 30px;}#loginMsg{text-align: center;color: aliceblue;}
    • register:
* {margin: 0;padding: 0;list-style-type: none;}.reg-content{padding: 30px;margin: 3px;}a, img {border: 0;}body {background-image: url("../imgs/reg_bg_min.jpg") ;text-align: center;}table {border-collapse: collapse;border-spacing: 0;}td, th {padding: 0;height: 90px;}.inputs{vertical-align: top;}.clear {clear: both;}.clear:before, .clear:after {content: "";display: table;}.clear:after {clear: both;}.form-div {background-color: rgba(255, 255, 255, 0.27);border-radius: 10px;border: 1px solid #aaa;width: 424px;margin-top: 150px;margin-left:1050px;padding: 30px 0 20px 0px;font-size: 16px;box-shadow: inset 0px 0px 10px rgba(255, 255, 255, 0.5), 0px 0px 15px rgba(75, 75, 75, 0.3);text-align: left;}.form-div input[type="text"], .form-div input[type="password"], .form-div input[type="email"] {width: 268px;margin: 10px;line-height: 20px;font-size: 16px;}.form-div input[type="checkbox"] {margin: 20px 0 20px 10px;}.form-div input[type="button"], .form-div input[type="submit"] {margin: 10px 20px 0 0;}.form-div table {margin: 0 auto;text-align: right;color: rgba(64, 64, 64, 1.00);}.form-div table img {vertical-align: middle;margin: 0 0 5px 0;}.footer {color: rgba(64, 64, 64, 1.00);font-size: 12px;margin-top: 30px;}.form-div .buttons {float: right;}input[type="text"], input[type="password"], input[type="email"] {border-radius: 8px;box-shadow: inset 0 2px 5px #eee;padding: 10px;border: 1px solid #D4D4D4;color: #333333;margin-top: 5px;}input[type="text"]:focus, input[type="password"]:focus, input[type="email"]:focus {border: 1px solid #50afeb;outline: none;}input[type="button"], input[type="submit"] {padding: 7px 15px;background-color: #3c6db0;text-align: center;border-radius: 5px;overflow: hidden;min-width: 80px;border: none;color: #FFF;box-shadow: 1px 1px 1px rgba(75, 75, 75, 0.3);}input[type="button"]:hover, input[type="submit"]:hover {background-color: #5a88c8;}input[type="button"]:active, input[type="submit"]:active {background-color: #5a88c8;}.err_msg{color: red;padding-right: 170px;}#password_err,#tel_err{padding-right: 195px;}#reg_btn{margin-right:50px; width: 285px; height: 45px; margin-top:20px;}
  • imgs图片

HTML部分:

  1. login
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>login</title><link href="css/login.css" rel="stylesheet"></head><body><div id="loginDiv"><form action="" id="form"><h1 id="loginMsg">LOGIN IN</h1><p>Username:<input id="username" name="username" type="text"></p><p>Password:<input id="password" name="password" type="password"></p><div id="subDiv"><input type="submit" class="button" value="login up"><input type="reset" class="button" value="reset"><a href="register.html">没有账号?点击注册</a></div></form></div></body></html>
  1. register
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>欢迎注册</title><link href="css/register.css" rel="stylesheet"></head><body><div class="form-div"><div class="reg-content"><h1>欢迎注册</h1><span>已有帐号?</span> <a href="login.html">登录</a></div><form id="reg-form" action="#" method="get"><table><tr><td>用户名</td><td class="inputs"><input name="username" type="text" id="username"><br><span id="username_err" class="err_msg" style="display: none">用户名不太受欢迎</span></td></tr><tr><td>密码</td><td class="inputs"><input name="password" type="password" id="password"><br><span id="password_err" class="err_msg" style="display: none">密码格式有误</span></td></tr></table><div class="buttons"><input value="注 册" type="submit" id="reg_btn"></div><br class="clear"></form></div></body></html>
  1. req
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><form action="/request_demo_war/req4" method="get"><input type="text" name="username"><br><input type="password" name="password"><br><input type="checkbox" name="hobby" value="1">游水<input type="checkbox" name="hobby" value="2">开冲<br><input type="submit"></form></body></html>

mybatis环境:

  • 数据库创建:
  • pojo下的User.java
package com.itheima.pojo;public class User {private Integer id;private String username;private String password;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;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}}
  • mybatis-config.xml
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.dorg/dt/mybatis-3-config.dtd"><configuration><typeAliases><package name="com.itheima.pojo"/></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><mappers><package name="com.itheima.mapper"/></mappers></configuration>
  • UserMapper.xml
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.itheima.mapper.UserMapper"></mapper>

4.1.2 代码实现

  • 核心配置文件:端口自行设置,如果端口被有的站点站了,那么后面网页登录提交后会报500错误
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>request-demo</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties><dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.tomcat.maven</groupId><artifactId>tomcat7-maven-plugin</artifactId><version>2.2</version><configuration><port>85</port></configuration></plugin></plugins></build></project>
  • UserMapper.java:
package com.itheima.mapper;import com.itheima.pojo.User;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select;public interface UserMapper {/*根据用户名和密码查询用户对象 */@Select("select * from tb_user where username = #{username} and password = #{password}")User select(@Param("username") String username,@Param("password") String password);}

loginServlet:

@WebServlet("/loginServlet")public class loginServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.接收用户名和密码String username = request.getParameter("username");String password = request.getParameter("password");//2.调用mybatis完成查询//2.1 获取SqlSessionFactory对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2.2 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.3 获取MapperUserMapper userMapper = sqlSession.getMapper(UserMapper.class);//2.4 调用方法User user = userMapper.select(username, password);//2.5 释放资源sqlSession.close();//获取响应数据的字符输出流,并设置content type 防止乱码response.setContentType("text/html;charset=utf-8");PrintWriter Pwriter = response.getWriter();//3.判断user释放为nullif (user!=null){// 登录成功Pwriter.write("登录成功");}else {// 登录失败Pwriter.write("登录失败");}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}

Mavn 运行:



登录成功:

4.2 用户注册

  • UserMapper
package com.itheima.mapper;import com.itheima.pojo.User;import org.apache.ibatis.annotations.Insert;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select;public interface UserMapper {/*根据用户名和密码查询用户对象 */@Select("select * from tb_user where username = #{username} and password = #{password}")User select(@Param("username") String username,@Param("password") String password);/*根据用户名查询用户对象 */@Select("select * from tb_user where username = #{username}")User selectByUsername(String username);//添加用户@Insert("insert into tb_user values(null,#{username},#{password})")void add(User user);}
  • registerServlet类
@WebServlet("/registerServlet")public class registerServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//1.接收用户数据String username = request.getParameter("username");String password = request.getParameter("password");//封装用户对象User user = new User();user.setUsername(username);user.setPassword(password);//2. 调用mapper 根据用户名查询用户对象//2.1 获取SqlSessionFactory对象String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2.2 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.3 获取MapperUserMapper userMapper = sqlSession.getMapper(UserMapper.class);//2.4 调用方法User u = userMapper.selectByUsername(username);//3.判断用户对象释放是否为nullif (u == null){//用户不存在,添加用户userMapper.add(user);//提交事务sqlSession.commit();//释放资源sqlSession.close();}else {//用户存在,给出提示信息response.setContentType("text/html;charset=utf-8");response.getWriter().write("用户名已存在");}}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request, response);}}
  • register的html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>欢迎注册</title><link href="css/register.css" rel="stylesheet"></head><body><div class="form-div"><div class="reg-content"><h1>欢迎注册</h1><span>已有帐号?</span> <a href="login.html">登录</a></div><form id="reg-form" action="/request-demo/registerServlet" method="post"><table><tr><td>用户名</td><td class="inputs"><input name="username" type="text" id="username"><br><span id="username_err" class="err_msg" style="display: none">用户名不太受欢迎</span></td></tr><tr><td>密码</td><td class="inputs"><input name="password" type="password" id="password"><br><span id="password_err" class="err_msg" style="display: none">密码格式有误</span></td></tr></table><div class="buttons"><input value="注 册" type="submit" id="reg_btn"></div><br class="clear"></form></div></body></html>



注册成功:

4.3 SqlSessionFactory 工具类提取

  • 创建SqlSessionFactory代码优化

存在问题:

  1. 代码重复:工具类
  2. SqlSessionFactory 工厂只创建一次,不要重复创建:静态代码块

案例:
在itheima下的util包创建:SqlSessionFactoryUtils类

public class SqlSessionFactoryUtils {private static SqlSessionFactory sqlSessionFactory;static {//静态代码块会随着类的加载而自动执行,且只执行一次try {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);} catch (IOException e) {e.printStackTrace();}}public static SqlSessionFactory getSqlSessionFactory(){return sqlSessionFactory;}}

实现: