解决SQL注入问题

  • 只要用户提供的信息不参与sql语句的编译过程,那么尽管用户输入的信息中含有sql关键字那么也不会起作用了

  • 要想使用户提供信息不参与sql语句的编译过程,那么必须使用 java.sql.PreparedStatement 预编译的数据库操作对象,提前编译sql语句框架

  • PreparedStatement 继承了 Statement

  • PreparedStatement的原理是预先对sql语句框架进行编译,然后再给sql语句传值。

  • 将Statement(数据库操作对象) 换为 PreparedStatement(预编译的数据库操作对象)

  • 获取预编译数据库连接对象preparedStatement,将sql语句框架预先进行编译。 其中SQL语句中的 一个 ?表示一个占位符,占位符不能用单引号括起来。

    • preparedStatement=connection.prepareStatement("select * from t_user where loginName=? and loginPwd=? "); 使用 ?进行占位。
  • 给占位符 ? 传值 注意:第一个问号的下标是1 ,第二个问号下标是 2

      - preparedStatement.setString(1,loginName);   第一个问号传   loginName
    
      - preparedStatement.setString(2,loginPwd);    第二个问号传   loginPwd
  • 代码实例:

           
    
         import java.sql.*;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Scanner; /**
    * 解决sql注入问题
    * 只要用户提供的信息不参与sql语句的编译过程,那么尽管用户输入的信息中含有sql关键字那么也不会起作用了
    * 要想使用户提供信息不参与sql语句的编译过程,那么必须使用java.sql. PreparedStatement 预编译的数据库操作对象
    * PreparedStatement 继承了 Statement
    * PreparedStatement的原理是预先对sql语句框架进行编译,然后再给sql语句传值
    * 将Statement(数据库操作对象) 换为 PreparedStatement(预编译的数据库操作对象)
    *
    *
    */ public class 解决sql注入 {
    public static void main(String[] args) throws SQLException { //掉用initUI()获取用户名密码
    Map<String,String> userLoginInfo=initUI(); //调用register()方法。
    //boolean registerSuccess=register(userLoginInfo); //输出结果
    //System.out.println(registerSuccess?"注册成功":"注册失败"); //调用logIn()方法。
    boolean loginSuccess=login(userLoginInfo);
    System.out.println(loginSuccess?"登陆成功":"密码错误"); } /**
    * 用户注册
    * @param userLoginInfo 用户登录信息
    * @return true成功, false失败
    */ private static boolean register(Map<String, String> userLoginInfo) {
    //创建连接对象
    Connection connection=null;
    Statement statement=null;
    int count=0; try {
    //注册驱动
    Class.forName("com.mysql.cj.jdbc.Driver"); //获取连接
    connection= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai",
    "root","123456"); //获取数据库操作对象
    statement=connection.createStatement(); //执行SQL语句
    count=statement.executeUpdate("insert into t_user(loginName,loginPwd,realName)values('"+userLoginInfo.get("loginName")+"','"+userLoginInfo.get("loginPwd")+"',' ') "); } catch (ClassNotFoundException | SQLException e) {
    e.printStackTrace();
    }finally {
    if(statement!=null){
    try {
    statement.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    } if(connection!=null){
    try {
    connection.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }
    if(count==1){
    return true;
    }
    return false;
    } /**
    * 用户登录
    * @param userLoginInfo 用户信息
    * @return 成功true 失败fslse
    */ private static boolean login(Map<String, String> userLoginInfo) throws SQLException { //标识
    boolean flag=false; //获取用户信息
    String loginName=userLoginInfo.get("loginName");
    String loginPwd=userLoginInfo.get("loginPwd"); //创建连接对象
    Connection connection=null;
    PreparedStatement preparedStatement=null; //这里使用PreparedStatement(预编译的数据库操作对象)
    ResultSet resultSet=null; try {
    //注册驱动
    Class.forName("com.mysql.cj.jdbc.Driver"); //获取连接
    connection=DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai",
    "root","123456"); //获取预编译数据库连接对象,将sql语句框架预先进行编译。其中一个?表示一个占位符,占位符不能用单引号括起来
    preparedStatement=connection.prepareStatement("select * from t_user where loginName=? and loginPwd=?"); //使用?进行占位 //给占位符? 传值 注意:第一个问号的下标是1 ,第二个问号下标是 2
    preparedStatement.setString(1,loginName); //第一个问号传 loginName
    preparedStatement.setString(2,loginPwd); //第二个问号传 loginPwd //执行SQL语句 使用 PreparedStatement,执行sql的使用,不用再传入sql语句,因为前面已经编译过了。
    resultSet=preparedStatement.executeQuery(); //处理查询结果集
    if(resultSet.next()){
    flag=true;
    }
    } catch (ClassNotFoundException | SQLException e) {
    e.printStackTrace();
    }finally {
    if(resultSet!=null){
    resultSet.close();
    }
    if(preparedStatement!=null){
    preparedStatement.close();
    }
    if (connection!=null){
    connection.close();
    }
    } return flag;
    } /**
    * 初始化用户界面
    * @return 返回用户登录信息
    */
    private static Map<String, String> initUI() { //创建用户信息接收对象
    Scanner scanner=new Scanner(System.in);
    System.out.println("请输入您的用户名:");
    String userName=scanner.nextLine(); System.out.println("请输入您的密码:");
    String pwd=scanner.nextLine(); //创建一个Map集合用来存放用户输入得用户名和密码
    Map<String,String> userLoginInfo=new HashMap<String,String>();
    userLoginInfo.put("loginName",userName);
    userLoginInfo.put("loginPwd",pwd);
    return userLoginInfo;
    }
    }

JDBC_08_解决SQL注入问题 (登录和注册)的更多相关文章

  1. MySQL_(Java)使用preparestatement解决SQL注入的问题

    MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC创建用户名和密码校验查询方法 传送门 MySQL数据库中的数据,数据库名garysql,表名gar ...

  2. jdbc 07: 解决sql注入

    jdbc连接mysql,解决sql注入问题 package com.examples.jdbc.o7_解决sql注入; import java.sql.*; import java.util.Hash ...

  3. IBatis.Net使用总结(一)-- IBatis解决SQL注入(#与$的区别)

    IBatis解决SQL注入(#与$的区别) 在IBatis中,我们使用SqlMap进行Sql查询时,需要引用参数,在参数引用中可以使用两种占位符#和$.这两种占位符有什么区别呢? (1):#***#, ...

  4. 利用SQL注入漏洞登录后台的实现方法

    利用SQL注入漏洞登录后台的实现方法 作者: 字体:[增加 减小] 类型:转载 时间:2012-01-12我要评论 工作需要,得好好补习下关于WEB安全方面的相关知识,故撰此文,权当总结,别无它意.读 ...

  5. PreparedStatement解决sql注入问题

    总结 PreparedStatement解决sql注入问题 :sql中使用?做占位符 2.得到PreparedStatement对象 PreparedStatement pst=conn.prepar ...

  6. 使用过滤器解决SQL注入和跨站点脚本编制

    1 SQL注入.盲注 1.1 SQL注入.盲注概述 Web 应用程序通常在后端使用数据库,以与企业数据仓库交互.查询数据库事实上的标准语言是 SQL(各大数据库供应商都有自己的不同版本).Web 应用 ...

  7. 解决 SQL 注入的另类方法

    本文是翻译,版权归原作者所有 原文地址(original source):https://bitcoinrevolt.wordpress.com/2016/03/08/solving-the-prob ...

  8. MyBatis是如何解决Sql注入的

    转:[转]mybatis如何防止sql注入 java中预处理PrepareStatement为什么能起到防止SQL注入的作用??!! 一.SQL注入 sql注入大家都不陌生,是一种常见的攻击方式,攻击 ...

  9. 防止SQL注入的登录页面

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/T ...

随机推荐

  1. linux 安装node和pm2

    用yum安装 curl -sL https://rpm.nodesource.com/setup_10.x | bash - yum install -y nodejs npm install -g ...

  2. 【Notes_2】现代图形学入门——向量与线性代数

    向量与线性代数 点乘和叉乘 Dot Multiplication 点乘在图形学的应用 (1) 求两个向量之间的夹角: $$\cos(\theta) = \frac{(\vec{a} \cdot \ve ...

  3. 微信小程序滚动条设置

    隐藏滚动条 ::-webkit-scrollbar { width: 0rpx; height: 0rpx; background-color: transparent; } 其实设置为宽高为 0 或 ...

  4. XXL-JOB v2.3.0 发布 | 易用性增强

    转: XXL-JOB v2.3.0 发布 | 易用性增强 v2.3.0 Release Notes 1.[新增]调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略.立即补偿触发一次等: 2. ...

  5. python带颜色打印字符串

    python带颜色打印字符串 之前调试pwn题的时候,有时候需要将某些特别的,重要的信息用不一样的颜色打印出来.查阅一些资料,了解了print函数的特性后,自己写了一个脚本,可以用来获取带颜色信息的字 ...

  6. rest-framework routers

    路由器 资源路由可以让你快速声明所有给定的足智多谋的控制器的共同路线.相反,宣布独立的路线索引的......一个足智多谋的路线宣称他们在一个单一的代码行. - Ruby on Rails的文档 一些W ...

  7. MIMO OFDM 常用信号检测算法

    MIMO OFDM 系统检测算法 1. 前言 MIMO的空分复用技术可以使得系统在系统带宽和发射带宽不变的情况下容易地获得空间分集增益和信道的容量增益.OFDM技术采用多个正交的子载波并行传输数据,使 ...

  8. java网络通信不止UDP,TCP

    预备知识 多线程 实现多线程 线程池 IO流 核心功能就是读和写 扩展功能对什么读写,怎么读写,如何优化读写 网络基础 IP IP规定网络上所有的设备都必须有一个独一无二的IP地址,就好比是邮件上都必 ...

  9. 2019HDU多校第七场 HDU6651 Final Exam

    一.题目 Final Exam 二.分析 题目说的比较绕,总之一定要记住,$n$个题目都可以做,至少作对$k$到,但是做题目的人不知道每道题对应的分数. 作为出题人,如果他是田忌,肯定不会去在做题目的 ...

  10. python-类的隐藏和封装

    7 """ 8 封装是面对对象的三大特征之一(另外两个是集成和多态),它指的是将对象> 的信息隐藏在对象的内部,不允许外部程序直接访问对象内部信息,而是通> ...