05_CRUD操作

时间:2023-03-08 21:30:59
05_CRUD操作
1.Params拦截器:
  • 作用:Parameters拦截器将把表单字段映射到ValueStack栈的栈顶对象的各个属性中,
  • 注意:如果某个字段在栈顶对象中没有对应的属性,则Params拦截器将尝试在ValueStack中的下一个对象
2.ModelDriven拦截器
  • 作用:
    • Struts2作为企业级的前端应用程序,将Action和Model隔离开是很有必要的
    • 有些Action类并不代表任何Model对象,它们的存在仅仅提供显示服务
  • 流程:
    • 先会执行ModelDrivenInterceptor的Intercept方法
  • 执行
    • 05_CRUD操作
  • ParametersInterceptor的intercept方法:把请求参数的值赋给栈顶对象对应的属性
  • 注意:getModel方法不提供以下实现,的确会返回一个Employee对象到值栈的栈顶,但是当前action的employee确是null05_CRUD操作
    • 05_CRUD操作
3.paramsPrepareParamsStack拦截器栈:
  • 问题:
    • Struts2表单回显时,从值栈栈顶开始查找匹配的属性,若找到就添加到value属性中
    • 若想将Employee对象压入到值栈栈顶,未使用05_CRUD操作
      05_CRUD操作而是直接使用05_CRUD操作
      05_CRUD操作此时的栈顶对象除了employeeId之外全部为null
    • 此时,不能够进行表单的回显,因为经过重写赋值的employee对象以及不是栈顶对象
    • 可以手动将Employee对象放入到值栈栈顶,但是值栈中会存在两个Employee对象,造成冗余
  • 解决方法:
    • 因为Action类实现了ModelDriven接口,所以我们可以在getModel方法中判断是Edit还是Create
    • 若为Edit则05_CRUD操作05_CRUD操作
    • 若为Create则05_CRUD操作05_CRUD操作
    • 此处我们可以根employeeId进行判断,若id为null,则是Create否则是Edit
    • 但是,使用employeeId来判断则需要在ModelDriven拦截器之前使用一个params拦截器
    • 而这个可以使用paramsPrepareParams拦截器栈来实现,因为默认的拦截器栈中ModelDriven之前没有params
    • 05_CRUD操作05_CRUD操作
  • 缺点:
    • 在执行删除操作的时候,getModel方法会从数据库中加载一个对象,浪费资源
    • 执行查询全部信息是也会new 一个新的对象出来,造成浪费
  • 流程:
    • params拦截器首先给action中的相关参数赋值
    • prapare拦截器首先调用prapare方法,给方法中会根据参数(如id)去调用业务逻辑,设置model对象
    • modelDriven拦截器将model对象压入到value stack,这里的model对象就是在prapare中创建的
    • params拦截器再将参数赋值给model对象
    • action业务逻辑执行
3.preparable拦截器:
  • 作用:
    • struts2中的modelDriven拦截器负责把Action类以外的一个对象压入到值栈栈顶
    • 而prepare拦截器负责准备为getModel()方法准备model
    • 一般prepare拦截器是和modelDriven拦截器一起使用的
  • PrepareInterceptor 运行流程(源码解析):
  • 05_CRUD操作05_CRUD操作
  • PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes)方法:05_CRUD操作
    •  05_CRUD操作
  • PrefixMethodInvocationUtil.getPrefixedMethod方法:05_CRUD操作
    • 05_CRUD操作
  • 总结:
    • 若Action实现了Prepareble接口,则struts将尝试执行prepare[ActionMethodName]方法,若prepare[ActionMethodName]不存在,则会尝试执行prepareDo[ActionMethodName]方法
    • 若PrepareInterceptor的alwaysInvokePrepare属性为false,则struts将不会调用实现了Prepareble接口的Action的prepare方法
    • 解决getModel方法造成的浪费:
      • 可以为每一个ActionMethod准备prepare[ActionMethodName]方法,而抛弃原先的prepare方法
      • 将PrepareInterceptor的alwaysInvokePrepare属性设置为false,以避免Struts框架再调用prepare方法
      • 如何在配置文件中为拦截器栈的属性赋值05_CRUD操作
    •   05_CRUD操作