JavaWeb 笔记——3

news2024/11/26 10:45:28

JavaWeb 笔记——3

  • JavaWeb技术栈
  • 一、HTTP
    • 1.1、HTTP介绍
    • 1.2、HTTP请求数据格式
    • 1.3、HTTP响应数据格式
  • 二、Web服务器 - Tomcat
    • 2.1、简介&基本使用
    • 2.2、Tomcat配置和部署项目
    • 2.3、Web项目结构
    • 2.4、创建MavenWeb项目
    • 2.5、IDEA集成本地Tomcat
    • 2.6、Tomcat-Tomcat Maven插件
  • 三、Servlet
    • 3.1、Servlet简介&快速入门
    • 3.2、Servlet执行流程和生命周期
    • 3.3、Servlet方法介绍&体系结构
    • 3.4、urlPattern配置
    • 3.5、XML配置Servlet
  • 四、Request
    • 4.1、Request&Response介绍
    • 4.2、Request继承体系
    • 4.3、Request获取请求数据
    • 4.4、Request通用方式获取请求参数
    • 4.5、请求参数中文乱码处理
    • 4.6、Request请求转发
  • 五、Response
    • 5.1、Response设置相应数据功能介绍
    • 5.2、Response完成重定向
    • 5.3、资源路径问题
    • 5.3、Response响应字符数据
    • 5.4、Response响应字节数据
    • 5.5、案例
      • 5.5.1、用户登录
      • 5.5.2、用户注册
    • 5.6、代码优化

JavaWeb技术栈

  • B/S架构: Browser/Server,浏览器/服务器架构模式,它的特点是,客户端只需要浏览器,应用程序的逻辑和数据都存储在服务器端。浏览器只需要请求服务器,获取Web资源,服务器把Web资源发送给浏览器即可
    • 好处:易于维护升级:服务器端升级后,客户端无需任何部署就可以使用到新的版本
      在这里插入图片描述
  • 静态资源: HTML、CSS、JavaScript、图片等。负责页面展现
  • 动态资源: Servlet、JSP等。负责逻辑处理
  • 数据库: 负责存储数据
  • Web服务器: 负责解析HTTP协议,解析请求数据,并发送响应数据

一、HTTP

1.1、HTTP介绍

  • 概念: HyperText Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则

  • HTTP协议特点:

  1. 基于TCP协议:面向连接,安全
  2. 基于请求-响应模型的:一次请求对应一次响应
  3. HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的。
    • 缺点:多次请求间不能共享数据。->Java中使用会话技术(Cookie、Session)来解决这个问题
    • 优点:速度快

1.2、HTTP请求数据格式

  • 请求数据分为3部分:
  1. 请求行:请求数据的第一行。其中GET表示请求方式,/表示请求资源路径,HTTP/1.1表示协议版本
  2. 请求头:第二行开始,格式为key: value形式。
  3. 请求体: POST请求的最后一部分,存放请求参数
  • 常见的HTTP请求头:

  • Host:表示请求的主机名

  • User-Agent:浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 …Chrome/79,IE浏览器的标识类似Mozilla/5.0 (Windows NT …) like Gecko;

  • Accept:表示浏览器能接收的资源类型,如text/*,image*或者*/*表示所有;

  • Accept-Language:表示浏览器偏好的语言,服务器可以据此返回不同语言的网页;

  • Accept-Encoding:表示浏览器可以支持的压缩类型,例如gzip, deflate等。

  • GET请求和POST请求的区别

    1. GET请求请求参数再请求行中,没有请求体。
      POST请求请求参数在请求体
    2. GET请求请求参数大小有限制
      POST没有

1.3、HTTP响应数据格式

响应数据分为3部分:

  1. 响应行:响应数据的第一行。其中HTTP/1.1表示协议版本200表示响应状态码OK表示状态码描述
  2. 响应头:第二行开始,格式为key: value形式
  3. 响应体:最后一部分。存放响应数据
  • 常见的HTTP响应头:
    • Content-Type:表示该响应内容的类型,例如text/html,image/jpeg;
    • Content-Length:表示该响应内容的长度(字节数);
    • Content-Encoding:表示该响应压缩算法,例如gzip;
    • Cache-Control:指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒
状态码分类说明
1xx响应中——临时状态码,表示请求已经接受,告诉客户端应该继续请求或者如果它已经完成则忽略它
2xx成功―—表示请求已经被成功接收,处理已完成
3xx重定向——重定向到其它地方:它让客户端再发起一个请求以完成整个处理。
4xx客户端错误—―处理发生错误,责任在客户端,如:客户端的请求一个不存在的资源,客户端未被授权,禁止访问等
5xx服务器端错误—―处理发生错误,责任在服务端,如:服务端抛出异常,路由出错,HTTP版本不支持等

二、Web服务器 - Tomcat

2.1、简介&基本使用

  • Web服务器是一个应该程序(软件),对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让web开发更加便捷。主要功能是“提供网上信息浏览眠务”

  • 概念: Tomcat是Apache软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。

  • JavaEE: Java Enterprise Edition,Java企业版。指Java企业级开发的技术规范总和。包含13项技术规范:JDBCJNDIEJBRMIJSPServletXMLJMSJava IDLJTSJTAJavaMailJAF

  • Tomcat也被称为Web容器、Servlet容器。Servlet 需要依赖于Tomcat才能运行

Tomcat-基本使用

  • 下载:官网下载

  • 安装:绿色版,直接解压即可

  • 卸载:直接删除目录即可

  • 启动:双击: bin\startup.bat
    在这里插入图片描述

  • 关闭:

    1. 直接×掉运行窗口:强制关闭
    2. bin\shutdown.bat:正常关闭
    3. Ctrl+C:正常关闭

2.2、Tomcat配置和部署项目

  • 配置:

    1. 修改启动端口号:conf/server.xml
      在这里插入图片描述
  • HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号

  • 启动时可能出现的问题:

    1. 端口号冲突:找到对应程序,将其关闭掉
      在这里插入图片描述
    2. 启动窗口一闪而过:检查JAVA_HOME环境变量是否正确配置

Tomcat一部署项目

  • Tomcat部署项目:
    • 将项目放置到webapps目录下,即部署完成
  • 一般JavaWeb项目会被打成war包,然后将war包放到webapps目录下,Tomcat会自动解压缩war文件

2.3、Web项目结构

  • Web项目结构
    • Maven Web项目结构:开发中的项目
      在这里插入图片描述
  • 部署的JavaWeb项目结构:开发完成,可以部署的项目
    在这里插入图片描述

在这里插入图片描述

  • 编译后的Java字节码文件和resources的资源文件,放到WEB-INF下的classes目录下
  • pom.xml中依赖坐标对应的jar包,放入WEB-INF下的lib目录下

2.4、创建MavenWeb项目

  • 使用骨架
    • 骨架:项目模板
  1. 选择Web项目骨架,创建项目
  2. 删除pom.xml中多余的坐标
  3. 补齐缺失的目录结构

在这里插入图片描述

  • 不使用骨架
  1. 选择web项目骨架,创建项目
  2. pom.xml中添加打包方式为war
  3. 补齐缺失的目录结构: webapp

在这里插入图片描述

2.5、IDEA集成本地Tomcat

  • 将本地Tomcat集成到IDEA中,然后进行项目部署即可
    在这里插入图片描述

2.6、Tomcat-Tomcat Maven插件

IDEA中使用Tomcat-Tomcat Maven插件

  1. pom.xml 添加Tomcat插件
<build>
	<plugins>
		<!-- Tomcat 插件-->
		<plugin>
			<groupld>org.apache.tomcat.maven</groupld>
			<artifactld>tomcat7-maven-plugin</artifactld>
			<version>2.2</version>
		</plugin>
	</plugins>
</build>
  1. 使用Maven Helper插件快速启动项目,选中项目,右键–> Run Maven --> tomcat7:run
    在这里插入图片描述

三、Servlet

3.1、Servlet简介&快速入门

  • Servlet是Java提供的一门 动态 web资源开发技术
  • Servlet是JavaEE规范之一,其实就是一个接口,将来我们需要定义Servlet类实现Servlet接口,并由web服务器运行Servlet
  1. 创建web项目,导入Servlet依赖坐标
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
  1. 创建:定义一个类,实现Servlet接口,并重写接口中所有方法,并在service方法中输入一句话
public class ServletDemo1 implements Servlet {
	public void service()
}
  1. 配置:在类上使用@WebServlet注解,配置该Servlet的访问路径
@WebServlet("/demo1")
public class ServletDemo1 implements Servlet {
  1. 访问:启动Tomcat,浏览器输入URL 访问该Servlet
http://localhost:8080/web-demo/demo1

3.2、Servlet执行流程和生命周期

  1. Servlet由谁创建? Servlet方法由谁调用?
    • Servlet由web服务器创建,Servlet方法由web服务器调用。
  2. 服务器怎么知道servlet中一定有service方法?
    • 因为我们自定义的Servlet,必须实现Servlet接口并复写其方法,而Servlet接口中有service方法

生命周期

  • 对象的生命周期指一个对象从被创建到被销毁的整个过程
  • Servlet运行在servlet容器(web服务器)中,其生命周期由容器来管理,分为4个阶段:
    1. 加载和实例化:默认情况下,当Servlet第一次被访问时,由容器创建servlet对象

      • 非默认情况下可以该改变创建时机
      @WebServlet (urlPatterns = "/demo",loadOnStartup =1)
      
      • 负整数:第一次被访问时创建Servlet对象
      • 0或正整数:服务器启动时创建Servlet对象,数字越小优先级越高
    2. 初始化:在Servlet实例化之后,容器将调用servlet的init()方法初始化这个对象,完成一些如加载配置文件、创建连接等初始化的工作。该方法只调用一次

    3. 请求处理每次请求Servlet时,Servlet容器都会调用servlet的service()方法对请求进行处理。

    4. 服务终止:当需要释放内存或者容器关闭时,容器就会调用servlet实例的destroy()方法完成资源的释放。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收

3.3、Servlet方法介绍&体系结构

Servlet方法介绍

  • 初始化方法,在Servlet被创建时执行,只执行一次

    void init(ServletConfig config)
    
  • 提供服务方法,每次Servlet被访问,都会调用该方法

    void service(ServletRequest req, ServletResponse res)
    
  • 销毁方法,当Servlet被销毁时,调用该方法。在内存释放或服务器关闭时销毁servlet

    void destroy()
    
  • 获取ServletConfig对象

    ServletConfig getServletConfig()
    
  • 获取Servlet信息

    String getServletInfo()
    
package com.Smulll.web;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

@WebServlet(urlPatterns = "/demo1",loadOnStartup = 1)
public class ServletDemo1 implements Servlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Servlet hello world");
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
        System.out.println("被销毁了!!");
    }
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init输出了~~~");
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
}

体系结构

在这里插入图片描述
我们将来开发B/S架构的web项目,都是针对HTTP协议,所以我们自定义Servlet,会继承HttpServlet

  1. HttpServlet使用步骤
    1. 继承HttpServlet
    2. 重写doGetdoPost方法
  2. HttpServlet原理
    获取请求方式,并根据不同的请求方式,调用不同的doXxx方法
package com.Smulll.web;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class ServletDemo4 implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
    }
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        //根据请求方式不同分别处理
        HttpServletRequest request =  (HttpServletRequest)servletRequest;
        String method = request.getMethod();
        if ("GET".equals(method)) {
            //get请求处理处理方式
            doGet();
        }else if ("POST".equals(method)){
            //POST请求处理方式
            doPost();
        }
    }
    protected void doPost() {
    }
    protected void doGet() {
    }
    @Override
    public String getServletInfo() {
        return null;
    }
    @Override
    public void destroy() {
    }
}

3.4、urlPattern配置

  • Servlet要想被访问,必须配置其访问路径(urlPattern)

    1. 一个Servlet,,可以配置多个urlPattern
    @WebServlet(urlPatterns = {"/demo1", "/demo2"})
    
    1. urlPattern配置规则
      1. 精确匹配
        • 配置路径:@WebServlet(urlPatterns = "/user/select")
        • 访问路径:localhost:8080/web-demo/user/select
      2. 目录匹配
        • 配置路径:@WebServlet(urlPatterns = "/user/*")
        • 访问路径:localhost:8080/web-demo/user/*
      3. 扩展名匹配
        • 配置路径:@WebServlet(urlPatterns = "*.do")
        • 访问路径:localhost:8080/web-demo/aaa.do
          localhost:8080/web-demd/bbb.do
      4. 任意匹配
        • 配置路径:@WebServlet(urlPatterns = "/")
          @WebServlet(urlPatterns = "/*")
        • 访问路径:localhost:8080/web-demo/hehe
          localhost:8080/web-demo/hehe
  • //*区别:

    • 当我们的项目中的Servlet配置了“/”,会覆盖掉tomcat中的DefaultServlet,当其他的url-pattern都匹配不上时都会走这个Servlet
    • 当我们的项目中配置了“/*”,意味着匹配任意访问路径
  • 注:不要使用这两个路径,会覆盖掉DefaultServlet,导致无法加载出静态资源

  • 优先级:
    精确路径>目录路径>扩展名路径>/* >/

3.5、XML配置Servlet

  • Servlet 从3.0版本后开始支持使用注解配置,3.0版本前只支持XML配置文件的配置方式
  • 步骤
    1. 编写Servlet类
    2. 在web.xml中配置该Servlet
<servlet>
	<servlet-name>demo5</servlet-name>
	<servlet-class>com.Smulll.web.servlet.servletDemo5</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>demo5</servlet-name>
	<url-pattern>/demo5</url-pattern>
</servlet-mapping>

四、Request

4.1、Request&Response介绍

在这里插入图片描述

  • Request:获取请求数据
  • Response:设置响应数据

4.2、Request继承体系

在这里插入图片描述

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

4.3、Request获取请求数据

  • 请求数据分为3部分:
    1. 请求行:GET/request-demo/req1?username=zhangsan HTTP/1.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
    2. 请求头:User-Agent: Mozilla/5.0 Chrome/91.0.4472.106
      • String getHeader(String name):根据请求头名称,获取值
    3. 请求体:username=superbaby&password=123
      • ServletlnputStream getInputStream():获取字节输入流
      • BufferedReader getReader():获取字符输入流

4.4、Request通用方式获取请求参数

  • 请求参数获取方式:
    • GET方式:
    String getQueryString()
    
    • POST方式
    BufferedReader getReader()
    

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

  • Map<String, String[ ]> getParameterMap():获取所有参数Map集合
  • String[ ] getParameterValues(String name)︰根据名称获取参数值(数组)
  • String getParameter(String name):根据名称获取参数值(单个值)
package com.Smulll.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.IOException;
import java.util.Map;
import java.util.function.BiConsumer;
@WebServlet("/request/dome2")
public class RequestDome2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取所有参数Map集合
        Map<String, String[]> map = req.getParameterMap();

        //遍历该map集合
        map.forEach(new BiConsumer<String, String[]>() {
            @Override
            public void accept(String s, String[] strings) {
                System.out.print(s+":");
                for (String string : strings) {
                    System.out.print(string+" ");
                }
                System.out.println();
            }
        });
        System.out.println("-------------------------------------------------");
        //根据名称获取参数值(数组)
        String[] usernames = req.getParameterValues("username");
        String[] passwords = req.getParameterValues("password");
        String[] hobbies = req.getParameterValues("hobby");

        for (String username : usernames) {
            System.out.print(username+ " ");
        }
        System.out.println();
        for (String password : passwords) {
            System.out.print(password+" ");
        }
        System.out.println();
        for (String hobby : hobbies) {
            System.out.print(hobby+" ");
        }
        System.out.println();

        System.out.println("--------------------------------------------------");
        String hobby = req.getParameter("hobby");
        System.out.println(hobby);//1 只打印出第一个
    }
  • 这三种类都通用于GET和POST请求方法

4.5、请求参数中文乱码处理

  • 请求参数如果存在中文数据,则会乱码

  • 解决方案:

    • POST:设置输入流的编码
    req.setCharacterEncoding("UTF-8");
    
    • 通用方式(GET/POST):先编码,再解码
    new String(username.getBytes("ISO-8859-1"),"UTF-8");
    
  • URL编码

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

URL编码实现方式:

  • 编码:
    URLEncoder.encode(str, "utf-8"");
    
  • 解码:
    URLDecoder.decode(s, "ISO-8859-1");
    

4.6、Request请求转发

  • 请求转发(forward):一种在服务器内部的资源跳转方式
    在这里插入图片描述
  • 实现方式:
req.getRequestDispatcher("资源B路径").forward(req,resp);
  • 请求转发资源间共享数据:使用Request对象

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

    • 浏览器地址栏路径不发生变化
    • 只能转发到当前服务器的内部资源
    • 一次请求,可以在转发的资源间使用request共享数据
package com.Smulll.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.IOException;

@WebServlet("/req3")
public class RequestDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Demo3");
        //转发资源
        req.setAttribute("msg","hello");
        //请求转发
        req.getRequestDispatcher("/req4").forward(req,resp);
    }
}
package com.Smulll.web;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/req4")
public class RequestDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("demo4");
        //获取Demo3传来的数据
        Object msg = req.getAttribute("msg");
        System.out.println(msg);
    }
}

在这里插入图片描述

五、Response

5.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():获取字节输出流

5.2、Response完成重定向

  • 重定向(Redirect):一种资源跳转方式
    在这里插入图片描述
  • 实现方式:
resp.setStatus(302);
resp.setHeader("location”,“资源B的路径");
  • 简化方式
resp.sendRedirect("资源B的路径");

代码实现

package com.Smulll.Respone;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/resp1")
public class responeDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("resp1...");
        //告诉浏览器状态码
        resp.setStatus(302);
        //给其资源B的路径
        resp.setHeader("location","resp2");
        //简化方式
        resp.sendRedirect("resp2");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
    }
}
package com.Smulll.Respone;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/resp2")
public class responeDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("resp2...");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {

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

5.3、资源路径问题

  • 明确路径谁使用?
    • 浏览器使用:需要加虚拟目录(项目访问路径)
    • 服务端使用:不需要加虚拟目录

在这里插入图片描述

5.3、Response响应字符数据

使用:

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

代码演示

package com.Smulll.Response;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/resp3")
public class responseDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //设置响应的数据格式以及编码字符集
        resp.setContentType("text/html;charset=UTF-8");
        //获取输出流
        PrintWriter writer = resp.getWriter();
        writer.write("<h1>你好</h1>");
        writer.write("<h2>你好</h2>");
        writer.write("<h3>你好</h3>");
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {

    }
}

在这里插入图片描述

5.4、Response响应字节数据

  • 使用:
  1. 通过Response对象获取字符输出流

    ServletOutputStream outputStream = resp.getOutputStream();
    
  2. 写数据

    outputStream.write(字节数据);
    
  • lOUtils工具类使用
    1. 导入坐标
    <dependency>
    	<groupld>commons-io</groupld>
    	<artifactld>commons-io</artifactld>
    	<versign>2.6</version>
    </dependency>
    
    1. 使用
    IOUtils.copy(输入流,输出流);
    

5.5、案例

5.5.1、用户登录

  • 流程说明:
    1. 用户填写用户名密码,提交到LoginServlet
    2. 在LoginServlet中使用MyBatis查询数据库,验证用户名密码是否正确
    3. 如果正确,响应“登录成功”,如果错误,响应“登录失败”

在这里插入图片描述

  • 准备环境
    1. 复制资料中的静态页面到项目的webapp目录下
    2. 创建db1数据库,创建tb_user表,创建User实体类
    3. 导入MyBatis坐标,MySQL驱动坐标
    4. 创建mybatis-config.xml核心配置文件,UserMapper.xml映射文件,UserMapper接口

代码实现在Tomcat-demo2文件夹中

5.5.2、用户注册

  • 流程说明:
    1. 用户填写用户名、密码等信息,点击注册按钮,提交到RegisterServlet
    2. 在RegisterServlet中使用MyBatis保存数据
    3. 保存前,需要判断用户名是否已经存在:根据用户名查询数据库

在这里插入图片描述
代码实现在Tomcat-demo2文件夹中

5.6、代码优化

  • 创建SqlSessionFactory 代码优化

    //2.1获取SqlSessionFactory对象
    string resource = "mybatis-config.xml";
    Inputstream inputstream = Resources.getResourceAsStream(resource);
    sqlSessionFactory sqlSessionFactory = new sqlSessionFactoryBuilder().build(inputStream);
    
  • 问题:

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

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
public class SqlSessionFactoryUtils {
    private static SqlSessionFactory sqlSessionFactory;
    
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
             sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}

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

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

相关文章

23西安电子科技大学通信工程学院811考研录取情况

01、通信工程学院各个方向 02、23通信工程学院一志愿考研录取情况总览、平均分 PS&#xff1a;通院23年院线相对于22年院线上涨5-15分&#xff0c;个别专业下降10分反应西电通院热度23年和22年基本一致。 PS&#xff1a;1、通院23年比较多的考生在本部学硕、专硕扎堆&#xff…

【花雕】全国青少年机器人技术一级考试备考实操搭建手册6

随着科技的不断进步&#xff0c;机器人技术已经成为了一个重要的领域。在这个领域中&#xff0c;机械结构是机器人设计中至关重要的一部分&#xff0c;它决定了机器人的形态、运动方式和工作效率。对于青少年机器人爱好者来说&#xff0c;了解机械结构的基础知识&#xff0c;掌…

yolov7论文学习——创新点解析、网络结构图

创新点 1、提出了E-ELAN&#xff0c;但是只在yolov7-e6e中使用到。 2、yolov7基于拼接模型的缩放方法&#xff0c;在yolov7x中使用到。 3、将重参数化卷积应用到残差模块中或者用到基于拼接的模块中去。RepConvN 4、提出了两种新的标签分配方法 一、ELAN和E-ELAN 1、 ELAN …

AI 如何应对 DevOps 监控和可观察性挑战

持续监控和可观察性用例 CI异常检测&#xff1a; AI可以分析历史数据以检测持续集成阶段的异常。任何不寻常的变化都可以在进入下一阶段之前进行标记以供审查。IBM Watson AnomalyDetection 等工具可以通过使用 AI 检测模式和异常情况来帮助识别这些异常情况。 代码质量保证&…

如何快速定位linux故障

1、背景 有时候会遇到一些疑难杂症&#xff0c;并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累&#xff0c;并且有些问题涉及到的领域非常广&#xff0c;才能定位到问题。所以&#xff0c…

防火墙详解

1、什么是防火墙&#xff1f; 防火墙&#xff08; Firewall &#xff09;是防止火灾发生时&#xff0c;火势烧到其它区域&#xff0c;使用由防火材料砌的墙。 后来这个词语引入到了网络中&#xff0c;把从外向内的网络入侵行为看做是火灾&#xff0c;防止这种入侵的策略叫做防…

批量多开谷歌浏览器丨非扩展chrome浏览器实现分身多开微博 切换多个微博帐号工具

教你多开用Google 浏览器 实现Chrome怎样同时登录多个微博号 按照此教程多开后的Google浏览器可以实现相互的独立性&#xff0c;每个浏览器上收藏的书签、增加的拓展程序都可以实现独立性并可实现独立记忆性 一、安装正版Google浏览器 1&#xff1a;安装位置最好选择非C盘 二…

基于低代码平台打造的焙乐道销售支持系统

编者按&#xff1a;低代码平台说了那么多&#xff0c;在实际应用中又是怎样体现的它的种种优势呢&#xff1f;今天小编结合实际案例来说说。 本文是以最大的烘焙原料产商——焙乐道的销售支持系统为例子&#xff0c;进行说明。 客户说明&#xff1a;焙乐道是一家国际性集团公司…

凝思系统docker离线安装

# linux离线安装docker (18.03.1-ce) ## 解压&#xff0c;得到docker文件夹 tar xzvf docker-18.03.1-ce.tgz ## 将docker文件夹里面的所有内容复制到/usr/bin目录 sudo cp docker/* /usr/bin/ ## 开启docker守护进程 sudo dockerd & 当终端中显示【API list…

有参构造,无参构造,半缺省构造

目录 有参构造 无参构造 半缺省构造 有参构造 C 中的有参构造函数&#xff08;Parameterized Constructor&#xff09;是一个类中带有参数的特殊成员函数&#xff0c;用于创建对象并根据传入的参数对对象的成员进行初始化。有参构造函数在定义时需要指定参数的类型和名称&am…

相机- yolo训练集 环境搭建

一、环境准备 运行cmd执行python --version 检查是否安装成功 安装pip&#xff0c;打开运行指令 python -m ensurepip --upgrade 打开官网&#xff0c;下载get_pip.py 运行cmd 运行指令python get-pip.py 运行cmd 运行指令 pip --version 显示pip版本即安装成功 根据上面获…

Lucene介绍与入门使用

https://github.com/apache/lucene Lucene简介 Lucene是apache软件基金会4 jakarta项目组的一个子项目&#xff0c;是一个开放源代码的全文检索引擎工具包&#xff0c;但它不是一个完整的全文检索引擎&#xff0c;而是一个全文检索引擎的架构&#xff0c;提供了完整的查询引擎…

宁波阿里云代理商:阿里巴巴CEO张勇:阿里云是一家云计算产品公司

4月26日&#xff0c;在2023阿里云合作伙伴大会上&#xff0c;阿里巴巴董事会主席兼CEO、阿里云智能CEO张勇表示&#xff0c;阿里云的核心定位是一家云计算产品公司&#xff0c;生态是阿里云的根基。 张勇表示&#xff0c;当前我们正站在智能化的起点&#xff0c;这是让“被集成…

基于Python的二维码识别系统设计与实现

博主介绍&#xff1a;擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案例…

基于单片机智能加湿器 水位防干烧加湿器的设计与实现

功能介绍 以51/STM32单片机作为主控系统&#xff1b;LCD1602液晶显示当前温湿度&#xff0c;当前模式&#xff0c;湿度下限;按键设置湿度下限&#xff0c;当湿度低于下限时开启加湿器;水位传感器检查加湿器是否有水&#xff0c;如果没有水到话加湿器不进行工作&#xff0c;蜂鸣…

Spring Security OAuth2.0(2):基于session的认证方式

文章目录 认证流程创建工程1 创建maven工程2. 实现认证功能3. 会话功能4. 授权功能 认证流程 \qquad 基于session的认证方式如下 \qquad 它的交互流程是&#xff0c;用户认证成功后&#xff0c;在服务端生成用户相关的数据保存在session(当前会话)中&#xff0c;发给客户端的s…

银河麒麟服务器v10 sp1 部署.Net6.0 http https

上一篇&#xff1a;银河麒麟服务器V10 SP1 .Net6.0 开机自动启动_csdn_aspnet的博客-CSDN博客 参考微软官网&#xff1a;ASP.NET Core 中的 Kestrel Web 服务器 | Microsoft Learn 为 ASP.NET Core Kestrel Web 服务器配置终结点 | Microsoft Learn 注意&#xff1a;使用此…

【云效】使用流水线进行应用部署

目录 前言一、部署应用步骤1、创建流水线2、编辑流水线源3、编辑java构建上传4、编辑主机部署 前言 「流水线」&#xff0c;又名「Flow」&#xff0c;是阿里云「云效」产品矩阵中的一款企业级自动化研发交付工具。 它提供了灵活易用的持续集成、持续验证和持续发布功能&#…

基于springboot+mybatis-plus+mysql+vue实现物流信息管理系统(课设)

基于springbootmybatis-plusmysqlvue实现物流信息管理系统&#xff08;课设&#xff09; 一、系统介绍1、系统主要功能&#xff1a;2、环境配置 二、功能展示1.登陆2.用户管理3.个人信息4.物流管理 三、其它系统四、获取源码 一、系统介绍 1、系统主要功能&#xff1a; 用户&…

ElasticSearch 快速上手教程 (二) —— 基本概念术语

上一部分&#xff0c;我们讲解了 ES 的一些基本概念和应用场景&#xff0c;以及如何在本机搭建一个 ELK 测试环境。现在这篇文章带你了解 ES 当中一些基本术语以及相关的工作原理。 基本的概念术语 node(节点) ES 的一个运行实例&#xff0c;存储了部分文档数据&#xff0c;属…