Day32:安全开发-JavaEE应用Servlet路由技术JDBCMybatis数据库生命周期

目录

JavaEE-HTTP-Servlet&路由&周期

JavaEE-数据库-JDBC&Mybatis&库

思维导图


Java知识点:

功能:数据库操作,文件操作,序列化数据,身份验证,框架开发,第三方库使用等.

框架库:MyBatisSpringMVCSpringBootShiroLog4jFastJson

技术:ServletListenFilterInterceptorJWTAOP,待补充

安全:SQL注入,RCE执行,反序列化,脆弱验证,未授权访问,待补充

安全:原生开发安全,第三方框架安全,第三方库安全等,待补充

JavaEE-HTTP-Servlet&路由&周期

参考:https :// blog . csdn . net / qq_52173163 / article / details / 121110753

1、解释

Servlet是运行在Web服务器或应用服务器上的程序,它是作为来自Web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库或应用程序之间的中间层。使用Servlet可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。本章内容详细讲解了web开发的相关内容以及servlet相关内容的配置使用,是JAVAEE开发的重中之重。

2、创建和使用Servlet

-创建一个类继承HttpServlet

-web.xml配置Servlet路由

-WebServlet配置Servlet路由

-写入内置方法(init service destroy doget dopost)

3Servlet生命周期

4、处理接受和回显

HttpServletRequestServletRequest的子接口

getParameter(name) — String 通过name获得值

getParameterValues — String[ ] 通过name获得多值

HttpServletResponseServletResponse的子接口 

setCharacterEncoding() 设置编码格式

setContentType() 设置解析语言

getWriter() 获得一个PrintWriter字符输出流输出数据

PrintWriter 接受符合类型数据

IDEA配置

  1. 打开idea
  2. 创建javaEE项目
  3. 项目模板选用Web程序,创建Tomcat服务器
  4. 下载JDK1.8稳定版
  5. 选择javaEE 8创建项目即可
  6. 点击运行,即可看到网页页面

然后一路 next, 可能报错 javaee9 至少需要 java11 支持,直接将 javaee9 换为 javaee8 即可

要记得添加框架支持:Web框架,JavaEE框架支持

Facet 是 IntelliJ IDEA 中用于向项目添加功能和框架支持的概念,它提供了配置选项和功能集合。使用 Facet 可以集中管理项目的不同功能和框架的设置和依赖项,提高项目的可维护性和开发效率。

工件是通过编译、打包、构建等过程生成的最终结果。例如,在 Java 中,编译 Java 源代码将生成编译后的字节码文件(.class 文件)作为工件。

Tomcat工件部署

Servlet & 路由 &周期

JavaEE的核心-Servlet:https://blog.csdn.net/qq_52173163/article/details/121110753

Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。使用 Servlet 可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。本章内容详细讲解了 web 开发的相关内容以及 servlet 相关内容的配置使用,是 JAVAEE 开发的重中之重。

创建和使用Servlet

创建一个类继承HttpServlet

web.xml配置Servlet路由

这样也可以

写入内置方法(init service destroy doget dopost)
 

package com.example.demo1;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
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;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

@WebServlet("/a")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // HttpServletRequest是ServletRequest接口的子接口,提供了用于处理HTTP请求的额外功能。
        // HttpServletResponse是ServletResponse接口的子接口,提供了用于处理HTTP响应的额外功能。
        System.out.println("--------------doGet");
        // 通过参数名获取请求中的值。返回一个String,表示与给定参数名相对应的单个值。
        String id =req.getParameter("id");
        // 设置响应内容的类型和编码。常用于指定输出的数据类型,如HTML、JSON等。
        resp.setContentType("text/html;charset=utf-8");
        // PrintWriter是用于向客户端输出字符数据的类,可以接受各种数据类型,然后将其转换为文本并发送到客户端。
        // 通过 resp.getWriter() 获取一个 PrintWriter 对象,用于向客户端返回响应数据。
        PrintWriter out = resp.getWriter();
        // 向客户端发送数据
        out.println("这是GET请求的数据:");
        out.println("id:"+id+"<br>");
        // 通过调用 out.flush() 刷新缓冲区,并调用 out.close() 关闭 PrintWriter 对象。
        out.flush();
        out.close();
    }

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

        String name = req.getParameter("name");
        resp.setContentType("text/html;charset=utf-8");
        PrintWriter out = resp.getWriter();
        out.println("这是post提交的数据");
        out.println(name);
        out.flush();
        out.close();
        // 打印一条日志到终端
        System.out.println("--------------doPost");
    }

    // 当Servlet首次创建时调用的初始化方法
    @Override
    public void init(ServletConfig config) throws ServletException{
        System.out.println("--------------init");
//        try {
//            Class.forName("com.example.servletdemo.NewsServlet");
//
//        } catch (ClassNotFoundException e) {
//            throw new RuntimeException(e);
//        }

    }

    // 当Servlet被销毁时调用的方法
    @Override
    public void destroy() {
        System.out.println("--------------destroy");
        super.destroy();
    }

    // 处理GET和POST请求的服务方法
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("--------------http service");
        super.service(req, resp);
    }

    // 覆盖的用于ServletRequest和ServletResponse的服务方法
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("--------------Servlet service");
        super.service(req, res);
    }
}

Servlet声明周期

初次启动程序,终端没有表现,说明Servlet未被创建

使用get访问这个Servlet

关闭Servlet时

Servlet生命抽泣

JavaEE-数据库-JDBC&Mybatis&库

原生态数据库开发:JDBC

参考:https://www.jianshu.com/p/ed1a59750127

JDBC(Java Database connectivity): 由java提供,用于访问数据库的统一API接口规范.数据库驱动: 由各个数据库厂商提供,用于访问数据库的jar包(JDBC的具体实现),遵循JDBC接口,以便java程序员使用!

1、下载jar

https://mvnrepository.com/

2、引用封装jar

创建lib目录,复制导入后,添加为库

3、注册数据库驱动

Class.forName("com.mysql.jdbc.Driver");

4、建立数据库连接

String url ="jdbc:mysql://localhost:3306/demo01";

Connection connection=DriverManager.getConnection(url,"x","x");

5、创建Statement执行SQL

Statement statement= connection.createStatement();

ResultSet resultSet = statement.executeQuery(sql);

6、结果ResultSet进行提取

while (resultSet.next()){

int id = resultSet.getInt("id");

String page_title = resultSet.getString("page_title");

.......

}

安全修复SQL注入:预编译

原理:提前编译好执行逻辑,你注入的语句不会改变原有逻辑!

-框架数据库开发:Mybatis

Mybatis是一款优秀的持久层框架,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程,减少了代码的冗余,减少程序员的操作。

1、下载Jar包:https://mvnrepository.com/

2、引用jar包,创建lib目录,复制导入后,添加为库

添加为库

3、注册数据库驱动

JDBC(Java Database Connectivity)是 Java 用于与数据库交互的 API,而不同的数据库供应商提供了各自的 JDBC 驱动程序。在这里,"com.mysql.jdbc.Driver" 是 MySQL JDBC 驱动程序的类名。
加载和初始化: 当调用 Class.forName("com.mysql.jdbc.Driver"); 时,它会尝试查找、加载并初始化指定的类。在这个过程中,MySQL JDBC 驱动程序的静态代码块(static {...})会被执行,这通常用于注册驱动程序。

  • 在旧版本的 MySQL 驱动中,com.mysql.jdbc.Driver 是驱动类的完整路径。
  • 在新版本中,com.mysql.cj.jdbc.Driver 是 MySQL Connector/J 的驱动类。

4、建立数据库连接

Class.forName("com.mysql.jdbc.Driver");

// 定义数据库连接的URL,格式为:jdbc:mysql://host:port/database
String url = "jdbc:mysql://localhost:3306/dome01";

// 使用DriverManager获取数据库连接
Connection connection = DriverManager.getConnection(url, "root", "root");

// 打印数据库连接信息
System.out.println(connection);

5、创建Statement执行SQL

connection.createStatement();: 在Connection对象上调用createStatement方法,创建一个Statement对象。Statement对象用于执行SQL语句,它可以执行静态的SQL查询、更新、删除等操作。createStatement方法返回一个新的Statement对象。

创建一个Statement对象,然后使用该对象执行给定的SQL查询语句,将查询结果存储在一个ResultSet对象中。这样,您可以通过遍历ResultSet来检索和处理查询的结果集中的数据。

6、结果ResultSet进行提取

package com.example.demo1;

import java.sql.*;


public class NewsServlet{
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        // 加载 MySQL 驱动程序
        Class.forName("com.mysql.jdbc.Driver");
        String url ="jdbc:mysql://localhost:3306/demo01";
        // 通过调用 DriverManager.getConnection() 方法,你可以获取到一个 Connection 对象,
        // 该对象表示与数据库的连接。你可以使用这个 Connection 对象执行 SQL 语句和事务操作。
        Connection connection = DriverManager.getConnection(url,"root","123456");
        System.out.println(connection);
        String sql="select * from news";
        //危险写法
        //String vulsql="select * from news where id="+id;
        //预编译写法
        String safesql="select * from news where id=?";
        System.out.println(sql);
        // connection.createStatement() 是用来创建一个 Statement 对象,
        Statement statement= connection.createStatement();
        // 而 statement.executeQuery(sql) 是用来执行 SQL 查询并返回结果集。
        ResultSet resultSet = statement.executeQuery(sql);
        // resultSet.next() 方法用于将结果集的指针移动到下一行,并返回一个布尔值,
        // 表示是否还有更多行可供遍历。通过使用 while 循环,可以在结果集还有下一行的情况下不断迭代。
        while (resultSet.next()){
            // resultSet.getInt("id") 用于获取当前行 "id" 列的整数值,并将其赋给变量 id。
            int id = resultSet.getInt("id");
            String page_title = resultSet.getString("page_title");
            String heading = resultSet.getString("heading");
            String subheading = resultSet.getString("subheading");
            String content = resultSet.getString("content");
            String img = resultSet.getString("img");
            System.out.println(id+"|"+page_title+"|"+heading+"|"+subheading+"|"+content+"|"+img);
        }
    }
}

安全修复SQL注入:预编译
原理:提前编译好执行逻辑,你注入的语句不会改变原有逻辑!

  1. 预编译写法: safesql 是一个预编译的 SQL 查询语句,其中 ? 是一个占位符,表示将在执行时动态替换。
  2. 使用 PreparedStatement: PreparedStatement 是 Statement 的子接口,用于执行预编译的 SQL 语句。通过调用 connection.prepareStatement(safesql) 创建一个 PreparedStatement 对象。
  3. 设置参数: 使用 setXXX 方法设置占位符的值。在这里,使用 setInt(1, id) 将 id 的值设置到第一个占位符上。这种方式防止了 SQL 注入攻击,因为参数值是通过预编译的方式传递的,而不是通过直接拼接字符串。
  4. 执行查询: 调用 executeQuery() 执行查询,得到 ResultSet 对象。
  5. 处理结果集: 根据业务需要,处理查询结果集的数据。
// 预编译写法
String safesql = "SELECT * FROM news WHERE id=?";

// 使用PreparedStatement
try (PreparedStatement preparedStatement = connection.prepareStatement(safesql)) {
    **// 设置参数,防止SQL注入攻击
    preparedStatement.setInt(1, id);**

    // 执行查询
    ResultSet resultSet = preparedStatement.executeQuery();

    // 处理结果集...
} catch (SQLException e) {
    e.printStackTrace();
}

相比较于直接拼接 SQL 语句的方式,预编译语句提供了更好的安全性,可以防止SQL注入攻击。在使用预编译语句时,务必通过参数设置的方式传递值,而不要直接拼接值到 SQL 语句中。

思维导图

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

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

相关文章

RabbitMQ - 04 - Fanout交换机 (广播)

目录 部署demo项目 什么是Fanout交换机 实现Fanout交换机 1.控制台 声明队列 声明交换机 将交换机与队列绑定 2.编写消费者方法 3.编写生产者测试方法 部署demo项目 通过消息队列demo项目进行练习 相关配置看此贴 http://t.csdnimg.cn/hPk2T 注意 生产者消费者的…

转移表回调函数实现

回调函数实现 计算器的模拟&#xff08;函数指针数组的使用&#xff09;&#xff08;回调函数&#xff09; 简化 冗余 老的代码的问题就是 冗余 写死 不能完成不同的任务 函数调用的时候只需要知道地址就可以 calc计算器 这里也称之为转移表 #define _CRT_SECURE_NO_WAR…

微信小程序开发系列(二十五)·wxml语法·条件渲染wx:if, wx:elif, wx:else 属性组以及hidden 属性的使用

目录 1. 使用 wx:if、wx:elif、wx:else 属性组 2. 使用 hidden 属性 条件渲染主要用来控制页面结构的展示和隐藏,在微信小程序中实现条件渲染有两种方式: 1. 使用 wx:if, wx:elif, wx:else 属性组 2. 使用 hidden 属性 wx:if 和 hidden 二者的区别&#xff1a; 1. wx…

计算机网络-第4章 网络层(2)

主要内容&#xff1a;网络层提供的两种服务&#xff1a;虚电路和数据报&#xff08;前者不用&#xff09;、ip协议、网际控制报文协议ICMP、路由选择协议&#xff08;内部网关和外部网关&#xff09;、IPv6,IP多播&#xff0c;虚拟专用网、网络地址转换NAT&#xff0c;多协议标…

背包问题算法

背包问题算法 0-1背包问题二维数组一维数组 完全背包问题二维数组一维数组 多重背包问题一维数组 0-1背包问题 问题&#xff1a;背包的容量为9&#xff0c;有重量分别为[2, 4, 6, 9]的四个物品&#xff0c;价值分别为[3, 4, 5, 6]&#xff0c;求背包能装的物品的最大价值是多少…

构建LVS集群

一、集群的基本理论&#xff08;一&#xff09;什么是集群 人群或事物聚集&#xff1a;在日常用语中&#xff0c;群集指的是一大群人或事物密集地聚在一起。例如&#xff0c;“人们群集在广场上”&#xff0c;这里的“群集”是指大量人群聚集的现象。 计算机技术中的集群&…

C语言连接【MySQL】

稍等更新图片。。。。 文章目录 安装 MySQL 库连接 MySQLMYSQL 类创建 MySQL 对象连接数据库关闭数据库连接示例 发送命令设置编码格式插入、删除或修改记录查询记录示例 参考资料 安装 MySQL 库 在 CentOS7 下&#xff0c;使用命令安装 MySQL&#xff1a; yum install mysq…

arcgis栅格数据处理3——定义投影(同样适用于其他类型文件)

进行数据连接时可能出现未设置投影无法链接的情况&#xff0c;需要先定义投影 点击最右侧“目录”&#xff0c;弹出带有系统工具的面板&#xff0c;点击“data management tools”点击“投影”&#xff0c;“定义投影”

【轮式平衡机器人】——TMS320F28069片内外设之eCAP

引入 TMS320F28069的eCAP&#xff08;增强型捕获模块&#xff09;是一个强大的外设&#xff0c;用于精确测量和捕获输入信号的事件和时间戳。 在电机控制、传感器数据采集和信号处理等应用中&#xff0c;eCAP模块可以用于测量霍尔传感器、编码器或其他数字输入信号的周期、频…

计算表达式x*(2^i)的值math.ldexp(x, i)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 计算表达式x*(2^i)的值 math.ldexp(x, i) [太阳]选择题 关于以下代码输出的结果说法正确的是&#xff1f; import math print("【执行】math.ldexp(3,2)") print(math.ldexp(3,2)) …

2024/3/10总结:数据结构教程:顺序表的创建以及基本的12个操作

首先&#xff0c;按照惯例&#xff0c;欢迎大家边听歌边看本博客&#xff01;&#xff01;&#xff01; 这里是神奇的赛尔号_张杰 (kugou.com) 一.背景&#xff1a;由于是上机实验&#xff0c;直接引用数据结构教程第6版73页的实验题1 修改第6&#xff0c;7&#xff0c;8&am…

CI/CD笔记.Gitlab系列:控制台强制修改root用户密码

CI/CD笔记.Gitlab系列 控制台强制修改root用户密码 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.cs…

SpringBoot中的上传文件接口

SpringBoot中的上传文件 上传文件的操作在有些功能中属于比较常用的环节&#xff0c;这里整理下SpringBoot环境中上传文件的实现方式。 这里实现的是上传文件的后台接口&#xff0c;前端部分可以用测试工具模拟实现&#xff0c;就先不在这里表述了。 Dto层 使用MultipartFile…

【C++】类和对象(六个默认成员函数)

文章目录 类的六个默认成员函数**构造函数****构造函数的目的****构造函数的特性** 析构函数析构函数概念析构函数处理的顺序析构函数清理细节 拷贝构造函数拷贝构造函数典型调用场景 赋值运算符重载运算符重载赋值运算重载前置和后置 重载 const成员函数再提权限的问题: 取地址…

Guiding Large Language Models viaDirectional Stimulus Prompting

1. 通过定向刺激提示指导大语言模型 论文地址&#xff1a;[2302.11520] Guiding Large Language Models via Directional Stimulus Prompting (arxiv.org) 源码地址&#xff1a;GitHub - Leezekun/Directional-Stimulus-Prompting: [NeurIPS 2023] Codebase for the paper: &qu…

目标检测论文模型笔记——RCNN系列

RCNN系列模型&#xff08;two-stages、基于区域的)主要包括以下几种&#xff0c;按发布时间排序&#xff1a; RCNN&#xff08;2014年&#xff09;&#xff1a;首次将深度学习应用于目标检测&#xff0c;通过选择性搜索Selective Search提出候选区域&#xff0c;然后使用CNN&am…

章六、集合(1)—— 概念、API、List 接口及实现类、集合迭代

零、 关闭IDEA调试时自动隐藏空元素 一、 集合的概念 存储一个班学员信息&#xff0c;假定一个班容纳20名学员 当我们需要保存一组一样&#xff08;类型相同&#xff09;的元素的时候&#xff0c;我们应该使用一个容器来存储&#xff0c;数组就是这样一个容器。 数组有什么缺…

9. 内核、文件系统加载工具

内核、文件系统加载工具 内核、文件系统加载工具是嵌入式开发必备的工具 1. 烧写BootLoader 1.1 通过超级终端方式 烧写 Bootloader 可以使用超级终端的“传送” |“发送文件”命令进入发送文件对话框&#xff0c;使用 Xmodem 协议和 Kermit 协议发送 Bootloader 的各个文件…

《计算机网络》考研:2024/3/9 2.1.7-数据交换方式;2.2-物理层传输介质;2.3-物理层设备

2024/3/9 2.1.7、2.2、2.3 2.1.7 数据交换方式 电路交换存储转发方式 报文交换分组交换&#xff1a; 数据报方式虚电路方式 电路交换 报文交换 分组交换 2.2 物理层传输介质 物理层的主要任务 物理层设备 中继器&#xff1a; 集线器&#xff08;多口中继器&#xff09;…

如何获取用户请求的真实ip,并返回访问者的ip地理位置?node,vue

一、获取真实IP 方式1、前端调用免费公共接口获取 前端获取访问者的真实的外网ip,可以通过调用接口https://api.ipify.org/来获取。你也可以直接在网页上访问它来看自己的外网ip。 ipify介绍&#xff1a; ipify是一个免费的公共 API&#xff0c;用于获取设备的公共 IP 地址。…