之前给大家分享了[Struts2的配置和使用方法][1],今天跟大家分享下 Struts2 的基础内容

Struts2是什么

  • Struts 是基于 MVC 的 Web 应用框架
  • Struts2 = Struts1 的知名度和市场 + WebWork 的技术

Struts2 有哪些优势?

  1. 实现 MVC 模式,结构清晰(Struts2替代了原先 Servlet 的控制层 C 的位置)
  2. 丰富的标签(tag)(s 标签库)
  3. 通过配置文件页面导航,便于后期维护(resoure 下的 struts.xml 文件,通过 package-action-result 进行导航跳转)
  4. 与 Servlet API 松耦合,便于测试(把原先的 HttpSession 和 HttpServletRequest API中剥离。转换成 Map 键值对)

Struts2 流程分析

  • 步骤包括:
    1. 浏览器通过 URL 发送请求到服务器
    2. web.xml 拦截器拦截到请求,由StrutsPrepareAndExecuteFilter 核心控制器分发给 Struts.xml 文件
    3. struts.xml 接收到请求 action 的 name 名进行匹配,找到后跳转 class 制定的对应 Action
    4. Action 业务控制器进行业务逻辑操作后,return 返回一个字符串对应 Struts.xml 文件中 result 的 name
    5. 根据 result 节点下的 URL 地址进行跳转操作,返回浏览器页面

浏览器 -> 服务器 -> web.xml -> struts.xml -> Action -> struts.xml -> 浏览器

创建业务控制器 Action 的方式

  • 共有三种
    1. 普通的 Java 类
    2. 实现 Action 借口
    3. 继承 ActionSupport 类

调用方式一样

Struts2 与 MVC

  • Struts2 是基于 MVC 的 Web 应用框架,它将请求和展现分开实现
    • M:模型层 — 用于处理业务逻辑关系及数据的封装传递

例如:业务逻辑层 Service 与 Entity 实体类(数据对象模型)

  • V:试图层 — 用于显示数据和接收用户请求

例如:HTML、JSP

  • C:控制层 — 用于协调模型和试图

例如:Servlet、Struts2(核心控制器和业务控制器)

Action 的作用

  • 控制业务逻辑
    1. 如果业务逻辑很复杂,可以爸业务逻辑构建成业务类,在 Action 中调用业务类
    2. 返回结果字符串(例如:success、error、自定义字符串)
  • 方便处理数据
    • 例如:Action 中以属性方式接受用户数据

Action 接受参数

  • 属性方式:
    • 控制业务逻辑
    • 表单参数名称必须在 Action 中有对应的 setter 和 getter
    • 解决乱码
    • 修改 strust.xml 添加代码<constant name=”struts.i18n.encoding” value=”UTF-8″ /><!– 国际化字符集编码为 UTF-8 –>
  • 页面显示
<%@taglib uri="/struts-tags" prefix="s"%>
<s:property value="属性名"/>
或者EL表达式${属性名 }
  • 应用场景
    • 接收的参数字段个数少的时候适合使用,比如对于搜索应用,接收用户输入的搜索条件

JavaBean 方式

  • 将模型数据从 Action 中分离出来
  • 定义实体类 com.entity.User,为实体添加属性以及 setter 和 getter
  • 为 Action 添加实体属性以及 setter 和 getterUser user
  • 修改表单参数 name 为实体对象名
  • <input type=”text” name=”user.username”/>
  • 取值通过 <input type=”text” name=”对象名.属性名”/>的形式<input type=”text” name=”user.username”/>

使用 method 属性(即静态调用业务方法)

  • 访问 Action 时,默认调用的是 execute()方法
    • 可以在Action中定义多个业务方法
public static add(){
}

public static update(){
}
  • 配置多个 <action> 标签
    • method 属性制定调用的方法
<action name="house" class="web.action.HouseAction2">
    <result name="addSuccess">
        /houseAddSuccess.jsp
    </result>
    <result name="updateSuccess">
        /houseUpdateSuccess.jsp
    </result>
</action>

使用动态方法调用

  • 1. DMI (dynamic method invocation)动态方法调用 Struts.xml中必须有所需配置:
<!-- 配置参数 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" /><!-- 动态方法调用是否开启 -->
  • 2. 一个 Action 类中可以有多个业务方法
<constant name="struts.devMode" value="true" /><!-- 开启开发者模式 -->
<constant name="struts.i18n.encoding" value="UTF-8" /><!-- 国际化字符集编码为 UTF-8 -->
  • 3. 只需要配置一个 <action> 标签
public static add(){

}

public static update(){

}
  • 4. 不需要使用 method 属性
  • 5. 调用时指出 Action 名和业务方法
http://localhost:8080/webname/house!add

<result> 的 name 属性

  • 根据 Action 业务方法的返回值跳转到不同的结果视图

例如:

  1. 当登录成功时,Action 返回字符串Success,则调用 result 的 name 属性值为 Success 的分支跳转成功页面
  2. 当登录失败时,Action 返回字符串error,则调用 result 的 name 属性值为 error 的分支跳转登录页面
if("admin".equals(user.getUsername()) && "123456".equals(user.getPassword())){
    // 从 Action 请求上下文中,获取上下文对象,获取其中的 Session 会话
    session = ActionContext.getContext().getSession();
    // 把登录者用户信息存入会话中
    // 等价于 session.setAttribute("user_info",user);
    session.put("user_info",user);
    // 从 Action 请求上下文中,获取上下文对象,获取其中的 request 请求对象
    request = (Map<String,Object>) ActionContext.getContext().get("request");
    // 把登录者所在地放入 request 请求对象中
    // 等价于 request.setAttribute("loginAddress","江苏南京");
    request.put("loginAddress","江苏南京");
    System.out.println("登录成功");
}else{
    this.setErrMsg("用户名或密码不匹配");// 当用户不匹配时设置错误信息
    System.out.println("用户名或密码不匹配");// 控制台打印错误相信
    return ERROR;// 返回给 Struts.xml 中
}

 

<action name="toLogin" class="web.action.LoginAction">
    <result name="success">
        /loginSuccess.jsp
    </result>
    <result name="error">
        /login.jsp
    </result>
</action>