Struts2

(在xml中,访问xml路径,默认在web下)

概述

应用javaee中的三层框架中的web层(展示层)

技术特点

原始的servlet:增加一个功能,就要添加一个servlet。
Struts2

web时期用过baseServlet,反射实现

package com.yangwei.mvc.servlet;

import java.io.IOException;
import java.lang.reflect.Method;

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

/**
 * 这个BaseServlet类不需要在web.xml中进行配置
 */
public class BaseServlet extends HttpServlet {
    
    private static final long serialVersionUID = 1L;
    /**
     * 所有的Servlet请求都会被service()方法拦截
     */
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //传递过来用户的操作名(add,list,update等)即可
        String mm=request.getParameter("operate");
        Method method=this.getClass().getMethod(mm, HttpServletRequest.class,HttpServletResponse.class);
        String rel=method.invoke(this, request,response);
        String redirStr="redirect:";
        if(rel.startsWith(redirStr)){
            //客户端跳转
            response.sendRedirect(rel.substring(redirStr.length()));
        }else{
            //将服务器端的跳转转移到这里统一执行
            request.getRequestDispatcher("/WEB-INF/"+rel).forward(request,response);
        }
        
    }

}

servlet代码

package com.yangwei.mvc.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.yangwei.mvc.model.User;

/**
 * 我们具体的Servlet继承BaseServlet
 * 各个方法的返回值说明我们要跳转到的页面
 */
public class MyServlet extends BaseServlet {
    
    public String add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("add method");
        //对于客户端跳转,我们用redirect:标识
        return "redirect:my/add.jsp";
    }
    public String update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("update method");
        //服务器端的跳转
        return "my/update.jsp";
    }
    public String delete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("delete method");
        //服务器端的跳转
        return "my/delete.jsp";
    }
}

要写到底层反射代码。

struts2如何解决?

所有的请求会被struts2自带的过滤器拦截,过滤器中对不同的操作,分别调用不同的方法去执行。

action:方法就写在action,类似之前的servlet方法

day01 Struts2入门

struts2的创建

首先是idea的配置,在这篇指导下完成 传送门

1、创建action(类似servlet),每次访问action的时候都会执行execute方法。

2、配置action类的访问路径

2.1 、创建核心配置文件,名称和位置是固定的。src下的 struts.xml
package

作用:类似于代码的包,用于区分不同的action。

标签的属性:

  • name : 和功能本身没有关系的,是为了用于区分不同的package

  • extend: 继承,固定为struts-default。类因此具备action功能

  • namespace:要和action标签里面的name值构成访问路径

action

作用:配置action的访问路径

标签的属性:

  • name: 访问路径的一部分。同一个package下的action的name不可相同。
  • class:全路径,为了反射时找到实体位置
  • method:默认的是execute,假如现在希望执行的是update方法,那么method=“update”
result

作用:根据action的方法返回值,做跳转(不一定是页面,任何路径都行)

标签属性:

  • name:和返回值进行匹配
  • type: 配置跳转路径的方法,默认是转发(地址栏不变)
修改常量

Struts2最常用的一个,帮我们完善了post方式提交的中文乱码问题

目录如下Struts2

struts的执行过程

Struts2

协调开发

struts配置文件中,可以通过引入的方式引入文件。
Struts2

访问不同的action方法

Struts2
1、在action的method属性标识

2、通配符实现(重点掌握)
struts2.5版本对此进行更新
需要把dtd约束改成2.5。
然后二选一
要么加上<global-allowed-methods>regex:.*</global-allowed-methods>
要么加上<allowed-methods>add,hello</allowed-methods>

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
    <package name="hellodemo" extends="struts-default" namespace="/">
         <!--访问hello_update 那么就执行update方法
         {1}标识第一个*
         -->
        <global-allowed-methods>regex:.*</global-allowed-methods>
        <action name="User_*" class="com.lin.struts.StrutsDemo" method="{1}">
            <result name="success">/hello.jsp</result>
            <allowed-methods>add,hello</allowed-methods>
        </action>
    </package>
</struts>

3、动态访问

day02 Struts2入门 数据操作

1、结束页面配置

全局加局部,局部优先级大

1.1 全局结果页面

作用:多个action,返回的是用一个结果页面
配置:在package中!
只在当前package中生效

1.2 局部结果页面(普通)

 <package name="demo" extends="struts-default" namespace="/">
        <global-results>
            <result name="success">/quanju.jsp</result>
        </global-results>
        <action name="Login" class="com.lin.action.LoginAction">
            <result name="success">/login.jsp</result>
        </action>

        <action name="Regist" class="com.lin.action.RegistAction">
            <!--<result name="success">/regist.jsp</result>-->
        </action>
    </package>

1.3 result中的type属性

  • 重定向 redirect
  • 转发 dispatcher
到其他action
  • chain:转发到action 一般不用
  • redirectAction: 重定向到action

2、在action获取表单提交的数据

2.1 使用ActionContext类获取
Struts2

2.2 使用ServletActionContext类获取
Struts2操作域对象
Struts2
2.3 使用接口的注入方式获取
Struts2

3、在struts2里面使用的封装方式

3.1 属性封装

在action中定义数据成员(和表单一一对应且name相等,当表单发送过来时,struts2自动把数据封装到数据成员中)

Struts2

3.2 模型驱动封装(主要使用)

第一步:action实现ModelDriven
Struts2
第二步:new一个实体类的对象

第三步:在getModel中返回该对象

第四步:操作该对象

作用:

当表单发送数据过来时,自动封装到这个对象里面

3.3 表达式封装(适合封装到不同的实体类)

第一步:在action里声明实体类

第二部:生成实体类对象的get、set方法
Struts2
第三步:在表单输入项的name属性值里面写表达式形式
Struts2

4、获取数据封装到集合中(会用)

4.1 封装到list
Struts2Struts2
4.2 封装到map
Struts2Struts2

5、实战,客户关系系统中的添加客户

第一步: 通过模型驱动完成表单获取

Struts2
第二步:使用hibernate插入新数据
Struts2

第三步:发送请求至查询页面,展示新插入的数据

Struts2

day03 Struts2的值栈和ognl表达式

1、OGNL表达式

1.1 简介

之前在web阶段学习过EL表达式,应用在JSP页面中获取域对象内容

用于struts2里面操作值栈数据,可以结合struts2里面的标签一起使用值栈

ognl不属于struts2的一部分,他是单独存在的。struts2提供了ognl的jar包

1.2 ognl入门实例

第一步:导入jar包,然后引入标签库

之前在使用jstl的时候需要引入标签库,现在也一样,第一步是引入标签库
Struts2

第二步:结合struts的标签

Struts2

2、值栈

我们之前把东西放到作用域中,现在可以用struts2提供值栈来存取数据。

2.1 servlet和action的区别

  1. servlet只在第一次访问的时候创建,创建一次,单实例

  2. action每次访问的时候,创建action

2.2 值栈存储位置

每次访问都会创建action,每个action对象拥有独立的一个值栈

2.2 获取值栈对象

方法一: 用ActionContext对象获取

Struts2

方法二

2.3 值栈内部结构

第一部分:root,结构是list集合(一般使用这个)

第二部分: context,结构是map