Request和Response

前言

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

1. 介绍

在这里插入图片描述

就是这两个参数
在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

2. requset

2.1 request继承体系

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
前面两个我们都用过了

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

在这里插入图片描述
requset对象是由Tomcat创建的

2.2 request请求数据

在这里插入图片描述
请求行:请求方式+请求资源路径+请求协议+版本号
虚拟目录就是我们项目的目录
URL就是问号前面的
在这里插入图片描述
问号后面的是get方式的请求参数
URI:短的路径


@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();//获取请求方式System.out.println(method);//GETString contextPath=req.getContextPath();//获取虚拟目录,就是项目的访问路径System.out.println(contextPath);//没有设置项目的访问路径,那么返回的默认就是这个模块的名称StringBuffer url=req.getRequestURL();System.out.println(url.toString());//获取URLString uri=req.getRequestURI();//获取uriSystem.out.println(uri);String queryString=req.getQueryString();//获取请求参数System.out.println(queryString);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
}

在这里插入图片描述
在这里插入图片描述
拿着请求参数,切割就可以得到很多个键值对了
在把等号切割就OK了

在这里插入图片描述
获取客户端使用的浏览器的版本信息

在这里插入图片描述
只有post请求才有请求体

比如提交表单参数,就会把表单的参数放在请求体里面
上传图片文件就用字节流
上传的文本就用字符流

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

在这里插入图片描述
在这里插入图片描述
获取请求体要post请求,我们写个表单

<!--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>
    @Overrideprotected 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就长这个样子了

在这里插入图片描述
在这里插入图片描述
这三个方法就是通用方式
在这里插入图片描述

<!--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>
@WebServlet("/demo7")
public class ServletDemo7 extends HttpServlet {@Overrideprotected 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 lisiSystem.out.print(key+":");//获取值String[] values = map.get(key);for (String value : values) {System.out.print(value+" ");}System.out.println();}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        this.doGet(req, resp);}
}

在这里插入图片描述
在这里插入图片描述
变成get了,因为参数在地址那里

在这里插入图片描述

        System.out.println("---------------------------");//2.根据可以获取参数值,数组,,,意思就是根据一个key来获取对应的值,因为一个key可能会对应多个值,所以用的数组//我们明确知道hobby对应多个值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(password);System.out.println(username);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

然后我们把代码原封不动的复制给dopost
然后表单提交方式改为post
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里建议要刷新一下,不然可能一直是get,如果刷新不行,就关了重新来

在这里插入图片描述
既然get和post写的一模一样了,那就不要写两遍了

        this.doGet(req, resp);

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

我们还是post的提交方式

在这里插入图片描述
在这里插入图片描述
这个的反应就是post
在这里插入图片描述
然后打印出来,其实走的是doget

2.4 idea模版创建servlet

在这里插入图片描述

我们点击设置,编辑器,文件和代码模版,其他,web,Java代码模版,点Servlet Annotated Class.java
在这里插入图片描述
改造一下,修改dopost,和webservlet就可以了

在这里插入图片描述
在这里插入图片描述
如果新建里面没有servlet的话,要到设置里面,编辑器,文件和代码模版,文件,新建一个servlet
在这里插入图片描述
这样就有了

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第一个选项可以不用选

就这样我们就创建好了
下面分享一下里面的模版内容

#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 {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doGet(request,response);}
}

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

我们先演示一下乱码

在这里插入图片描述
改成get和demo8

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就乱码了,其实post也会乱码
改成post
在这里插入图片描述
服务器后退一下,就可以访问了,只有servlet的代码没有变,就没有必要重启代码

在这里插入图片描述
在这里插入图片描述
也是乱码

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面来get

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

在这里插入图片描述
产生get乱码的原因就是解码与编码不一样,但是getQueryString解码方式写死了,所以我们要了解URL编码才行

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里就是URL编码了

Java里面也有URL编码

在这里插入图片描述
选第一个

        String username="张三";//1.url编码String encode=URLEncoder.encode(username,"utf-8");System.out.println(encode);

在这里插入图片描述

        //url解码String decode = URLDecoder.decode(encode, "utf-8");System.out.println(decode);

在这里插入图片描述

        String decode = URLDecoder.decode(encode, "ISO-8859-1");

Tomcat就是这样处理的

所以会这样
在这里插入图片描述
注意乱码和张三的字节是一样的
所以可以把乱码转换成二进制数据,在用UTF-8变成张三

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

在这里插入图片描述
6个字节

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

在这里插入图片描述
所以我们只需要干第三步和第四步

//1.获取一下usernameString 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);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

        //合二为一username = new String(username.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);

这句代码还可以解决post的

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为我们当前的tomcat只到了7版本所以会出错

在这里插入图片描述

2.7 request请求转发

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建两个demo

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
资源跳转,那么我们就要共享数据,数据就要存在一个地方,这个地方就是request

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述
修改了servlet代码就要重启服务器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
第一虽然资源转变了但是路径并没有变
只能在同一个服务器里边,不能跑到百度那里去了

3. response

在这里插入图片描述

3.1 设置响应数据功能介绍

在这里插入图片描述
http是协议和版本号,200是状态码,OK是状态码的描述
在这里插入图片描述

3.2 完成重定向

在这里插入图片描述
302是告诉我们要重定向,location是告诉重定向的位置在哪里

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

        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都固定,所以可以优化

        response.sendRedirect( "/Tomcat-demo1/resp2");

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为请求资源是通过浏览器发出的,所以可以到任意的资源

        response.sendRedirect( "https://www.itcast.cn");

在这里插入图片描述

这个就是外部资源

在这里插入图片描述
在这里插入图片描述
两次请求就有两个requset域,就不能在多个资源中使用request共享数据

3.3 资源路径问题

重定向要加上虚拟目录,资源转发不需要
要访问远的,浏览器使用,就加上虚拟目录,近的,服务端使用,就不需要加上虚拟目录

在这里插入图片描述
在这里插入图片描述
href是超链接,浏览器发出的,远的
form表单浏览器发出请求,提交到服务器的某一个资源
转发–》服务器内部
在这里插入图片描述
注意虚拟目录的这个值我们可以动态的配置,
在这里插入图片描述
path那里就可以动态的配置

但是这里改的话,其他地方的虚拟目录就写死了
所以可以让虚拟目录的值动态的获取

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

这样和前面也是一样的
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4 response响应字符数据

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

        writer.write("<h1>aaaa</h1>");

在这里插入图片描述
在这里插入图片描述
但是这样却原模原样的展示了
因为没有告诉我们响应的是html的,这里默认的就是纯文本的形式

        //响应字符数据,设置字符数据的响应体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这个头,还可以设置流的编码,但还是要先设置,在获取流的编码

    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响应字节数据

在这里插入图片描述
为了响应字节数据,我们用一张图片来

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

我们一般不这样实现流的对拷,我们一般使用工具类,引个坐标
在这里插入图片描述

在这里插入图片描述

        <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.17.0</version></dependency>

在这里插入图片描述
选第三个,如果没有就刷新Maven

        //读取文件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 环境准备与用户登录

在这里插入图片描述
在这里插入图片描述
先准备页面
在这里插入图片描述

<!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环境准备
数据库的

-- 创建数据库
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的实体类

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;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
}

在这里插入图片描述
现在导入mybatis坐标,mysql驱动坐标
原来
在这里插入图片描述
现在导入mybatis坐标

        <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.5</version></dependency>

mysql驱动坐标

        <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.34</version></dependency>

在这里插入图片描述
现在创建mybatis核心配置文件,UserMapper.xml映射文件,和UserMapper接口
mybatis核心配置文件
在这里插入图片描述
在resources底下新建

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//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的目录必须要一模一样

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

在这里插入图片描述
在这里插入图片描述

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

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

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的工作就做完了

<form action="/web_demo_war_exploded/loginServlet" method="post">

在login.html中,action还要改一下
要加上虚拟目录

<!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底下创建
在这里插入图片描述
在这里插入图片描述

    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 获取MapperUserMapper 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 typeresponse.setContentType("text/html;charset=utf-8");PrintWriter writer = response.getWriter();//用来响应数据,响应的是中文数据,所以还要设置if (user != null) {//登录成功writer.write("登录成功");}else {//登录失败writer.write("登录失败");}}

在这里插入图片描述
这样我们就写完了,我们先访问login.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先故意输错密码

但是我这样运行不了,我修改一下
在这里插入图片描述
在这里插入图片描述
这里加个cj,因为我是mysql8版本的

在这里插入图片描述

然后就是我修改了一下目录
在这里插入图片描述
然后就是这里,我们应该写3306,或者不写locallhost
在这里插入图片描述

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

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

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

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

  <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

    //根据用户名,查询用户对象@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);

在这里插入图片描述
下面开始写注册页面

<!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

    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.判断用户对象是否为nullif (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类就可以了
在这里插入图片描述

public class SqlSessionFactoryUtils {private static SqlSessionFactory sqlSessionFactory;//将那三行代码写在静态代码块里面,就只会执行一次了,随着类的加载而自动执行,只会一次,但是静态代码块不能抛异常,所以我们要try catchstatic {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里面添加这个代码就可以了

        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

在这里插入图片描述
在这里插入图片描述
然后我们发现sqlSession也是重复的
但是这个不需要共享同一个
因为这只是一个对象,不同用户之间最好不要共享,连接池共享就可以了
在这里插入图片描述
欧克,我们还是可以运行的

总结

最好再提供一下gitee
gitee
下一次讲JSP

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/885729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue全栈开发旅游网项目(10)-设计用户模型

1.设计用户模型 文件地址&#xff1a;accounts/models.py 1.1 用户详细信息 内容包括&#xff1a;性别 手机号 年龄 生日 真实姓名 创建常量&#xff1a;1-男&#xff0c;0-女&#xff1b;editableFalse不许循环 class Profile(models.Model):SEX_CHOICES{(1,男),(0,女)}u…

C++初阶——vector

一、什么是vector vector是表示可变大小的数组的序列容器&#xff0c;就像数组一样&#xff0c;vector也采用连续空间来存储元素。也就是说它的访问和数组一样高效&#xff0c;但是它的大小是动态可变的&#xff0c;并且它的大小会被容器自动处理。 二、vector的构造 常用的构…

迁徙线,动态轨迹线

使用canvas结合贝塞尔曲线实现&#xff0c;效果如下 <template><div class"box"><div class"mapBox"><div class"map"><img src"/img/dataCockpit/map.png" alt"" /><div class"dot&…

SQLI LABS | Less-39 GET-Stacked Query Injection-Intiger Based

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 输入下面的链接进入靶场&#xff08;如果你的地址和我不一样&#xff0c;按照你本地的环境来&#xff09;&#xff1a; http://localhost/sqli-labs/Less-39/ 本关是堆…

NVM 介绍及使用指南

在日常的开发工作中&#xff0c;我们往往会遇到需要在同一台机器上同时管理多个版本的 Node.js 的情况。为了解决这个问题&#xff0c;我一个同事推荐了NVM&#xff08;Node Version Manager&#xff09;。NVM 是一个用于管理 Node.js 版本的工具&#xff0c;可以方便地在不同的…

web——[SUCTF 2019]EasySQL1——堆叠注入

这个题主要是讲述了堆叠注入的用法&#xff0c;来复现一下 什么是堆叠注入 堆叠注入&#xff1a;将多条SQL语句放在一起&#xff0c;并用分号;隔开。 1.查看数据库的名称 查看数据库名称 1;show databases; 发现有名称为ctftraining的数据库 2.对表进行查询 1;show tabl…

【ARM】MDK-烧录配置文件无权限访问

【更多软件使用问题请点击亿道电子官方网站】 1、 问题场景 客户代码编译正常、调试出现报错<Error: Flash Download failed - "Cortex-M4"> 仿真器识别正常&#xff0c;keil-Debug内显示相关信息、设备启动正常。 记录排查步骤&#xff0c;找到配置文件位…

深度解析 ICP 备案、公安备案、等保备案编号与统一社会信用代码

1. 前言 在当今数字化时代&#xff0c;各类网站和系统如雨后春笋般涌现&#xff0c;为了确保网络安全、合法运营以及用户信息保护&#xff0c;不同类型的备案工作应运而生。其中&#xff0c;ICP 备案、公安备案和等保备案尤为重要&#xff0c;它们各自对应的备案编号不仅是一串…

11个简单易用的电商购物车设计案例

文章目录 前言正文1.扁平化设计购物车2.无表格布局购物车3.美食购物车4.响应式购物车5.jQuery购物车6.动态价格更新购物车7.标签式滑动购物车8.动态商店与购物车一体化设计9.简约清爽的购物车设计10.基于Vue.js的购物车11.域名购物车 总结 前言 现在的电子商务网站&#xff0c…

turtlesim修改窗口大小;添加自己的小乌龟;

目前手边有humble版本ROS。以此为教程。其他版本以此类推 github中搜索ros&#xff0c;然后选择ros官网&#xff08;九点方阵那个图标&#xff09;。然后 在branch中&#xff0c;选择humble&#xff0c;然后复制链接。 git clone https://github.com/ros/ros_tutorials.git -…

电阻按材料分类、不同的电阻

TOC 按电阻材料工艺进行分类 3.1.线绕电阻&#xff1a; 使用高电阻率的康铜、锰铜或镍铬合金丝缠绕在陶瓷骨架&#xff08;一般采用陶瓷、塑料、涂覆绝缘层的金属骨架&#xff09;上制作而成的。玻璃釉绕线电阻表面被覆一层玻璃釉&#xff1b;涂漆线绕电阻表面被覆一层保护有…

spark的学习-06

SparkSQL读写数据的方式 1&#xff09;输入Source 方式一&#xff1a;给定读取数据源的类型和地址 spark.read.format("json").load(path) spark.read.format("csv").load(path) spark.read.format("parquet").load(path) 方式二&#xff1a…

react-markdown内容宽度溢出和换行不生效问题

情景复现&#xff1a; 解决办法&#xff0c;添加样式进行限制 /* index.css */ .markdown-container {word-break: break-word; /* 强制长单词断行 */white-space: pre-wrap; /* 保留空白符序列&#xff0c;但是正常地进行换行 */overflow-wrap: break-word; /* 在长单词或…

java双向链表解析实现双向链表的创建含代码

双向链表 一.双向链表二.创建MyListCode类实现双向链表创建一.AddFirst创建&#xff08;头插法&#xff09;二.AddLast创建&#xff08;尾叉法&#xff09;三.size四.remove(指定任意节点的首位删除)五.removeAll(包含任意属性值的所有删除)六.AddIndex(给任意位置添加一个节点…

VMWare虚拟机NAT模式下与外部主机(非宿主机)通信

VMWare虚拟机NAT模式下与外部主机(非宿主机)通信 1. VMWare虚拟机网络 VMWare的三种网络工作模式&#xff1a; Bridged&#xff1a;桥接模式NAT&#xff1a;网络地址转换模式Host-Only &#xff1a;仅主机模式 VMWare 网络连接配置界面如下&#xff1a; 在本次测试环境中&a…

Mac保护电池健康,延长电池使用寿命的好方法

使用Mac的过程中&#xff0c;如何延长电池的使用寿命是大家非常关心的问题&#xff0c;而养成一个良好的充电习惯能够有效的延长电池的使用寿命 避免过度充电和过度放电能够有效的保护电池&#xff0c;因此长时间的充电与长时间放点都不可取&#xff0c;但是在日常的使用过程中…

显示器接口种类 | 附图片

显示器接口类型主要包括VGA、DVI、HDMI、DP和USB Type-C等。 VGA、DVI、HDMI、DP和USB Type-C 1. 观察 VGA接口:15针 DP接口&#xff1a;在DP接口旁&#xff0c;都有一个“D”型的标志。 电脑主机&#xff1a;DP(D) 显示器&#xff1a;VGA(15针) Ref https://cloud.tenc…

qt QUndoCommand 与 QUndoStack详解

1、概述 QUndoCommand 和 QUndoStack 是 Qt 框架中用于实现撤销/重做&#xff08;undo/redo&#xff09;功能的两个核心类。QUndoCommand 是表示单个可撤销操作的基类&#xff0c;而 QUndoStack 则负责管理这些命令的堆栈&#xff0c;提供撤销和重做操作的接口。 QUndoCommand…

双指针(二)双指针到底是怎么个事

一.有效的三角形个数 有效的三角形个数 class Solution {public int triangleNumber(int[] nums) {Arrays.sort(nums);int i0,end nums.length-1;int count 0;for( i end;i>2;i--){int left 0;int right i-1;while(left<right){if(nums[left]nums[right]>nums…

springboot的增删改查商城小实践(b to c)

首先准备一张表&#xff0c;根据业务去设计表 订单编号是参与业务的&#xff0c;他那订单编号里面是有特殊意义的&#xff0c;比如说像什么一些年月日什么的&#xff0c;一些用户的ID都在那编号里面呢&#xff1f;不能拿这种东西当主件啊 根据数据量去决定数据类型 价格需要注意…