JDBC_08_解决SQL注入问题 (登录和注册)
解决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注入问题 (登录和注册)的更多相关文章
- MySQL_(Java)使用preparestatement解决SQL注入的问题
MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC创建用户名和密码校验查询方法 传送门 MySQL数据库中的数据,数据库名garysql,表名gar ...
- jdbc 07: 解决sql注入
jdbc连接mysql,解决sql注入问题 package com.examples.jdbc.o7_解决sql注入; import java.sql.*; import java.util.Hash ...
- IBatis.Net使用总结(一)-- IBatis解决SQL注入(#与$的区别)
IBatis解决SQL注入(#与$的区别) 在IBatis中,我们使用SqlMap进行Sql查询时,需要引用参数,在参数引用中可以使用两种占位符#和$.这两种占位符有什么区别呢? (1):#***#, ...
- 利用SQL注入漏洞登录后台的实现方法
利用SQL注入漏洞登录后台的实现方法 作者: 字体:[增加 减小] 类型:转载 时间:2012-01-12我要评论 工作需要,得好好补习下关于WEB安全方面的相关知识,故撰此文,权当总结,别无它意.读 ...
- PreparedStatement解决sql注入问题
总结 PreparedStatement解决sql注入问题 :sql中使用?做占位符 2.得到PreparedStatement对象 PreparedStatement pst=conn.prepar ...
- 使用过滤器解决SQL注入和跨站点脚本编制
1 SQL注入.盲注 1.1 SQL注入.盲注概述 Web 应用程序通常在后端使用数据库,以与企业数据仓库交互.查询数据库事实上的标准语言是 SQL(各大数据库供应商都有自己的不同版本).Web 应用 ...
- 解决 SQL 注入的另类方法
本文是翻译,版权归原作者所有 原文地址(original source):https://bitcoinrevolt.wordpress.com/2016/03/08/solving-the-prob ...
- MyBatis是如何解决Sql注入的
转:[转]mybatis如何防止sql注入 java中预处理PrepareStatement为什么能起到防止SQL注入的作用??!! 一.SQL注入 sql注入大家都不陌生,是一种常见的攻击方式,攻击 ...
- 防止SQL注入的登录页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/T ...
随机推荐
- DisplayFormat属性
DataFormatString="{0:格式字符串}" 在DataFormatString 中的 {0} 表示数据本身,而在冒号后面的格式字符串代表所们希望数据显示的格式: 数字 ...
- python基础(2)字符串常用方法
python字符串常用方法 find(sub[, start[, end]]) 在索引start和end之间查找字符串sub 找到,则返回最左端的索引值,未找到,则返回-1 start和end都可 ...
- vue之provide和inject跨组件传递属性值失败(父组件向子组件传值的两种方式)
简单介绍:当一个子组件需要用到父组件的父组件的某些参数.那么这个时候为了避免组件重复传参,使用vue的依赖注入是个不错的方法,直接在最外层组件设置一个provide,内部不管多少嵌套都可以直接取到最外 ...
- Redis集群简介及部署
1简介 在 Redis 3.0 之前,使用 哨兵(sentinel)机制来监控各个节点之间的状态.Redis Cluster 是 Redis 的 分布式解决方案,在 3.0 版本正式推出,有效地解决了 ...
- Java基础语法:JavaDoc
一.简介 JavaDoc是一种将注释生成HTML文档的技术,它从程序源代码中抽取类.方法.成员等注释形成一个和源代码配套的API帮助文档. 也就是说,只要在编写程序时以一套特定的标签作注释,在程序编写 ...
- WPF -- 一种实现本地化的方法
本文介绍一种WPF程序实现本地化的方法. 步骤 首先,假设xaml文件中存在一个Button按钮,内容为"按钮",实现本地化的步骤如下: 展开程序的Properties,双击Res ...
- PVE连接Wi-Fi
连接wifi参考文章: https://lzxz1234.cn/archives/417 services看不全信息 connmanctl> services 之后信息太多,看不到上面的怎么办? ...
- C语言中字符串详解
C语言中字符串详解 字符串时是C语言中非常重要的部分,我们从字符串的性质和字符串的创建.程序中字符串的输入输出和字符串的操作来对字符串进行详细的解析. 什么是字符串? C语言本身没有内置的字符串类型, ...
- Java 语言基础 01
语言基础·一级 什么是计算机? 计算机(Computer)全称:电子计算机,俗称电脑.是一种能够按照程序运行,自动.高速处理海量数据的现代化智能电子设备.由硬件和软件所组成,没有安装任何软件的计算机称 ...
- 聊一聊和Nacos 2.0.0对接那些事
前言 nacos 2.0.0 已经发布了 alpha1, alpha2 和 beta 三个版本了,部分测试报告也已经出来了. Nacos2.0.0-ALPHA2 服务发现性能测试报告 Nacos 2. ...