PreparedStatement对象解决SQL注入问题----个人学习记录

1.SQL注入的概念

SQL注入是指用户输入的条件中含有SQL的关键字,并且参与了SQL语句执行,改变了SQL语句的执行结果,叫SQL注入。SQL注入坏处:他人可以通过SQL注入盗取信息等等。

在tt_user表中查询userna为 'zs' 的用户,输入语句

SELECT * FROM tt_user WHERE username = 'zs AND password = 'z1234'就行了;

但是在我们在后面添加一个 OR 1 = 1时,就能把我们表里的数据都查询出来。

这是因为不论前面的条件是否成立而 OR 后面的 1 = 1 绝对会成立,最终条件是成立的所以就能查询到我们表里的全部数据。


2.SQL注入的解决方案

预编译:

预编译就是我们先将SQL语句预先处理,处理了以后,用户只能输入条件,而且输入的这个条件不能改变SQL语句的执行结果。

预编译的好处:

1.可以有效防止SQL注入;

2.安全且效率高;

3.可以动态填充数据。


3.登录示例理解  PreparedStatement 

PreparedStatement概述:

PreparedStatement 继承了 Statement 类,可以有效的防止SQL注入。

登录示例:

需求:1.写一个登录界面,有账号、密码,账号和密码取数据库表中的username和password;

           2.写一个登录成功的界面,内容随意;

           3.利用PreparedStatement 对象,验证登录密码是否正确,且登录成功后跳转登录成功界                面

第一步,先写登录界面login.jsp,eclipse新建jsp文件,这里注意了action里要写请求 Servlet 的名

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>登录页面</title>
</head>
<body>
<!-- action写要请求 Servlet 的名 -->
<form action="leleServlet" method="post">
    用户名:<input type="text" name="uname"><br><br>
    密码:<input type="password" name="pwd"><br><br>
    <input type="submit" value="登录">
    <input type="reset" value="重置">
</form>
</body>
</html>

第二步,再把登录成功界面hello.jsp搞出来,这个也很简单,就是一个jsp界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>登录成功页面</title>
</head>
<body>

登录成功!<br>
<a href="链接">返回登录页面</a>
</body>
</html>

第三步---编写Java代码

(1)新建一个带doget方法的servlet类

 

 (2)PreparedStatement 代码:

具体由以下几步:

1.先加载驱动 

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

报错不要慌,鼠标放在 forName 上点击 surround with try/catch 即可 我们接下来的代码写在 try 

2.获取数据库的链接和获取前面jsp传输过来的数据

//			2.获取数据库链接
			String url = "jdbc:mysql://localhost:3306/数据库名称?useSSL=false";
			String username = "用户名";
			String password = "密码";
			Connection connt =DriverManager.getConnection(url,username,password);
//			获取通过HTTP协议传输过来的数据
			String name = request.getParameter("uname");
			String pwd = request.getParameter("pwd");

3.定义SQL语句,注意SQL语句中的参数值,使用 ?占位符替代并获取 PreparedStatement 对象

//			定义SQL语句
//			SQL语句中的参数值,使用 ?占位符替代
			String sql = "SELECT username,password FROM tt_user WHERE username=? AND password=?";
//			获取 PreparedStatement 对象
			PreparedStatement pstmt = conn.prepareStatement(sql);

4.执行SQL,并根据用户输入的数据判断

//			执行SQL
			ResultSet resultSet=pstmt.executeQuery(sql);
//			判断
			if (resultSet.next()) {
				request.getRequestDispatcher("hello.jsp").forward(request, response);
			} else {
				request.getRequestDispatcher("login.jsp").forward(request, response);
			}

5.最后释放资源就行了,但是try里是局部变量,我们无法释放资源,所以我们把一些变量对的定义放在try外面即可。

		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet resultSet = null

完整代码如下:

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

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


@WebServlet("/leleServlet")
public class leleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public leleServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet resultSet = null;
		try {
//			注册MySQL驱动
			Class.forName("com.mysql.jdbc.Driver");
//			获取链接
			String url = "jdbc:mysql://localhost:3306/数据库名称?useSSL=false";
			String username = "用户名";
			String password = "密码";
			conn = DriverManager.getConnection(url, username, password);
//			获取通过HTTP协议传输过来的数据
			String name = request.getParameter("uname");
			String pwd = request.getParameter("pwd");
//			定义SQL语句
//			SQL语句中的参数值,使用 ?占位符替代
			String sql = "SELECT username,password FROM tt_user WHERE username=? AND password=?";
//			获取 PreparedStatement 对象
			pstmt = conn.prepareStatement(sql);
//			设置 ? 的值
			pstmt.setString(1, name);
			pstmt.setString(2, pwd);
//			执行SQL
			resultSet = pstmt.executeQuery();
			if (resultSet.next()) {
				request.getRequestDispatcher("hello.jsp").forward(request, response);
				System.out.println("yes");
			} else {
				request.getRequestDispatcher("login.jsp").forward(request, response);
				System.out.println("no");;
			}
		} 
//		捕捉异常,打印异常
		catch (Exception e) {
			e.printStackTrace();
		}
	}

}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值