第二阶段:反射的概念和介绍、jdbc介绍及注入式攻击

1、反射的概念
1、反射的应用场景
在框架中或者是应用中,往往会遇到如下的场景,就是知道一个类的字符串全名,从而能够构建这个字符串全名对
于的类对象,进而去执行操作。还要比如在框架中,我们要构建一个对象,这个对象一般不是用户去创建的,而是
由框架本身去创建,进而提供给用户使用。比如spring框架的配置,经常要创建很多的Bean对象。它就需要用到
反射。
**2、往往需要在程序运行的过程中,通过类的全名字符串去创建对象,进而去使用它的构造方法、成员变量、成员
方法。我们可以通过操作类的反射对象、属性、方法、构造方法的反射对象,从而达到对类的操作。
3、什么是反射?
任何对象在运行时都在内层中由一个对象,这个对象就是所谓的反射对象,它的类型是Class.
2、反射的API介绍
1)如何获得类对于的反射对象Class?
a)Class.forName(“类的全名字符串”); 比如 Class c=Class.forName(“com.kgc.User”);
b)类名.class(用的少),比如 Class c=User.class
c)对象名.getClass(),比如 User u=new User(); Class c=u.getClass(
2) 如何获得构造方法、属性、成员方法对应的反射对象?
getConstructor(Class<?>…
parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的
指定公共构造方法。
getDeclaredConstructor(Class<?>…
parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的
类或接口的指定构造方法。
getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指
定公共成员字段。
getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口
的指定已声明字段。
getMethod(String name, Class<?>…
parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口
的指定公共成员方法
getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口
的指定已声明字段。
3)如何通过Field属性对应的反射对象操作属性?
Xxx getXxx(Object obj) 获取基本类型的属性值
Object get(Object obj) ) 得到引用类型属性值
void setXxx(Object obj,Xxx val) 将obj对象的该属性设置成val值
void set(Object obj,object val) 将obj对象的该属性设置成val值
void setAccessible(bool flag) 对获取到的属性设置访问权限
4)如何通过方法的反射对象Method去操作对象的方法?
Method setName = clz1.getMethod(“setName”, String.clas
3、演示操作
1)构建一个User类
public class User {
private Integer id;
private String name;
private Integer age;
public User() {
}
public User(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void info(){
System.out.println(“用户的信息是:”);
System.out.println(getId()+" “+getName()+” “+getAge());
}
}
2)构建User的反射对象
2)构建User的反射对象
public static void test1(){
try {
//1、通过全名构建
Class<?> clz1 = Class.forName(“com.kgc.entity.User”);
//2、通过类名.class
Class clz2 = User.class;
//3、通过对象来构建
User user=new User();
Class<? extends User> clz3 = user.getClass();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
2)获得构造方法的反射对象?
public static void test2() {
try {
//1、通过全名构建
Class<?> clz1 = Class.forName(“com.kgc.entity.User”);
//2、构建构造方法的反射对象,获得的是无参的构造反射对象
Constructor<?> constructor = clz1.getDeclaredConstructor();
Constructor<?> constructor1 = clz1.getDeclaredConstructor(Integer.class,
String.class, Integer.class);
} catch (Exception e) {
e.printStackTrace();
}
}
3)通过反射对象获得类的实例对象?
public static void test2() {
try {
//1、通过全名构建
Class<?> clz1 = Class.forName(“com.kgc.entity.User”);
//2、构建构造方法的反射对象,获得的是无参的构造反射对象
Constructor<?> constructor = clz1.getDeclaredConstructor();
Constructor<?> constructor1 = clz1.getDeclaredConstructor(Integer.class,
String.class, Integer.class);
//Object 实际是User对应的实例对象 User obj_user=new User();
User u2 = (User) clz1.newInstance();
//通过clz1,构建实例对象,相等于通过User obj=new User(1,”",12);
User u = (User) constructor1.newInstance(1, “张三”, 12);
u.info();
User u1 = (User) constructor.newInstance();
System.out.println("===");
u1.info();
System.out.println("
=");
u2.info();
} catch (Exception e) {
e.printStackTrace();
}
}
说明:对应类的实例对象,要获得空参构造方法对应的实例对象,可以有两种方式,分别是
a)空参构造方法的反射对象去创建:User u1 = (User) constructor.newInstance();
b) 类的反射对象去创建:User u2 = (User) clz1.newInstance();
对应获得有参的实例对象,只能公共有参构造的反射对象去创建,比如 User u = (User)
constructor1.newInstance(1, “张三”, 12);这里的constructor1必须是构造方法的反射对象,而且是带参数的。
4)获得属性对应的反射对象,并操纵该对象对原始属性进行读写操作?
public static void test3() {
try {
//1、通过全名构建
Class<?> clz1 = Class.forName(“com.kgc.entity.User”);
//2、构建空参对象
Object obj = clz1.newInstance();
//3、获得id属性对应的反射对象
Field id = clz1.getDeclaredField(“id”);
id.setAccessible(true);
//4、设置id的属性值
id.set(obj,12);
//5、获得id的属性值
Object oid = id.get(obj);
Field name = clz1.getDeclaredField(“name”);
//设置操作权限
name.setAccessible(true);
//设置属性值
name.set(obj,“小红”);
//获得属性值
Object oname = name.get(obj);
//输出验证
System.out.println(oname);
System.out.println(oid);
} catch (Exception e) {
e.printStackTrace();
}
}
4)操作方法的反射对象,对原始的方法进行操作?
4、jdbc的概念
1、什么是JDBC?
它是Java语言操作数据库的技术,通过java代码发送sql语言到数据库,并执行语句。
2、什么是jdbc驱动?为什么每种数据库在发布后都会发布对应的驱动程序?
jdbc驱动实际上可以理解成操作某种数据库的java工具包。sun公司对操作数据库写了一组接口代码。数据库厂商
要生存下去,必须要有用户用。那么数据库厂商就必须遵循sun的规范去实现接口(写接口的实现类),我们编码
的时候使用接口就行了。至于用的是哪个数据库,我们不需要理睬。
3、JDBC的API
1)DriverManager:是驱动管理器
2)Connection对象:用来连接数据库
3)PreparedStatement对象和Statement对象:是用来发送sql语句执行对象。
4) 查询:ResultSet对象,结果集对象,对于查询的结果需要通过该对象获取。
4、使用步骤
1)构建驱动包到项目
2)构建利用DriverManager.getConnection(url,user,password)构建Connection对象
3) 利用Connection.createStatement()创建命令对象Statement对象
或者PreparedStatement pstmt = connection.prepareStatement(sql);
4)查询获得结果集
statement.executeQuery(sql)或者pstmt.executeQuery();
5)获得字段的值
6)反向关闭
import java.sql.*;
public class DeptDaoImpl {
public static void main(String[] args) {
DeptDaoImpl deptDao=new DeptDaoImpl();
deptDao.getDeptByDeptNo(20);
}
/

  • 功能:根据部门编号查询该部门的信息
  • @param deptNo
    /
    public void getDeptByDeptNo(Integer deptNo){
    Connection connection =null;
    Statement statement =null;
    ResultSet rs=null;
    try {
    //1、加载驱动
    Class.forName(“com.mysql.jdbc.Driver”);
    //2、创建连接对象
    connection = DriverManager
    .getConnection(“jdbc:mysql://localhost:3306/k9506”,
    “root”, “1234”);
    //3、命令执行对象
    statement = connection.createStatement();
    //4、结果集对象
    String sql=“select * from dept where deptno=”+deptNo;
    rs = statement.executeQuery(sql);
    //5、获得每条记录的每个字段的值
    if(rs.next()){
    int deptno = rs.getInt(“deptno”);
    String dname = rs.getString(“dname”);
    String loc = rs.getString(“loc”);
    //6、验证是否正确
    System.out.println(deptno+" “+dname+” "+loc);
    }
    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    try {
    if(null!=rs){
    rs.close();
    }
    if(null!=statement){
    statement.close();
    }
    if(null!=connection){
    connection.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }
    5、jdbc注入式攻击
    public class UserDaoImpl {
    public static void main(String[] args) {
    UserDaoImpl userDao=new UserDaoImpl();
    String loginName=“admin”;
    // PASSWORD=‘abc’ OR ‘1=1’
    String password=“abc’ or '1=1”;
    boolean login = userDao.login(loginName, password);
    if(login){
    System.out.println(“登录成功”);
    }else{
    System.out.println(“登录失败”);
    }
    }
    /
    *
  • 演示注入式攻击
  • @param loginName
  • @param password
  • @return
    */
    public boolean login (String loginName,String password){
    boolean isLogin=false;
    Connection connection =null;
    Statement statement =null;
    ResultSet rs=null;
    try {
    //1、加载驱动
    Class.forName(“com.mysql.jdbc.Driver”);
    //2、创建连接对象
    connection = DriverManager
    .getConnection(“jdbc:mysql://localhost:3306/k9506”,
    “root”, “1234”);
    //3、命令执行对象
    statement = connection.createStatement();
    //4、结果集对象
    String sql=“SELECT * from user WHERE loginName=’”+loginName+"’ and
    password=’"+password+"’";
    System.out.println(sql);
    rs = statement.executeQuery(sql);
    //5、获得每条记录的每个字段的值
    isLogin=rs.next();
    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    try {
    if(null!=rs){
    rs.close();
    }
    if(null!=statement){
    statement.close();
    }
    if(null!=connection){
    connection.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    return isLogin;
    }
  • 演示注入式攻击
  • @param loginName
  • @param password
  • @return
    */
    public boolean login1 (String loginName,String password){
    boolean isLogin=false;
    Connection connection =null;
    PreparedStatement pstmt=null;
    ResultSet rs=null;
    try {
    //1、加载驱动
    Class.forName(“com.mysql.jdbc.Driver”);
    //2、创建连接对象
    connection = DriverManager
    .getConnection(“jdbc:mysql://localhost:3306/k9506”,
    “root”, “1234”);
    String sql=“SELECT * from user WHERE loginName=? and password=?”;
    //3、命令执行对象
    pstmt = connection.prepareStatement(sql);
    //4、结果集对象
    pstmt.setString(1,loginName);
    pstmt.setString(2,password);
    System.out.println(sql);
    rs = pstmt.executeQuery();
    //5、获得每条记录的每个字段的值
    isLogin=rs.next();
    } catch (Exception e) {
    e.printStackTrace();
    }finally {
    try {
    if(null!=rs){
    rs.close();
    }
    if(null!=pstmt){
    pstmt.close();
    }
    if(null!=connection){
    connection.close();
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    return isLogin;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值