1、JAVA反射

获取类对象的三种方式
Class.forName
ClassPersion.class
persion p =new persion() p.getclass

  1. 方式一:
  2. Class cls1 = Class.forName("Domain.Person");
  3. System.out.println(cls1);
  4. 方式二:
  5. Class cls2 = Person.class;
  6. System.out.println(cls2);
  7. 方式三:
  8. Person p = new Person();
  9. Class cls3 = p.getClass();
  10. System.out.println(cls3);
  11. 三者返回都一样 返回的位一个class对象====》class xx.Domain.Persion

获取成员方法
getMethod (String name方法名,Class类名) 获取类里的指定的成员方法,必须为Public修饰
getDeclaredMethods() 获取类里的所有成员方法,返回的是一个数组
getDeclaredMethod (String name方法名,Class类名) 获取类里的指定的成员方法

getMethod第一个参数是方法名,第二个参数是该方法的参数类型

获取成员变量
getFields 获取类里所有的Public成员变量,返回的是一个数组
getField(”String name”) 获取指定的Public成员变量
getDeclaredFields 获取类里所有的成员变量,不考虑修饰符
getDeclaredField 获取指定的成员变量,不考虑修饰符

获取构造方法
getConstructor 获取构造方法,必须为Public修饰
getDeclaredConstructor
getDeclaredConstructors

获取全类名
String getName() 返回一个字符串,为xx.123.Persion.

意思是调用object类里的method的方法,并给这个方法传了一个值,这个值不是固定的,看方法的调用
method.invoke(object,command)
exec.invoke(o,”ipconfig”)
method.invoke的第一个参数必须是类实例对象,如果调用的是static方法那么第一个参数值可以传null,因为在java中调用静态方法是不需要有类实例的,因为可以直接类名.方法名(参数)的方式调用

2、El表达式

是啥?
作用:EL表达式主要用来在JSP页面中用来获取数据的一种方式
使用语法:${EL表达式}
EL表达式和JSP代码等价转换。事实上,可以将EL表达式理解为一种简化的JSP代码。

pageContext对象
${pageContext.request.queryString}
image.png

param对象
如果jsp页面存在username=request.getParameter方法来接受参数,那么此时我们就可以使用
${param[“username”]}来接受这个参数,返回给客户端
http://127.0.0.1/?username=ice
那么此时页面返回为ice这个字符串
image.png

header对象
${header[“user-agent”]}
image.png

调用JAVA方法
step1、
创建一个类,类中定义方法dosomething返回一个字符串

  1. package eltest;
  2. public class ELFunc {
  3. public static String doSomething(String str){
  4. return str + ".com";
  5. }
  6. }

step2、
在WEB-INF文件夹下(除lib和classess目录外新建一个test.tld,配置URL与指定方法dosometing

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd">
  5. <tlib-version>1.0</tlib-version>
  6. <short-name>ELFuncxxxxxxx</short-name>
  7. <uri>http://www.mi1k7ea.com/ELFunc</uri>
  8. <function>
  9. <name>doSomething</name>
  10. <function-class>eltest.ELFunc</function-class>
  11. <function-signature>java.lang.String doSomething(java.lang.String)</function-signature>
  12. </function>
  13. </taglib>

step3、导入taglib标签库,URI为test.tld中设置的URI地址,prefix为test.tld中设置的short-name

  1. <%@taglib uri="http://www.mi1k7ea.com/ELFunc" prefix="ELFuncxxxxxxx"%>
  2. ${ELFunc:doSomething("mi1k7ea")}
  1. <br />step4、此时页面返回mi1k7ea.com

禁用EL表达式
1、Web.xml配置

  1. <jsp-config>
  2. <jsp-property-group>
  3. <url-pattern>*.jsp</url-pattern>
  4. <el-ignored>true</el-ignored>
  5. </jsp-property-group>
  6. </jsp-config>
  1. 2、在JSP页面里写上<br />**<%@** page isELIgnored**=**"true" **%>**

EL表达式注入
EL表达式注入漏洞和SpEL、OGNL等表达式注入漏洞是一样的漏洞原理的
即表达式外部可控导致攻击者注入恶意表达式实现任意代码执行。

calc.jsp 弹出计算器

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4. <title>ELSTES</title>
  5. </head>
  6. <body>
  7. ${pageContext.setAttribute("a","".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"calc.exe"))}
  8. </body>
  9. </html>
  10. //Runtime.getRuntime().exec("command")

${pageContext.getSession().getServletContext().getClassLoader().getResource(“”)} 查询绝对路径

目前实际场景的EL表达式注入都是在服务端接受参数,外部传参时使用EL表达式渲染导致JAVA代码执行
https://www.cnblogs.com/junsec/p/11132652.html

可能现在遇到得多的场景是SpEL
SpEL 主要是 bean 的属性进行动态赋值:主要是注入基本数据类型和String

3、jackson使用

readValue(jason字符串数据,class) 将json转为java对象
writeValueAsString(obj、list集合) 将java对象转为json字符串
writeValue(File,obj) File: 将object对象转为JSON字符串,并保存在文件中
writeValue(Writer,obj) Write:将object对象转为JSON字符串,并将json数据填充到字符输出流
writeValue(OutputStream,obj) OutputStream:将object对象转为JSON字符串,并将JSON数据填充到字节输出流

4、Mybatis

1)创建maven工程导入坐标,依赖的东西比较多

  1. <packaging>jar</packaging>
  2. <dependencies>
  3. <dependency>
  4. <groupId>org.mybatis</groupId>
  5. <artifactId>mybatis</artifactId>
  6. <version>3.4.5</version>
  7. </dependency>
  8. <dependency>
  9. <groupId>mysql</groupId>
  10. <artifactId>mysql-connector-java</artifactId>
  11. <version>5.1.6</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>junit</groupId>
  15. <artifactId>junit</artifactId>
  16. <version>4.10</version>
  17. </dependency>
  18. </dependencies>

2) 编写一个实体类,实体类主要用来定义基本属性
image.png
编写一个DAO接口

  1. public interface studentDao{
  2. public List<UserStudent> selectUsers();
  3. //这个selectUser对应是的一个SQL语句的执行,可以看到方法的第二个单词为返回类型,返回类型为List,内部存储的是为User类型的对象
  4. }

3)编写studentDao.xml文件(sql映射文件)
这个Xml文件的作用是为了找到DAO接口,mybatis解析它之后,会默认执行里面的sql语句,然后通过resultType返回,这个返回类型一般我们定义和接口里执行数据方法(selectUsers)的返回类型一致

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.test.dao.studentDao">//
  6. <select id="selectUsers" resultType="com.test.domain.UserStudent">
  7. select * from user where id=#{id}
  8. </select>
  9. </mapper>

4)开始配置SqlMapConfig.xml,可以将该文件配置在resource文件夹中,一般我们在里面配置数据库的配置,例如连接账户密码等
想看在cms框架中是否使用mybatis的话,可以尝试搜索”http://mybatis.org/dtd/mybatis-3-config.dtd“ 字符串
“Resources.getResourceAsStream”

SqlMapConfig.xml主要配置内容有:
配置mysql的环境:

  1. 1. 配置事务的类型;
  2. 1. 配置连接池:配置连接数据库的4个基本信息,账户密码、IP和驱动
  1. <dataSource type="POOLED">
  2. <!--配置连接数据库的4个基本信息-->
  3. <property name="driver" value="com.mysql.jdbc.Driver"/>
  4. <property name="url" value="jdbc:mysql://192.168.214.128:3306/mybatis"/>
  5. <property name="username" value="root"/>
  6. <property name="password" value="root"/>
  7. </dataSource>

以及mapper——sql映射文件的位置配置写在SqlMapConfig.xml的最下面,Mybatis通过它来识别到真正的sql映射文件,才能执行SQL语句

  1. <mappers>
  2. <mapper resource="com/test/dao/Userdao.xml">
  3. <mapper resource="com/test/dao/Persiondao.xml">
  4. <mapper resource="com/test/dao/Studentdao.xml">
  5. //写了多少个查询,就加多少个配置文件
  6. </mappers>

5、编写测试类(main方法)

  1. public class mybatistest {
  2. public static void main(String[] args)throws Exception {
  3. //1.读取配置文件
  4. InputStream in = Resources.getResourceAsStream("mapconfig.xml");
  5. //2.创建SqlSessionFactory工厂
  6. SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  7. SqlSessionFactory factory = builder.build(in);
  8. //3.使用工厂生产SqlSession对象
  9. SqlSession session = factory.openSession();
  10. //4.使用SqlSession创建Dao接口的代理对象
  11. s);
  12. //5.使用代理对象执行方法
  13. List<UserStudent> users = studentDao.selectUsers();
  14. //6 不断的获取获取返回的user数据
  15. for(User user : users){
  16. System.out.println(user.toString());
  17. }
  18. //7.释放资源
  19. session.close();
  20. in.close();
  21. }
  22. }

2、注解配置Mybatis
上述的例子是使用xml配置Mybatis,但是我们可以想象到会有大量的写着查询语句的xml文件在项目中,虽然十分清晰,但是还是比较繁杂和冗余,因此我们可以使用注解配置Mybatis

只需要在接口类处添加select注解即可 ,这样我们就可以少写一个配置文件了

  1. public interface studentDao{
  2. @Select("select * from user where id=#{id}")
  3. public List<UserStudent> selectUsers();
  4. //这个selectUser对应是的一个SQL语句的执行,可以看到方法的第二个单词为返回类型,返回类型为List,内部存储的是为User类型的对象
  5. }

此时我们的mapper配置修改为

  1. <mappers>
  2. <mapper class="com.test.dao.Userdao">
  3. <mapper class="com.test.dao.Studentdao">
  4. //写了多少个查询,就加多少个类名
  5. </mappers>