1、CGLIB代理
有一个类没有实现接口,想要对这个类实现增强,就需要使用CGLIB代理
- 导入CGLIB的包
<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version>
</dependency>
- 编写被代理的类
package com.wz.practice.proxy.cglib;public class UserService {public void add(){System.out.println("--------add执行--------");}public void update(){System.out.println("--------update执行--------");}
}
- 实现代理
package com.wz.practice.proxy.cglib;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/*** 实现了MethodInterceptor接口:该接口是CGLIB提供的用于连接方法调用的机制* 通过实现intercept方法,可以在方法调用前后进行额外的操作.*/public class UserServiceFactory implements MethodInterceptor {private UserService userService;public UserServiceFactory(UserService userService){this.userService=userService;}public UserService getUserServiceProxy(){//创建Enhancer对象,Enhancer enhancer = new Enhancer();//给生成的类指定一个爹enhancer.setSuperclass(UserService.class);//将UserServiceFactory设置为方法拦截器callbackenhancer.setCallback(this);//创建代理对象,将其转换为UserService并返回return (UserService) enhancer.create();}/***在这里进行拦截* @param o* @param method* @param objects* @param methodProxy* @return* @throws Throwable*/public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("打开事务");//method.invoke() 方法是 Java 反射 API 提供的方法,// 用于在指定对象上调用指定的方法。// 它接受两个参数:第一个参数是要调用方法的对象实例,第二个参数是要传递给方法的参数。Object invoke = method.invoke(this.userService, objects);System.out.println("提交事务");return invoke;}
}
- 测试
package com.wz.practice.proxy.cglib;public class Test001 {public static void main(String[] args) {UserService userServiceFactory = new UserServiceFactory(new UserService()).getUserServiceProxy();userServiceFactory.add();}
}
结果:
2、jsp是什么
jsp的爹是 HttpJspbase HttpJspBase 继承了 HttpServlet也就是说 jsp本质就是一个Servletjsp的对外表象就是一个页面,但是这个页面上可以完成Servlet的所有功能jsp是不能直接运行的,在运行之前需要先经过翻译这样一个过程,翻译成Java代码之后,在编译成.class文件 最终这个class文件才会运行
3、域对象
拥有作用域的对象称为域对象,简单来说就是有作用范围的Java对象
jsp中有四个域对象request:作用范围是当前请求,当前请求结束,这个域对象就不存在了,每一个请求都会创建你这样一个域对象。session:生命周期是当前会话 (简单理解就是一次浏览器的打开和关闭)实际上会话的生命周期是30分钟,即使页面关闭了,这个对象也会在jvm中存活一定时间才会死亡application(ServletContext):Tomcat只要打开这个对象就存在,tomcat关闭这个对象就不存,生命周期最长pageContext:生命周期是当前页面,页面关闭,这个对象就不存在了按照生命周期先后顺序排序:pageContext < request < session < application(ServletContext)在开发中使用的最多的是 request session也有使用 application和pageContext基本不会使用与域对象究竟有啥作用呢?可以将Servlet的执行结果直接 带到jsp页面并进行显示
4、EL表达式
EL表达式能直接从四个域对象中取出数据
4.1、El表达式的基本使用
4.1.1、在Servlet中向域对象放数据
package com.wz.practice.servlet;import com.wz.practice.pojo.User;import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;@WebServlet(urlPatterns = "/users")
public class UserServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//这里可以向域对象里放数据req.setAttribute("username","ZhangSan");req.setAttribute("user",new User(01,"ZhangSan","123456"));ArrayList<User> userList = new ArrayList<User>();for (int i = 0; i < 3; i++) {userList.add(new User(i+1,"Username"+i,"123456"));}req.setAttribute("list",userList);//在session对象中放数据HttpSession session = req.getSession();session.setAttribute("sessionKey","sessionVal");//在application中放对象ServletContext application = req.getServletContext();application.setAttribute("applicationKey","applicationVal");req.getRequestDispatcher("/index.jsp").forward(req,resp);}
}
4.1.2、在页面上使用EL表达式取数据
<%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" language="java" %>
<html><head><title>Title</title></head><body><%pageContext.setAttribute("pageKey","pageVal");%><%--从req中取数据--%>用户名是:${username}<br>对象的名字:${user.username}<br>集合中第一个对象的名字:${list[0].username}<br><%--从session中取数据--%>从session中取数据:${sessionKey}<br>从application中取数据:${applicationKey}<br>从pageContext中取数据:${pageKey}</body>
</html>
结果:
4.2、EL取出数据的顺序
pageContext < req < session < application上面的顺序就是我们的EL表达式取出数据的顺序 如果是pageContext没取到 那么就会去 req中取数据 req中没取到 那么就要去session中取数据 session中没取到 那么就要去application中取出数据EL表达式 只能 取出数据 不能表达逻辑关系 以及遍历集合
5、JSTL标准标签库的基本使用
JavaServer Pages Standard Tag Library
EL存在的问题:
- EL主要用于作用域获取数据,虽然可以做判断,但是得到的都是一个结果做展示
- EL不存在流程控制语句,比如判断
- EL对于集合只能做单点访问,不能实现遍历操作,比如循环
JSTL是一个jsp的标签集合
JSTL的作用:
可以对EL获取到的数据进行逻辑操作
可以与EL合作完成数据的展示
- 导包
<!--jstl的标签库-->
<dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version>
</dependency>
- 数据准备
package com.wz.practice.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class Dept {private Integer id;private String username;private Double salary;
}package com.wz.practice.servlet;import com.wz.practice.pojo.Dept;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;@WebServlet(urlPatterns = "/depts")
public class DeptServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setAttribute("age",18);req.setAttribute("score",10);ArrayList<Dept> depts = new ArrayList<Dept>();for (int i = 0; i < 10; i++) {depts.add(new Dept(i+1,"clerk"+i+1,8000.));}req.setAttribute("deptList",depts);req.getRequestDispatcher("/dept_list.jsp").forward(req,resp);}
}
- 取数据
<%--Created by IntelliJ IDEA.User: WangZhiDate: 2023/8/19Time: 11:37To change this template use File | Settings | File Templates.--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%--prefix标签库的前缀--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><head><title>Title</title></head><body><%--jstl中的逻辑运行算符--%><c:if test="${age>=18}">电影可看</c:if><%--if-----else if---else--%><c:choose><c:when test="${score<=60}">不及格</c:when><c:when test="${score<75}">良好</c:when><c:otherwise>优秀</c:otherwise></c:choose><table cellpadding="0" cellspacing="0" border="1" style="width: 600px;text-align: center"><tr><th>id</th><th>名称</th><th>工资</th><th>遍历下标</th></tr><%--items:遍历的集合是啥var:每一次遍历出来的对象是啥varStatus:每一次遍历的状态begin="起始下标" 不写end="结束下标" 不写step="间隔长度" 不写--%><c:forEach items="${deptList}" var="dept" varStatus="status"><tr><td>${dept.id}</td><td>${dept.username}</td><td>${dept.salary}</td><td>${status.index}</td></tr></c:forEach></table></body>
</html>
结果: