java如何预防sql注入

1 sql注入

1.1 使用字符串拼接导致数据异常 sql语句拼接

        // 构建SQL查询语句,注意这里存在SQL注入风险
        String sql = "select name,age from user where name='" + username + "' and password ='" + password + "'";
        System.out.println("sql语句为:" + sql);

1.2 若使用超级用户名登录则造成数据泄露

    public static void main(String[] args) {
        // 测试用例1:正常用户名
        // String username = "张三";
        // 测试用例2:恶意构造的用户名,用于SQL注入攻击
        String username1 = "'or 1=1 or' '='";
        boolean flag = login(username1, "111111111111");
        System.out.println(flag);
    }

输出结果

1.3 非法登录 绕过验证

1.4 先通过用户名验证 再验证密码

          // 如果查询结果有记录,说明用户名存在
            if (resultSet.next()) {
                // 2. 继续验证取出的密码
                String pass = resultSet.getString("password");
                // 3. 继续判断数据库中的密码与用户传入的密码是否匹配
                if (pass != null && pass.equals(password)) {
                    // 密码匹配成功
                    return true;
                } else {
                    // 密码匹配失败
                    return false;
                }
            }

2 预处理

执行sql语句有 Statement PreparedStatement(防注入,特殊字符处理,效率高)

预处理使用占位符,之后再赋值

 // 使用预编译的SQL插入语句
        String sql1 = "insert into user(password,name,phone)" + "values(?,?,?)";
     // 使用预编译的SQL语句
        PreparedStatement ps = null;
        try {
            // 预编译SQL语句
            ps = conn.prepareStatement(sql1);
​
            // 为预编译语句中的占位符赋值
            ps.setString(1, "999999");
            ps.setString(2, "测试ps");
            ps.setString(3, "138457856523");
​
            // 执行预编译的SQL语句并获取影响的行数
            int row = ps.executeUpdate();
            System.out.println("-----" + row);
​

3 加载配置文件

加载配置文件

• 在文件中配置连接属性

import com.yw.utils.ConnectionUtil;
​
import java.sql.Connection;
​
public class test {
    public static void main(String[] args) {
        /**
         * 配置文件读取成功
         */
        Connection conn = ConnectionUtil.getConn();
        System.out.println(conn);
    }
}

• 在连接工具类中使用读取属性文件的方式获取连接参数

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
​
/**
 * 创建连接
 */
public class ConnectionUtil {
    /**
     * io流
     */
    private static String driver;
    private static  String url;
    private static String username;
    private static String password;
​
    static {
        InputStream is = ConnectionUtil.class.getResourceAsStream("/db.properties");
        Properties p = new Properties();
        try {
            p.load(is);
            driver = p.getProperty("driver");
            url = p.getProperty("url");
            username = p.getProperty("username");
            password = p.getProperty("password");
​
          //  password = p.getProperty("password");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
​
    /**
     * 建立连接方法
     * @return
     */
    public static Connection getConn(){
        Connection conn = null;
        try {
            Class.forName(driver);//加载驱动
            conn = DriverManager.getConnection(url,username,password);//给了三个参
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return conn;
    }
​
   public static void close(Connection connection,Statement statement,ResultSet resultSet){
      if(resultSet != null){
          try {
              resultSet.close();
          } catch (SQLException e) {
              throw new RuntimeException(e);
          }
      }
​
      if(statement != null){
          try {
              statement.close();
          } catch (SQLException e) {
              throw new RuntimeException(e);
          }
      }
​
      if(connection != null){
          try {
              connection.close();
          } catch (SQLException e) {
              throw new RuntimeException(e);
          }
      }
​
   }
}

• db.properties 直接使用文本文件进行编辑

username = root
password = root
driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/java_demo1

4 元数据集

import com.sun.xml.internal.ws.addressing.WsaActionUtil;
import com.yw.utils.ConnectionUtil;
​
import java.sql.*;
​
public class test1 {
    public static void main(String[] args) {
        String sql = "select * from user";
        query(sql);
    }
​
    public static void query(String sql){
        Connection conn = ConnectionUtil.getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            /*ResultSetMetaData metaData = rs.getMetaData();//元数据
            int count = metaData.getColumnCount();//获取列数
            System.out.println(count);
            for (int i = 0; i < count; i++) {
                String catalogName = metaData.getColumnName(i+1);
                int columnType = metaData.getColumnType(i + 1);
                System.out.println(catalogName+"==="+columnType);
            }*/
​
            ResultSetMetaData rsd = rs.getMetaData();//获取元数据
            String columnClassName = rsd.getColumnClassName(1);//返回字段类型
            int columnType = rsd.getColumnType(2);
            String columnName = rsd.getColumnName(1);
            String columnName1 = rsd.getColumnName(2);
            System.out.println(columnClassName+"====="+columnType+"=========="+columnName+"========"+columnName1);
​
​
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            ConnectionUtil.close(conn,ps,rs);
        }
    }
​
}

5 封装BaseDao

BaseDao

import com.yw.utils.ConnectionUtil;
​
import java.sql.*;
​
public class BaseDao {
​
    private String username ="root";
    private String password ="123456";
    private String driver ="com.mysql.cj.jdbc.Driver";
    private String url = "jdbc:mysql://localhost:3306/java_demo1";
​
    private Connection connection;//连接
    private PreparedStatement ps;//执行sql语句
    private ResultSet rs;//返回结果集
​
    /**
     * 连接方法
     * @return
     */
    public Connection getConnection(){
        try {
            if(connection == null || connection.isClosed()){ // 或者已经关闭
                Class.forName(driver);//加载驱动
                connection = DriverManager.getConnection(url,username,password);
            }
            return connection;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
​
  /*  public Connection getConnection(){
        try {
            if(connection == null || connection.isClosed()) {
                Class.forName(driver);
                connection = DriverManager.getConnection(url,username,password);
            }
            return connection;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }*/
​
  /*  public int update(String sql,Object ... params){ //sql以参数的形式传入
        connection = getConnection();
        System.out.println(sql);
        try {
            ps = connection.prepareStatement(sql);
            *//*int i = ps.executeUpdate();
            return i;*//*
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1,params[i]);
            }
            int i = ps.executeUpdate();
            return i;
        }catch (Exception e){
            e.printStackTrace();
        }
        return -1;
    }*/
​
    /**
     * 更新方法
     * @param sql
     * @param params 增加 加一  删除 少一个  修改 where id= ? 返回影响行
     * @return
     */
    public int update(String sql,Object...params){
        connection = getConnection();//获得连接
        System.out.println(sql);
        try {
            ps = connection.prepareStatement(sql);//使用预编译 占位符
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1,params[i]);
            }
            int i = ps.executeUpdate();//返回影响行数
            return i;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
​
​
   /* public ResultSet query(String sql,Object... params){
        System.out.println(sql);
        connection = getConnection();//连接
        try {
            ps = connection.prepareStatement(sql);//预编译
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i+1,params[i]);
            }
            rs = ps.executeQuery();
            return rs;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }*/
​
    /**
     *
     * @param sql
     * @param params 查询
     * @return
     */
​
    public ResultSet Query(String sql,Object...params){
        connection = getConnection();
        try {
            ps = connection.prepareStatement(sql);
            for (int i = 1; i < params.length; i++) {
                ps.setObject(i,params[i]);
            }
            rs = ps.executeQuery();
            return rs;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
​
​
    public void close(){
        try {
           if(rs != null){
               rs.close();
               rs = null;
           }
           if(ps != null){
               ps.close();
               ps = null;
           }
           if(connection !=  null){
               connection.close();
               connection = null;
           }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
​
}

TestBase

import java.sql.ResultSet;
import java.sql.SQLException;
​
public class TestBase {
    public static void main(String[] args) throws SQLException {
       /* String sql = "insert into user(password,name,age,phone)values(?,?,?,?)";
        Object[] params = {"654321","basedao",12,"1547895132"};
        BaseDao baseDao = new BaseDao();
        int i = baseDao.update(sql,params);
        */
​
        /**
         * 测试更新方法
         */
       /* String sql = "insert into user(password,name,age,phone)values(?,?,?,?)";
        BaseDao baseDao = new BaseDao();
        Object[] params = {"898989","测试params",15,"189878564"};
        baseDao.update(sql,params);*/
/*
        String sql = "select password,name,phone from user";
        BaseDao baseDao = new BaseDao();
        ResultSet query = baseDao.query(sql);//不能关闭
        try{
            while (query.next()){
                String password = query.getString("password");
                String name = query.getString("name");
                String phone = query.getString("phone");
                System.out.println(password+name+password);
            }
        }catch (Exception e){
            e.printStackTrace();
        }*/
​
        String sql1 = "select password,name, phone from user";
        BaseDao baseDao = new BaseDao();
        ResultSet query = baseDao.Query(sql1);
        while (query.next()){
            String pass = query.getString("password");
            String name = query.getString("name");
            String phone = query.getString("phone");
            System.out.println("pass="+pass+"name="+name+"phone="+phone);
        }
    }
}
​

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

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

相关文章

Stable diffusion3效果比midjourney强很多吗,未来会开源吗?

经过一个多月的期待&#xff0c;Stable Diffusion 3&#xff08;SD3&#xff09; 终于向会员开放了API接口&#xff0c;尽管每个用户的使用配额相对有限&#xff0c;据用户反馈&#xff0c;生成六张图像便可能耗尽配额。 SD曾依靠开源策略与竞争对手抗衡&#xff0c;但目前似…

和鲸科技携手浙江大学地球科学学院,助推地球科学研究范式变革

近日&#xff0c;浙江省资源与环境信息系统重点实验室&#xff08;下简称“实验室&#xff09;与上海和今信息科技有限公司&#xff08;下简称“和鲸科技”&#xff09;签订合作框架协议&#xff0c;双方将以助推“数据算力模型科研场景”的地球科学研究范式变革&#xff0c;孕…

kettle从入门到精通 第六十九课 ETL之kettle kettle cdc mysql,轻松实现增量同步

1、之前kettle cdc mysql的时候使用的方案是canalkafkakettle&#xff0c;今天我们一起学习下使用kettle的插件Debezium直接cdc mysql。 注&#xff1a;CDC (Change Data Capture) 是一种技术&#xff0c;用于捕获和同步数据库中的更改。 1&#xff09;Debezium步骤解析mysql b…

【PyTorch 新手基础】Regularization -- 减轻过拟合 overfitting

Overfit 过拟合&#xff0c;效果如最右图所示 常见应对方案如下&#xff1a; 增大数据集入手&#xff1a;More data or data argumentation简化模型参数入手&#xff1a;Constraint model complexity (shallow model, regularization) or dropout dropout: torch.nn.Dropout(0…

沉睡而且“狡猾”的特工:大模型也可以是!

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

跳舞电动机器人单片机方案

这款机器人形状智能电子玩具是一款集娱乐、教育和互动于一身的高科技产品。它的主要功能包括&#xff1a; 1、智能对话&#xff1a;机器人可以进行简单的对话&#xff0c;回答用户的问题&#xff0c;提供有趣的互动体验。 2、前进、后退、左转、右转、滑行&#xff1a;机器人…

Flink作业执行之 2.算子 StreamOperator

Flink作业执行之 2.算子 StreamOperator 前文介绍了Transformation创建过程&#xff0c;大多数情况下通过UDF完成DataStream转换中&#xff0c;生成的Transformation实例中&#xff0c;核心逻辑是封装了SimpleOperatorFactory实例。 UDF场景下&#xff0c;DataStream到Transf…

分布式高性能计算 (HPC)的工作负载管理平台和作业调度程序—— IBM Spectrum® LSF® Suites

IBM Spectrum LSF Suites 是面向分布式高性能计算 (HPC) 的工作负载管理平台和作业调度程序。基于 Terraform 的自动化现已可用&#xff0c;该功能可在 IBM Cloud 上为基于 IBM Spectrum LSF 的集群供应和配置资源。 借助我们针对任务关键型 HPC 环境的集成解决方案&#xff0…

uni-app利用renderjs实现安卓App上jssip+freeswitch+webrtc音视频通话功能

效果图 前置知识 利用renderjs在app端加载for web库 JsSIPFreeSwitchVue实现WebRtc音视频通话 原始模块 <template><viewclass"test-sip":userExtension"userExtension":change:userExtension"JsSIP.handleUserExtenSionChange":tar…

1+x(Java)中级题库易混淆理论题(五)

Java 语言具有许多优点和特点&#xff0c;多线性反映了 Java 程序并行机制的特点 字符流与字节流的区别在于每次读写的字节数不同 如果需要从文件中读取数据&#xff0c;则可以在程序中创建FileInputStream的对象 void 的含义是方法没有返回值 设 x1&#xff0c;y2&#xf…

SpringBoot集成slf4j日志配置

目录 前言 1、slf4j概述 2、pom.xml的日志依赖 3、application.yml的日志配置 4、logback.xml配置文件定义 5、logback.xml配置文件解析 5.1 定义日志的存储路径 5.2 定义日志的输出格式 5.3 定义控制台输出 5.4 定义日志相关参数 5.5 定义日志的输出级别 6、测试日…

AI大模型时代:一线大厂为何竞相高薪招揽AI产品经理?

前言 在当今日新月异的科技浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;技术已经渗透至各行各业&#xff0c;成为推动社会进步的重要力量。在这样的背景下&#xff0c;AI产品经理这一新兴职位逐渐崭露头角&#xff0c;成为各大企业竞相争夺的稀缺人才。那么&#xf…

​带三维重建和还原的PACS源码 医院PACS系统源码 PACS系统源码医院PACS系统源码 C/S架构 带三维重建和还原​

带三维重建和还原的PACS源码 医院PACS系统源码 PACS系统源码医院PACS系统源码 C/S架构 带三维重建和还原 ​ 主要的任务就是把日常产生的各种医学影像&#xff08;包括核磁&#xff0c;CT&#xff0c;超声&#xff0c;各种X光机&#xff0c;各种红外仪、显微仪等设备产生的图…

cleanmymacX和腾讯柠檬到底哪个好用 2024最新使用测评

CleanMyMac X和腾讯柠檬都是Mac系统清理软件&#xff0c;各有其特点和优势&#xff0c;选择哪个更好用取决于用户的具体需求和使用习惯。 经常有新关注的粉丝问&#xff0c;同样做为垃圾清理软件&#xff0c;付费CleanMyMac和免费的柠檬清理哪个更好用&#xff1f;其实&#xf…

【AI绘画】Stable Diffusion 3开源

Open Release of Stable Diffusion 3 Medium 主要内容 Stable Diffusion 3是Stability AI目前为止最先进的文本转图像开放源代码算法。 这款模型的小巧设计使其完美适合用于消费级PC和笔记本电脑&#xff0c;以及企业级图形处理单元上运行。它已经满足了标准化的文字转图像模…

HTML静态网页成品作业(HTML+CSS)—— 家乡山西介绍网页(3个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有6个页面。 二、作品演示 三、代…

使用Python保护或加密Excel文件的7种方法

目录 安装Python Excel库 Python 使用文档打开密码保护 Excel 文件 Python 使用文档修改密码保护 Excel 文件 Python 将 Excel 文件标记为最终版本 Python 保护 Excel 工作表 Python 在保护 Excel 工作表的同时允许编辑某些单元格 Python 锁定 Excel 工作表中的特定单元…

移植fatfs制作内存文件系统

本文目录 1、引言2、环境准备2.1 下载源码2.2 创建一个工程 3、移植3.1 修改配置3.2 修改diskio.c3.3 编写RAM驱动3.4 编写验证代码 4、验证 文章对应视频教程&#xff1a; 暂无&#xff0c;可以关注我的B站账号等待更新。 点击图片或链接访问我的B站主页~~~ 1、引言 在嵌入式…

GaN VCSEL:工艺革新引领精准波长控制新纪元

日本工程师们凭借精湛的技艺&#xff0c;开创了一种革命性的生产工艺&#xff0c;让VCSEL的制造达到了前所未有的高效与精准。这一成果由名城大学与国家先进工业科学技术研究所的精英们联手铸就&#xff0c;将氮化镓基VCSELs的商业化进程推向了新的高峰。它们将有望成为自适应前…

【Effective Web】常见的css居中方式

CSS居中方式 水平居中 text-align:center 适用范围&#xff1a;容器中都是行内元素 缺点&#xff1a;容器内所有元素都会居中&#xff0c;如果是文本描述需要左对齐&#xff0c;需要增加text-align:left覆盖 margin: 0 auto 适用范围&#xff1a;容器宽度固定。子元素宽度…