1.Struts2 初体验

一.概述

  1. Struts2框架=Struts+XWork
  2. Strust2 核心功能:
    1. 允许POJO(Plain Old Java Objects)对象作为Action.
    2. Action的execute 方法不再与Servlet API耦合,更易测试
    3. 支持更多视图技术(JSP、FreeMarker、Velocity)
    4. 基于Spring AOP思想的拦截器(感觉在Struts2中,使用数据的封装和国际化等等功能非常容易,)机制,更易扩展
    5. 更强大,更易用输入校验功能
    6. 整合Ajax支持

二.第一个Struts2程序

image

  1. 拷贝/apps/struts2-blank/WEB-INF/lib中的jar到项目的lib中.
    找到根下apps目录,找到struts2-blank(Struts2提供的空白项目),里面整合了Struts2的依`赖环境和配置.
    Struts运行必要jar包如下:
struts2-core-2.3.1.1.jar:  Struts 2框架的核心类库
xwork-core-2.3.1.1.jar:    Command模式框架,WebWork和Struts2都基于xwork 
ognl-3.0.3.jar:        对象图导航语言(Object Graph Navigation Language),  struts2框架通过其读写对象的属性
freemarker-2.3.18.jar:     Struts 2的UI标签的模板使用FreeMarker编写
commons-logging-1.1.x.jar:     ASF出品的日志包,Struts 2框架使用这个日志包来支持Log4J和JDK 1.4+的日志记录。
commons-fileupload-1.2.2.jar: 文件上传组件,2.1.6版本后需要加入此文件
commons-io-2.0.1.jar:  传文件依赖的jar包
commons-lang-2.5.jar:  对java.lang包的增强
  1. web.xml中配置Struts2的前端控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>struts2crud</display-name>
	<filter>
		<filter-name>struts</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>struts</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>
  1. 拷贝struts.xml文件到项目的Source folder文件夹中
  2. 定义一个POJO类,HelloAction,提供公共无参数execute方法
//POJO类
public class HelloAction {
	public String execute() {
		System.out.println("Hello World");
		//返回的逻辑试图名称
		return "dusk";
	}
}
  1. 在struts.xml文件中,配置HelloAction
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
	<!-- namespace决定访问路径 -->
	<package name="hellopkg" extends="struts-default" namespace="/hello">
		<action name="world" class="com.dusk.hello.HelloAction" method="execute"/>
		    <result name="dusk" type="dispatcher">/views/hello.jsp</result>
		</action>
	</package>
</struts>
  1. 部署Web项目,访问Action
    访问格式: http://ip:port/contextPath/namespace/actionName[.action]

访问格式:http://localhost:80/hello/world[.action]

三.Struts2简单流程

image

四.Struts2基本配置

Struts2框架按照如下顺序加载struts2配置:
  1. default.properties
    该文件保存在 struts2-core-2.3.7.jar 中 org.apache.struts2包里面:包含了Struts2的默认常量配置
  2. struts-default.xml
    该文件保存在 struts2-core-2.3.7.jar:包含了框架依赖的对象配置和结果类型,拦截器等配置.
  3. struts-plugin.xml
    该文件保存在Struts2框架的插件中:struts-Xxx-plugin-2.3.7.jar.由插件提供
    上述三个文件是框架自带的,我们不能修改,只能使用.
  4. struts.xml
    该文件是web应用默认的struts配置文件.重点.配置自定义的Action和其他信息.
  5. struts.properties
    该文件是Struts的默认配置文件–>可以修改default.properties 的常量配置.
  6. web.xml 该文件是Web应用的配置文件
    上述三个文件是我们可以修改操作的.
注意:

1.在大部分应用里,随着应用规模的增加,系统中Action的数量也会大量增加,导致struts.xml配置文件变得非常臃肿。为了避免struts.xml文件过于庞大、臃肿,提高struts.xml文件的可读性,我们可以将一个struts.xml配置文件分解成多个配置文件,然后在struts.xml文件中包含其他配置文件。下面的struts.xml通过元素指定多个配置文件:

struts.xml:
<struts>
      <include file="分支文件的路径"/>
      ...     
</struts>
  1. 如果多个文件配置了同一个struts2常量,则后一个文件中配置的常量值会覆盖前面文件配置的常量值.
    一般的,我们只在struts.xml中做常量配置
Struts2中常见常量:
  1. :指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法和freemarker、velocity的输出
<constant name="struts.i18n.encoding" value="UTF-8"/>
  1. :该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts2处理。
    如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号( , )隔开
<constant name="struts.action.extension" value="action,,"/>
  1. :设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭
<constant name="struts.serve.static.browserCache" value="false"/>
  1. :当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开
<constant name="struts.configuration.xml.reload" value="true"/>
  1. :开发模式下使用,这样可以打印出更详细的错误信息
<constant name="struts.devMode" value="true" />

:修改struts.xml之后,不要重启Tomcat.
6) :默认的视图主题

<constant name="struts.ui.theme" value="simple" />
  1. :是否支持动态方法调用
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>

五.package元素

  1. 元素: 是根元素的子元素.
    用来对多个元素分类管理,和Java中的package没有关系.
    常见的属性:
<package name="" extends="" namespace="" abstract=""></package>
  1. name:
    表示的名字,但是要保证不同的元素的name不同. 可以通过该名字被其他的包所指代.
  2. extends:
    表示当前继承哪一个,一般都是:struts-default.
    而struts-default其实就是struts-default.xml中元素的名字.
    继承struts-default之后,就拥有了该定义的所有资源.(结果返回类型,拦截器…)
  3. namespace:
    表示命名空间,一般的以"/"打头,命名一般以模块名.如: /crm, /oa. 和的name决定了一个Action类的访问路径.
  4. abstract:
    抽象的,缺省值是false. 若一个的abstract=“true”,那么该中就不能再定义元素,只能用来继承.

六.action元素

元素:是元素的子元素.

  1. 专门用来配置Action对象的.
<action name="" class="" method=""/>
  1. 常见的属性:
    1. name:
      action的名称,在同一个中,action的名字必须唯一.
      和的namespace共同决定了一个Action类的访问路径.
      Struts2中的资源名称: package的namespace/action的name
      注意:action的name值不能以"/"打头.
    2. class:
      一个Action类的全限定名. 缺省值:ActionSupport类.
    3. method:
      当前Action动作访问的方法, 缺省值:execute.

七.result元素

<result name="" type=""></result>
局部结果视图: <result>定义在<action>中.
全局结果视图: <result>定义在<global-results>中,而<global-results>在<package>中
  1. 逻辑视图寻找顺序:先从当前的Action中去选择局部结果视图,找到就跳转,找不到,再找当前action所在package中找全局的结果视图,找到,跳转,找不到,报错.No result defined.

  2. 常见的属性:

name:Action方法返回的逻辑视图名称. 缺省值:success
type:结果的跳转类型.该类型的值在struts-default.xml中已经预定义好了. 缺省值:dispatcher
  1. 常见的type值(结果类型):
dispatcher:      表示从Action请求转发到页面(JSP).缺省值
redirect:          表示从Action重定向到页面(JSP).
chain:               表示从Action请求转发到另一个Action.
redirectAction:  表示从Action重定向到另一个Action.
stream:          表示返回流. 用于文件下载时使用.

八.Action类的编写

  • 方式一,使用公共的POJO类作为Action. 提供公共的无参数的Action方法.(不推荐)
pubilc class Action1{
    public String execute(){
        return "success";
    }
}
  1. 缺点:
    1. 没有一种方式约束Action方法必须是公共的无参数的.
    2. Action方法的返回逻辑视图名可以自定指定. 有时起名不规范. 比如:“ooxx”.
  • 方式二,实现于com.opensymphony.xwork2.Action接口.并覆写execute方法即可.(不推荐)
    Action接口中,不仅提供了Action方法的声明,也提供了常用的逻辑视图名称:
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = "login";
public class Action2 implements Action{
    public String execute(){
        return SUCCESS;
    }
}
  1. 缺点:
    1. 不支持国际化,数据校验,消息机制.
  • 方式三,定义一个类,继承于com.opensymphony.xwork2.ActionSupport类.(推荐)
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider,LocaleProvider, Serializable {
    
}
public class Action3 extends ActionSupport{
    public String execute(){
        return SUCCESS;
    }
}

九.Action中方法调用

  • 方式一(不推荐)
<action name="employeeSave" class="com.dusk.EmployeeAction" method="save"/>
  • 方式二(不推荐)
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
<package name="methodPak" extends="struts-default">
    <action name="employeeSave" class="com.dusk.EmployeeAction"/>
</package>

调用 methodPak!方法名

  • 方式三(推荐)
    使用通配符的方式类配置: 通配符:* (推荐)
<action name="empoyee_*" class="com.manymethod.EmployeeAction" method="{1}">

Action的名字: empoyee_Action方法: 比如:emp_list,那么{1}的值就是list
empoyee_edit,那么{1}的值就是edit

两个通配符:

<action name="*_*" class="com.manymethod.{1}Action" method="{2}">

Action名字:Action类名_Action方法. 比如:Employee_list,表示调用的EmployeeAction中的list方法
比如:Department_edit,表示调用DepartmentAction中的edit方法.

十.Action获取请求参数

  • 方式一
    Action本身作为Model对象,通过OGNL表达式调用Action中的setter方法封装(属性注入).

Action类

public class LoginAction extends ActionSupport {
    @Setter
    private String username;
    @Setter
    private String password;

    private IEmployeeService service = new EmployeeServiceImpl();

    public String execute() {
        try {
            service.login(username, password);
        } catch (Exception e) {
            addActionError(e.getMessage());//在Action中设置错误信息
            return LOGIN;//返回登录界面
        }
        return SUCCESS;
    }
}

Jsp界面

    <a style="color:red"><s:property value="actionErrors"/></a>
    <s:form action="login">
        账号:<s:textfield name="username"/><br>
        密码:<s:password name="password"/><br>
        <s:submit value="朕要登录"/><br>
    </s:form>
  • 方式二
    创建独立Model对象,通过OGNL表达式把数据封装到Action对象的子属性中.

Model对象

@Getter@Setter@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
    private Long id;
    private String username;
    private String password;
}    

Action类

public class EmployeeAction extends ActionSupport {
    @Getter
    private Employee e = new Employee();
}

Jap页面

<s:a action="employee_input">编辑
    <s:param name="e.id" value="id"/>
</s:a> |
<s:a action="employee_delete" >删除
    <s:param name="e.id" value="id"/>
</s:a>

十一.ValueStack和OGNL介绍

  1. 通过ActionContext对象获取
ValueStack vs = ActionContext.getContext().getValueStack();
  1. ValueStack内部结构
root:类型: CompoundRoot extends ArrayList  : 表示栈的数据结构(后进先出)
context: 类型:                      Map:          : 上下文
  1. 把数据放入ValueStack.
    1. 把数据放入root中:(栈,ArrayList.每次都是压在栈顶)
      框架默认把当前被Action对象存入栈顶,这个设置建议大家不要去改动,
      在Action对象中提供读取属性的方法(getter方法)

      一般的,把单个对象可放入root中,就在栈顶.

    2. 把数据放入context中:
      ActionContext对象.put(String key,Object value);

从root中获取数据: 直接使用属性名获取.     --->    <s:property value="属性名"/>
从context中获取数据: 属性名称前加 # 号     --->    <s:property value="#属性名"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值