小黑子—JavaWeb:第四章 Request与Response

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 {
    @Override
    protected 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);
    }

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

    }
}

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

2、请求头:
在这里插入图片描述

  • String getHeader(String name):根据请求头名称,获取值
@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected 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);
    }

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

    }
}

在这里插入图片描述

3、请求体:
在这里插入图片描述

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

案例:
RequestDemo1类:

@WebServlet("/req1")
public class RequestDemo1 extends HttpServlet {
    @Override
    protected 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);
    }

    @Override
    protected 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<String, String[ ]> 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 {
    @Override
    protected 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: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);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取post 请求体:请求参数
        this.doGet(req,resp);//一样法典复用即可
//        System.out.println("post....");
//
//        //1.获取所有参数的map集合
//        Map<String, String[]> 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 {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.解决乱码:POST getReader()
        request.setCharacterEncoding("UTF-8");//设置字符输入流的参数

        //2.获取username
        String username = request.getParameter("username");
        System.out.println(username);

    }

    @Override
    protected 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 {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.解决乱码:POST getReader()
        request.setCharacterEncoding("UTF-8");//设置字符输入流的参数

        //2.获取username
        String 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);
    }

    @Override
    protected 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 {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo5...");

        //请求转发
        request.getRequestDispatcher("/req6").forward(request,response);
    }

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

RequestDemo6类:

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

    @Override
    protected 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 {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo5...");

        //存储数据
        request.setAttribute("msg","helloworld");

        //请求转发
        request.getRequestDispatcher("/req6").forward(request,response);
    }

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

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

        //获取数据
        Object msg = request.getAttribute("msg");
        System.out.println(msg);
    }

    @Override
    protected 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、响应体: <html><head>head><body></body></html>

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

3.2 Response 完成重定向

重定向(Redirect):一种资源跳转方式
在这里插入图片描述

案例:
ResponseDemo1类:

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp1......");

        //重定向
        //1.设置响应状态码302
        response.setStatus(302);
        //2.设置响应头 Location
//        response.setHeader("Location","/request_demo_war/resp2"); request_demo_war为自己的启动目录

        //简化方式完成重定向
        response.sendRedirect("/request_demo_war/resp2");
    }

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

ResponseDemo2类:

@WebServlet("/resp2")
public class ResponseDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp2......");
    }

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

  • 重定向特点:
    • 浏览器地址栏路径发生变化
    • 可以重定向到在意位置的资源(服务器内部、外部均可)
    • 两次请求,不能在多个资源使用request共享数据

对比:
在这里插入图片描述

3.2.1 资源路径问题

明确路径谁使用?

  • 浏览器使用:需要加虚拟目录(项目访问路径)
  • 服务端使用:不需要加虚拟目录
    在这里插入图片描述
    在这里插入图片描述

例如:

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp1......");

        //重定向
        //1.设置响应状态码302
        response.setStatus(302);
        //2.设置响应头 Location
//        response.setHeader("Location","/request_demo_war/resp2"); request_demo_war为自己的启动目录

        //简化方式完成重定向
        //动态获取虚拟目录
        String contextPath = request.getContextPath();

        response.sendRedirect(contextPath+"/resp2");
    }

    @Override
    protected 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 {
    @Override
    protected 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("<h1>aaaa</h1>");

    }

    @Override
    protected 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 {
    @Override
    protected 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.完成流的copy
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = fis.read(buff))!=-1){
            os.write(buff,0,len);
        }

        fis.close();

    }

    @Override
    protected 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">&nbsp;&nbsp;&nbsp;
            <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;
    }

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

  • mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//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&amp;useServerPrepStmts=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--扫描mapper-->
        <package name="com.itheima.mapper"/>
    </mappers>
</configuration>
  • UserMapper.xml
<?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="com.itheima.mapper.UserMapper">

</mapper>

4.1.2 代码实现

在这里插入图片描述

  • 核心配置文件:端口自行设置,如果端口被有的站点站了,那么后面网页登录提交后会报500错误
<?xml version="1.0" encoding="UTF-8"?>

<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 {
    @Override
    protected 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 获取Mapper
        UserMapper 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释放为null
        if (user!=null){
            // 登录成功
            Pwriter.write("登录成功");
        }else {
            // 登录失败
            Pwriter.write("登录失败");
        }
    }

    @Override
    protected 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 {
    @Override
    protected 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 获取Mapper
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //2.4 调用方法
        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("用户名已存在");
        }
    }

    @Override
    protected 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;
    }
}

实现:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp h5 竖向的swiper内嵌视频实现抖音短视频垂直切换,丝滑切换视频效果,无限数据加载不卡顿

一、项目背景&#xff1a;实现仿抖音短视频全屏视频播放、点赞、评论、上下切换视频、视频播放暂停、分页加载、上拉加载下一页、下拉加载上一页等功能。。。 二、前言&#xff1a;博主一开始一直想实现类似抖音进入页面自动播放当前视频&#xff0c;上下滑动切换之后播放当前…

CAN学习笔记3:STM32 CAN控制器介绍

STM32 CAN控制器 1 概述 STM32 CAN控制器&#xff08;bxCAN&#xff09;&#xff0c;支持CAN 2.0A 和 CAN 2.0B Active版本协议。CAN 2.0A 只能处理标准数据帧且扩展帧的内容会识别错误&#xff0c;而CAN 2.0B Active 可以处理标准数据帧和扩展数据帧。 2 bxCAN 特性 波特率…

24考研数据结构-数组和特殊矩阵

目录 数据结构&#xff1a;数组与特殊矩阵数组数组的特点数组的用途 特殊矩阵对角矩阵上三角矩阵和下三角矩阵稀疏矩阵特殊矩阵的用途 结论 3.4 数组和特殊矩阵3.4.1数组的存储结构3.4.2普通矩阵的存储3.4.3特殊矩阵的存储1. 对称矩阵(方阵)2. 三角矩阵(方阵)3. 三对角矩阵(方阵…

【Go语言】Golang保姆级入门教程 Go初学者介绍chapter1

Golang 开山篇 Golang的学习方向 区块链研发工程师&#xff1a; 去中心化 虚拟货币 金融 Go服务器端、游戏软件工程师 &#xff1a; C C 处理日志 数据打包 文件系统 数据处理 很厉害 处理大并发 Golang分布式、云计算软件工程师&#xff1a;盛大云 cdn 京东 消息推送 分布式文…

汉明距离,两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。

题记&#xff1a; 两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。 给你两个整数 x 和 y&#xff0c;计算并返回它们之间的汉明距离。 示例 1&#xff1a; 输入&#xff1a;x 1, y 4 输出&#xff1a;2 解释&#xff1a; 1 (0 0 0 1) 4 (0 1 0 0…

spring5源码篇(13)——spring mvc无xml整合tomcat与父子容器的启动

spring-framework 版本&#xff1a;v5.3.19 文章目录 整合步骤实现原理ServletContainerInitializer与WebApplicationInitializer父容器的启动子容器的启动 相关面试题 整合步骤 试想这么一个场景。只用 spring mvc&#xff08;确切来说是spring-framework&#xff09;&#x…

PostgreSQL 简洁、使用、正排索引与倒排索引、空间搜索、用户与角色

PostgreSQL使用 PostgreSQL 是一个免费的对象-关系数据库服务器(ORDBMS)&#xff0c;在灵活的BSD许可证下发行。PostgreSQL 9.0 &#xff1a;支持64位windows系统&#xff0c;异步流数据复制、Hot Standby&#xff1b;生产环境主流的版本是PostgreSQL 12 BSD协议 与 GPL协议 …

TypeScript -- 类

文章目录 TypeScript -- 类TS -- 类的概念创建一个简单的ts类继承 public / private / protected-- 公共/私有/受保护的public -- 公共private -- 私有的protected -- 受保护的 其他特性readonly -- 只读属性静态属性 -- static修饰ts的getter /setter抽象类abstract TypeScrip…

【深入理解NAND Flash】 闪存(NAND Flash) 学习指南

依公开知识及经验整理&#xff0c;付费内容&#xff0c;禁止转载。 所在专栏 《深入理解Flash:闪存特性与实践》 1. 我想和你说 漠然回首&#xff0c;从事存储芯片行业已多年&#xff0c;这些年最宝贵的青春都献给了闪存&#xff0c;虽不说如数家珍&#xff0c;但也算专业。 …

Nginx下载、安装与使用

Nginx下载 简介&#xff1a; Nginx是一个高性能的HTTP和反向代理web服务器&#xff0c;同时也提供了IMAP/POP3/SMTP服务&#xff08;邮件服务&#xff09;。 官网下载地址&#xff1a; https://nginx.org/en/download.html 国内镜像地址&#xff1a; https://mirrors.huawe…

华为云NFS使用API删除大文件目录

最近在使用华为云SFS时&#xff0c;如果一个目录存储文件数超过100W&#xff0c;执行 “rm -rf path”时&#xff0c;存在删不动的情况&#xff0c;可以使用华为云API接口&#xff0c;执行异步删除。 华为官网&#xff1a; 删除文件系统目录_弹性文件服务 SFS_API参考_SFS Tu…

Redis入门

一、Redis的安装 Redis的官方文档介绍了多种安装方式(包括Linux、Windows、MacOs平台上的安装和从源码包安装)&#xff1a;Redis安装。这里只介绍源码安装方式。 下载源码包 $ wget https://download.redis.io/redis-stable.tar.gz编译Redis $ tar -xzvf redis-stable.tar.gz …

Linux下进程特性总结:工作目录,环境变量,标准输出转命令行参数,O_CLOEXEC标志作用,读写锁控制进程互斥

进程是运行中的程序&#xff0c;是资源分配的最小单位&#xff0c;其有一些特性对于实际开发很有帮助&#xff0c;本篇博客将进程的相关特性进行梳理总结&#xff0c;包含工作目录&#xff0c;环境变量&#xff0c;标准输出转命令行参数&#xff0c;读写锁控制进程互斥。 目录…

MyBatis学习笔记之缓存

文章目录 一级缓存一级缓存失效 二级缓存二级缓存失效二级缓存相关配置 MyBatis集成EhCache 缓存&#xff1a;cache 缓存的作用&#xff1a;通过减少IO的方式&#xff0c;来提高程序的执行效率 mybatis的缓存&#xff1a;将select语句的查询结果放到缓存&#xff08;内存&…

Pytorch深度学习-----神经网络的卷积操作

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

IDEA将本地项目上传到码云

一、创建本地仓库并关联 用IDEA打开项目&#xff0c;在菜单栏点击vcs->create git repository创建本地仓库&#xff0c; 选择当前项目所在的文件夹当作仓库目录。 二、将项目提交本地仓库 项目名右键就会出现“GIT”这个选项->Add->Commit Directory, 先将项目add…

【嵌入式学习笔记】嵌入式基础11——STM32常用轮子(SYSTEM)

1.deley文件夹介绍 1.1.delay文件夹介绍 函数名函数功能OSdelay_osschedlockus级延时时,关闭任务调度(防止打断us级延迟)OSdelay_osschedunlockus级延时时,恢复任务调度OSdelay_ostimedlyus级延时时,恢复任务调度OSSysTick_Handlersystick中断服务函数OSdelay_init初始化延迟…

【学习笔记】关于图像YUV格式分类和排布方式的全学习

这里是尼德兰的喵学习笔记相关文章&#xff0c;欢迎您的访问&#xff01; 如果文章对您有所帮助&#xff0c;期待您的点赞收藏 让我们一起为芯片前端全栈工程师而努力 目录 前言 YUV格式导图 YUV444 packed planar I444 YV24 semi-planar NV24 NV42 YUV422 packed …

c++静态代码扫描工具clang-tidy详细介绍

clang-tidy 文章目录 clang-tidy1. 什么是clang-tidy2. clang-tidy可以解决什么问题3. 工作原理4. 如何使用clang-tidy4. 总结5. 举例说明&#xff1a; 1. 什么是clang-tidy Clang-Tidy是一个由LLVM项目提供的开源工具&#xff0c;是一个静态分析工具&#xff0c;用于进行静态…

【雕爷学编程】MicroPython动手做(15)——掌控板之AB按键3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…