Request和Response

前言

这一节主要讲的是Request和Response还有一些实例

1. 介绍

就是这两个参数

java 复制代码
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //使用request对象,获取请求数据  输入网址就是get
        String name = req.getParameter("name");//url?name=zhangsan
        //使用response对象,设置响应数据
        resp.setHeader("content-type", "text/html;charset=UTF-8");
        resp.getWriter().write("<h1>" + name+",欢迎你" + "</h1>");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}


2. requset

2.1 request继承体系


前面两个我们都用过了

RequestFacade实现的方法都是前面两个接口的

requset对象是由Tomcat创建的

2.2 request请求数据

请求行:请求方式+请求资源路径+请求协议+版本号

虚拟目录就是我们项目的目录

URL就是问号前面的

问号后面的是get方式的请求参数

URI:短的路径

java 复制代码
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();//获取请求方式
        System.out.println(method);//GET

        String contextPath=req.getContextPath();//获取虚拟目录,就是项目的访问路径
        System.out.println(contextPath);//没有设置项目的访问路径,那么返回的默认就是这个模块的名称

        StringBuffer url=req.getRequestURL();
        System.out.println(url.toString());//获取URL

        String uri=req.getRequestURI();//获取uri
        System.out.println(uri);

        String queryString=req.getQueryString();//获取请求参数
        System.out.println(queryString);

    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}


拿着请求参数,切割就可以得到很多个键值对了

在把等号切割就OK了

获取客户端使用的浏览器的版本信息

只有post请求才有请求体

比如提交表单参数,就会把表单的参数放在请求体里面

上传图片文件就用字节流

上传的文本就用字符流

java 复制代码
        String agent=req.getHeader("User-Agent");//User-Agent是获取浏览器版本的请求头
        System.out.println(agent);


获取请求体要post请求,我们写个表单

java 复制代码
<!--form的action就是虚拟路径的名称,就是项目加资源路径,这个就会把你表单提交的数据,通过post提交到demo7就是dopost-->
<form action="/Tomcat-demo1/demo7" method="post" >
  <input type="text" name="username">
  <input type="password" name="password">
  <input type="submit">
    </input>
  </input>
</form>
java 复制代码
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取post的请求体:请求参数,通过流的方式来获取
        //表单里面的数据都是字符串,所以我们用字符流
        BufferedReader br = req.getReader();//写完req.getReader(),alt加enter就会自动添加局部变量。
        // table补齐,或者enter也可以补齐
        String line=br.readLine();//参数只有一行
        System.out.println(line);//流不用关闭,因为req被销毁的时候,流就自动关闭了
    }

注意要关闭@WebServlet(urlPatterns = "/")这个哦,上一节说过的




2.2 request通用方式获取请求参数

这里要使用两种方式获取请求参数,要写两份,很麻烦,能够统一就好了

因为获取请求参数,后面执行的代码都是一样的,如果不同意就要写两份,统一的话,互相调用就可以了,因为代码是一样的

但是不能删post的,因为有post请求咋办,但是post和get代码一样,所以互相调用


params就长这个样子了


这三个方法就是通用方式

java 复制代码
<!--form的action就是虚拟路径的名称,就是项目加资源路径,这个就会把你表单提交的数据,通过get提交到demo7就是dopost-->
<form action="/Tomcat-demo1/demo7" 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>
<!--  因为hobby是一个复选框 选第一个值,提交过来的就是1,-->
</br>
  <input type="submit">
    </input>
  </input>
</form>
java 复制代码
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get.....");
        //1.获取所有参数的map集合
        Map<String, String[]> map = req.getParameterMap();
        for (String key : map.keySet()) {//这个是遍历map集合
            //username:zhangsan lisi
            System.out.print(key+":");
            //获取值
            String[] values = map.get(key);
            for (String value : values) {
                System.out.print(value+" ");
            }
            System.out.println();
        }
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        this.doGet(req, resp);
    }
}


变成get了,因为参数在地址那里

java 复制代码
        System.out.println("---------------------------");
        //2.根据可以获取参数值,数组,,,意思就是根据一个key来获取对应的值,因为一个key可能会对应多个值,所以用的数组
        //我们明确知道hobby对应多个值
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }

重启服务器,刷新表单页面

这里的密码是空字符串

java 复制代码
        //3.根据key来获取单个参数值,意思是这个键对应的值只有一个
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(password);
        System.out.println(username);



然后我们把代码原封不动的复制给dopost

然后表单提交方式改为post


这里建议要刷新一下,不然可能一直是get,如果刷新不行,就关了重新来

既然get和post写的一模一样了,那就不要写两遍了

java 复制代码
        this.doGet(req, resp);

这样就会去调用doget,然后对应的参数也是一样的,就可以正常使用了,因为doget和dopost参数一模一样所以可以相互调用

我们还是post的提交方式


这个的反应就是post

然后打印出来,其实走的是doget

2.4 idea模版创建servlet

我们点击设置,编辑器,文件和代码模版,其他,web,Java代码模版,点Servlet Annotated Class.java

改造一下,修改dopost,和webservlet就可以了


如果新建里面没有servlet的话,要到设置里面,编辑器,文件和代码模版,文件,新建一个servlet

这样就有了



第一个选项可以不用选

就这样我们就创建好了

下面分享一下里面的模版内容

java 复制代码
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")

#if ($JAVAEE_TYPE == "jakarta")
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
#else
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
#end
import java.io.IOException;

@WebServlet("/${Entity_Name}")
public class ${Class_Name} extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

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

2.5 请求参数中文乱码-post解决方案

我们先演示一下乱码

改成get和demo8




这样就乱码了,其实post也会乱码

改成post

服务器后退一下,就可以访问了,只有servlet的代码没有变,就没有必要重启代码


也是乱码

java 复制代码
        //2.解决乱码:post,getReader()--->读中文数据的时候不是utf-8,所以会出错
        request.setCharacterEncoding("UTF-8");//设置字符输入流的编码、、、但是要先设置在获取
        //1.获取一下username
        String username = request.getParameter("username");
        System.out.println(username);





下面来get

2.6 请求参数中文乱码-get解决方案

产生get乱码的原因就是解码与编码不一样,但是getQueryString解码方式写死了,所以我们要了解URL编码才行



这里就是URL编码了

Java里面也有URL编码

选第一个

java 复制代码
        String username="张三";
        //1.url编码
        String encode=URLEncoder.encode(username,"utf-8");
        System.out.println(encode);
java 复制代码
        //url解码
        String decode = URLDecoder.decode(encode, "utf-8");
        System.out.println(decode);
java 复制代码
        String decode = URLDecoder.decode(encode, "ISO-8859-1");

Tomcat就是这样处理的

所以会这样

注意乱码和张三的字节是一样的

所以可以把乱码转换成二进制数据,在用UTF-8变成张三

java 复制代码
        //3.转换成字节数据
        byte[] bytes = decode.getBytes("ISO-8859-1");
        for (byte b : bytes) {
            System.out.print(b+" ");
        }

6个字节

java 复制代码
        //3.转换成字节数据
        byte[] bytes = decode.getBytes("ISO-8859-1");
        //转换为字符串
        String s = new String(bytes, "utf-8");
        System.out.println(s);

所以我们只需要干第三步和第四步

java 复制代码
        //1.获取一下username
        String username = request.getParameter("username");
        System.out.println("乱码前"+username);

        //3.get   getParameter针对post用的流,针对get用的字符串,所以不一样,,所以get
        //get获取参数的方式;getQueryString,没有走流,所以不一样
        //乱码原因
        //tomcat用的是ISO-8859-1解码
        //先对乱码数据编码
        byte[] bytes = username.getBytes("ISO-8859-1");
//        byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);//这个也是一样的
//        String s = new String(bytes, "utf-8");
        username = new String(bytes, StandardCharsets.UTF_8);
        System.out.println("乱码后"+username);



java 复制代码
        //合二为一
        username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);

这句代码还可以解决post的






因为我们当前的tomcat只到了7版本所以会出错

2.7 request请求转发



创建两个demo

java 复制代码
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo9");
        //请求转发
        request.getRequestDispatcher("/demo10").forward(request, response);
    }



资源跳转,那么我们就要共享数据,数据就要存在一个地方,这个地方就是request

java 复制代码
        //存储数据
        request.setAttribute("msg", "hello");//这个数据就会放在request,随着转发而转发
java 复制代码
        //获取数据
        Object msg = request.getAttribute("msg");
        System.out.println(msg);


修改了servlet代码就要重启服务器



第一虽然资源转变了但是路径并没有变

只能在同一个服务器里边,不能跑到百度那里去了

3. response

3.1 设置响应数据功能介绍

http是协议和版本号,200是状态码,OK是状态码的描述

3.2 完成重定向

302是告诉我们要重定向,location是告诉重定向的位置在哪里


java 复制代码
        System.out.println("resp1");
        //重定向
        //1. 设置响应状态码
        response.setStatus(302);
        //2,。设置响应头
        //response.setHeader("Location", "http://localhost:8080/resp2");//或者
        response.setHeader("Location", "/Tomcat-demo1/resp2");//这个路径要加虚拟目录名称

重启服务器,反退输入resp1


我们发现重定向的302和location都固定,所以可以优化

java 复制代码
        response.sendRedirect( "/Tomcat-demo1/resp2");






因为请求资源是通过浏览器发出的,所以可以到任意的资源

java 复制代码
        response.sendRedirect( "https://www.itcast.cn");

这个就是外部资源


两次请求就有两个requset域,就不能在多个资源中使用request共享数据

3.3 资源路径问题

重定向要加上虚拟目录,资源转发不需要

要访问远的,浏览器使用,就加上虚拟目录,近的,服务端使用,就不需要加上虚拟目录


href是超链接,浏览器发出的,远的

form表单浏览器发出请求,提交到服务器的某一个资源

转发--》服务器内部

注意虚拟目录的这个值我们可以动态的配置,

path那里就可以动态的配置

但是这里改的话,其他地方的虚拟目录就写死了

所以可以让虚拟目录的值动态的获取

java 复制代码
        String contextPath = request.getContextPath();//获得虚拟目录
        response.sendRedirect(contextPath+"/resp2");

这样和前面也是一样的


3.4 response响应字符数据

java 复制代码
        //响应字符数据,设置字符数据的响应体
        PrintWriter writer = response.getWriter();//字符输出流
        writer.write("aaaa");



java 复制代码
        writer.write("<h1>aaaa</h1>");


但是这样却原模原样的展示了

因为没有告诉我们响应的是html的,这里默认的就是纯文本的形式

java 复制代码
        //响应字符数据,设置字符数据的响应体
        PrintWriter writer = response.getWriter();//字符输出流
        //设置头
        response.setHeader("content-type", "text/html");//告诉浏览器,将来我响应的数据格式是html格式,不是纯文本
        writer.write("aaaa");
        writer.write("<h1>aaaa</h1>");



但是真正响应的数据还是原来的样子,只不过用了html的解析

第一writer不用关闭,这个流不用关闭

第二中文数据也可以响应,但是会乱码,因为这个字符输出流还是上面那个,不是UTF-8

所以要设置流的编码

就是对 response.setHeader("content-type", "text/html");简化书写格式

setContentType这个方法不仅可以设置tContentType这个头,还可以设置流的编码,但还是要先设置,在获取流的编码

java 复制代码
    response.setContentType("text/html;charset=utf-8");//要的是html的数据格式,;charset=utf-8就可以支持中文了
    PrintWriter writer = response.getWriter();//字符输出流
    writer.write("你好");
    writer.write("<h1>aaaa</h1>");



3.5 response响应字节数据

为了响应字节数据,我们用一张图片来

java 复制代码
        //读取文件
        FileInputStream fis = new FileInputStream("E:\\JavaWeb\\java-web\\Tomcat-demo1\\src\\main\\resources\\pin\\a.png");
        //获取字节输出流
        ServletOutputStream os = response.getOutputStream();//目的地就是页面的响应数据体
        //完成流的copy
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = fis.read(b)) != -1) {
            os.write(b, 0, len);
        }
        fis.close();//关闭流。os不用关


我们一般不这样实现流的对拷,我们一般使用工具类,引个坐标

java 复制代码
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.17.0</version>
        </dependency>

选第三个,如果没有就刷新Maven

java 复制代码
        //读取文件
        FileInputStream fis = new FileInputStream("E:\\JavaWeb\\java-web\\Tomcat-demo1\\src\\main\\resources\\pin\\a.png");
        //获取字节输出流
        ServletOutputStream os = response.getOutputStream();//目的地就是页面的响应数据体
        IOUtils.copy(fis,os);//参数就是一个输入,一个输出,就可以拷贝了



4. 案例

4.1 环境准备与用户登录


先准备页面

java 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--注意将请求提交给loginServlet-->
<form action="/web_demo_war_exploded/loginServlet" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">
</form>
</body>
</html>

mabatis环境准备

数据库的

java 复制代码
-- 创建数据库
CREATE DATABASE db1;

USE db1;

-- 创建用户表
CREATE TABLE tb_user(
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(20) UNIQUE,
	PASSWORD VARCHAR(32)
);

-- 添加数据
INSERT INTO tb_user(username,PASSWORD) VALUES('zhangsan','123'),('lisi','234');

SELECT * FROM tb_user;

OK这样我们就创建好了

现在在创建user的实体类

java 复制代码
package pojo;

public class User {
    private Integer id;
    private String username;
    private String password;

    public User() {
    }

    public User(Integer id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = 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;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

现在导入mybatis坐标,mysql驱动坐标

原来

现在导入mybatis坐标

java 复制代码
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>

mysql驱动坐标

java 复制代码
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>

现在创建mybatis核心配置文件,UserMapper.xml映射文件,和UserMapper接口

mybatis核心配置文件

在resources底下新建

java 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

<!--    起别名-->
    <typeAliases>
        <package name="pojo"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
<!--                db1数据库,useSSL=false关闭安全链接,性能更高,useServerPrepStmts=true,预编译功能&amp;就是and-->
                <property name="url" value="jdbc:mysql://localhost:13306/db1?useSSL=false&amp;useServerPrepStmts=true"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--        扫描mapper,是从java开始的-->
        <package name="mapper"/>
    </mappers>
</configuration>

在新建一个接口

UserMapper.xml映射文件,

在resources底下新建目录,这个目录,和java对应,和mapper的目录必须要一模一样

java 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.UserMapper">
<!--    这里的接口名称就是全路径名,就是不写java目录的接口的路径名-->

</mapper>


java 复制代码
public interface UserMapper {
    //查询用户的,根据用户名和密码,返回user对象
    @Select("select * from tb_user where username = #{username} and password = #{password}")
    User select(String username, String password);//接下来对这个接口的方法,声明一个sql来对应,因为sql语句简单,所以用注解
}

还不够,因为有多个参数,所以还要加上param注解

java 复制代码
public interface UserMapper {
    //查询用户的,根据用户名和密码,返回user对象
    @Select("select * from tb_user where username = #{username} and password = #{password}")
    User select(@Param("username") String username,@Param("password") String password);//
    //@Param("username")这个username要和#{username}里面的一一对应
    //接下来对这个接口的方法,声明一个sql来对应,因为sql语句简单,所以用注解
}

所以mabatis的工作就做完了

java 复制代码
<form action="/web_demo_war_exploded/loginServlet" method="post">

在login.html中,action还要改一下

要加上虚拟目录

java 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--注意将请求提交给loginServlet-->
<!--虚拟地址中的Tomcat-demo1,就是项目名称,loginServlet就是资源-->
<form action="/Tomcat-demo1/loginServlet" method="post" id="form">
    <h1 id="loginMsg">LOGIN IN</h1>
    <p>Username:<input type="text" name="username" id="username"></p>
    <p>Password:<input type="password" name="password" id="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>
</body>
</html>

下面写一个login的servlet

我们在response底下创建

java 复制代码
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.接收用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //2.调用mabatis来完成查询
        //2.1 获取SqlSessionFactory对象------》直接官网粘贴
        String resource = "mybatis-config.xml";//mybatis-config.xml这个直接就在resources下,所以直接写名字就可以了
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.2 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //2.3 获取Mapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//Mapper的类型就是UserMapper.class
        //2.4 调用方法
        User user = userMapper.select(username, password);
        //2.5 释放资源
        sqlSession.close();
        //3.判断user是否null,为null登录失败
        //获取字符输出流,并设置content type
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();//用来响应数据,响应的是中文数据,所以还要设置
        if (user != null) {
            //登录成功
            writer.write("登录成功");
        }else {
            //登录失败
            writer.write("登录失败");
        }
    }

这样我们就写完了,我们先访问login.html


先故意输错密码

但是我这样运行不了,我修改一下

这里加个cj,因为我是mysql8版本的

然后就是我修改了一下目录

然后就是这里,我们应该写3306,或者不写locallhost

java 复制代码
                <property name="url" value="jdbc:mysql:///db1?useSSL=false&amp;useServerPrepStmts=true"/>

ok,经过我的仔细检查,发现错误最终在

java 复制代码
                <property name="url" value="jdbc:mysql://localhost:3306/db1?allowPublicKeyRetrieval=true&amp;useSSL=false"/>

就是这个url没写对,害得我网页一直是500错误,可以把网页的错误给ai看一下,就可能知道是什么错误了

在修改一下

java 复制代码
  <property name="url" value="jdbc:mysql://localhost:3306/db1?allowPublicKeyRetrieval=true&amp;useSSL=false&amp;useServerPrepStmts=true"/>

其实没什么大的错误,就是cj,还有mysql版本,还有就是这个url问题

具体细节和代码,可以看我的gitee
gitee

下面我们就直接运行了


4.2 用户注册


UserMapper

java 复制代码
    //根据用户名,查询用户对象
    @Select("select * from tb_user where username = #{username}")
//    User selectByUsername(@Param("username") String username);
    User selectByUsername(String username);//只有一个参数,不需要写Param注解
    
    //添加用户
    @Insert("insert into tb_user values(null,#{username},#{password})")//因为主键是自增长的,所以不用写出来,写个null就可以了
    void add(User user);

下面开始写注册页面

java 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div class="reg-content">
  <h1>欢迎注册</h1>
  <span>已有账号?</span><a href="login.html">登录</a>
</div>

<form action="/Tomcat-demo1/registerServlet" method="post" id="reg-form">
  <table>
    <tr>
      <td>用户名:</td>
      <td class="inputs">
        <input type="text" name="username" id="username">
        <br>
<!--        <span id="username_err" class="err-msg" style=".err-msg">用户名不太受欢迎</span>-->
      </td>
    </tr>

    <tr>
      <td>密码:</td>
      <td class="inputs">
        <input type="password" name="password" id="password">
        <br>
<!--        <span id="password_err" class="err-msg" style="color: red; font-size: 12px;">密码格式有误</span>-->
    </tr>

  </table>
  <div class="button">
    <input value="注册" type="submit" id="reg-btn">
  </div>
  <br class="clear">
</form>
</body>
</html>

下面开始创建servlet

java 复制代码
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.接收用户数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        //分装用户对象,因为void add(User user);,参数就是用户对象
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        //2.调用mapper,根据用户名查询用户对象
        //直接复制过来
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //调用方法
        User u = userMapper.selectByUsername(username);
        //3.判断用户对象是否为null
        if (u == null) {
            //不存在就添加
            userMapper.add(user);
            //因为这个是增删改的操作,所以还要一定要提交事务
            sqlSession.commit();
            //释放资源
            sqlSession.close();
        }else {
            //存在就添加
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().write("用户名已存在");//中文的话,就要设置一下编码
        }

    }

OK,我们就这样水淋淋的写完了

先访问登录页面,因为登录页面可以跳转到注册页面

点击注册



就这样我们就成功了

4.3 SqlSessionFactory工具类抽取

SqlSessionFactory这个对象我们在两个servlet中都创建了一次,相当于创建了两次,所以有点问题

第一就是重复了

第二就是SqlSessionFactory工厂对象创建一个就可以了,因为这是一个链接池,创建一个就好了

一般来说,重复代码,抽取一个工具类就可以了

连包带类的创建的话,直接就创建java类就可以了

java 复制代码
public class SqlSessionFactoryUtils {
    
    private static SqlSessionFactory sqlSessionFactory;
    
    //将那三行代码写在静态代码块里面,就只会执行一次了,随着类的加载而自动执行,只会一次,但是静态代码块不能抛异常,所以我们要try catch
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSessionFactory getSqlSessionFactory() {
        //这样我们只需要在这个方法里面放回静态代码块里面的工厂就可以了
        //如何用静态代码块里面的局部变量呢,提升一下作用域就可以了---》设置一个private变量
        return sqlSessionFactory;
    }
}

这样我们就写完了工具类

我们在doget里面添加这个代码就可以了

java 复制代码
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();


然后我们发现sqlSession也是重复的

但是这个不需要共享同一个

因为这只是一个对象,不同用户之间最好不要共享,连接池共享就可以了

欧克,我们还是可以运行的

总结

最好再提供一下gitee
gitee

下一次讲JSP

相关推荐
盼兮*1 天前
Python调用星火认知大模型API(流式传输)
开发语言·python·flask·request
不修×蝙蝠4 天前
搭建Tomcat(六)---Response的实现
java·服务器·tomcat·response
知兀9 天前
Maven
java·笔记·maven·javaweb·黑马程序员
SunnyRivers14 天前
黑马程序员Java项目实战《苍穹外卖》Day12
javaweb·苍穹外卖
岁岁岁平安15 天前
JavaWeb学习(4)(四大域、HttpSession原理(面试)、SessionAPI、Session实现验证码功能)
java·学习·javaweb·session·httpsession
大臣不想在月亮上上热搜19 天前
黑马2024AI+JavaWeb开发入门Day05-数据库DDL、DML、DQL飞书作业
sql·mysql·javaweb
SunnyRivers20 天前
黑马程序员Java项目实战《苍穹外卖》Day05
javaweb·苍穹外卖
岁岁岁平安23 天前
JavaWeb实战(1)(重点:分页查询、jstl标签与jsp、EL表达式、Bootstrap组件搭建页面、jdbc)
java·servlet·javaweb·jsp·el·分页查询·jstl
SunnyRivers25 天前
黑马程序员Java项目实战《苍穹外卖》Day01
javaweb·苍穹外卖
Slow菜鸟1 个月前
JavaWeb
javaweb