struts2常识总结

===首先引用jar包===

早在struts2.0.*的时候,struts2的必备jar包需要如下几个:

commons-logging-*.jar   Apache旗下commons项目的log日志包

freemarker-*.jar             一种前台页面模板,应用比较广泛

ognl-*.jar                        动态图导航语言,struts2处理前台页面的核心语言,相当实用

struts2-core-*.jar           struts2的核心包

xwork-core-*.jar             webwork的核心包,因为struts2的前身是webwork,所以这个是必须的

只要满足这5个基本jar包就可以运行一个struts2的hello world

(注:*表示版本号,struts2不同版本,使用的jar包版本也可能不一样。)



但是后面版本,比如struts-2.1.8.1,必须再添加一个jar包才能运行,不然启动就会报错:

commons-fileupload-1.2.1.jar   支持文件上传的jar包



===struts.xml配置文件===

struts.xml是核心配置文件,可以实现很多基本配置以及设置Action转发跳转等操作。可以手动创建或从struts源文件()中拷贝一个struts.xml,默认放在class下(也就是你的项目源文件src目录下),当然这个配置文件的存放位置是可配的,这个稍后介绍。

下面我们看看struts.xml常用的一些配置:

Xml代码 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE struts PUBLIC  
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"  
        "http://struts.apache.org/dtds/struts-2.0.dtd"> 
<struts> 
    <!--载入默认的struts配置--> 
    <include file="struts-default.xml" /> 
    <!--指定web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法--> 
    <constant name="struts.i18n.encoding" value="UTF-8"></constant>   
    <!--该属性指定需要Struts2处理的请求后缀,该属性的默认值是action--> 
    <constant name="struts.action.extension" value="action,do"></constant>   
    <!--设置浏览器是否缓存静态内容,默认值为true,生产环境下使用,开发阶段最好关闭 --> 
    <constant name="struts.serve.static.browserCache" value="false"></constant> 
    <!--当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false,生产环境下使用,开发阶段最好打开 --> 
    <constant name="struts.configuration.xml.reload" value="true"></constant> 
    <!--开发模式下使用,可以打印出更详细的错误信息 --> 
    <constant name="struts.devMode" value="true" /> 
    <!-- 是否支持通配符,默认为true --> 
    <constant name="struts.enable.DynamicMethodInvocation" value="false" /> 
    <!-- 是否支持页面调用静态方法,默认为false  注:这个在struts2.0.*版本是默认支持调用静态方法的 --> 
    <constant name="struts.ognl.allowStaticMethodAccess" value="true"/> 
    <!-- 默认的视图主题 --> 
    <constant name="struts.ui.theme" value="simple"></constant> 
    <!--Struts2集成Spring:所有action对象有Spring来负责创建--> 
    <constant name="struts.objectFactory" value="spring"></constant> 
    <!--全局的国际化文件命名--> 
    <constant name="struts.custom.i18n.resources" value="messageResource"></constant> 
      
    <package name="default" extends="struts-default"> 
    <!-- 找不到Action时的默认跳转地址 --> 
        <default-action-ref name="error"/> 
        <action name="error"> 
            <result>/error404.html</result> 
        </action> 
    </package> 
      
    <!-- 引用其它struts配置文件 --> 
    <include file="struts-*.xml"></include> 
</struts> 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <!--载入默认的struts配置-->
    <include file="struts-default.xml" />
    <!--指定web应用的默认编码集,相当于调用HttpServletRequest的setCharacterEncoding方法-->
    <constant name="struts.i18n.encoding" value="UTF-8"></constant>
    <!--该属性指定需要Struts2处理的请求后缀,该属性的默认值是action-->
    <constant name="struts.action.extension" value="action,do"></constant>
    <!--设置浏览器是否缓存静态内容,默认值为true,生产环境下使用,开发阶段最好关闭 -->
    <constant name="struts.serve.static.browserCache" value="false"></constant>
    <!--当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false,生产环境下使用,开发阶段最好打开 -->
    <constant name="struts.configuration.xml.reload" value="true"></constant>
    <!--开发模式下使用,可以打印出更详细的错误信息 -->
    <constant name="struts.devMode" value="true" />
    <!-- 是否支持通配符,默认为true -->
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <!-- 是否支持页面调用静态方法,默认为false  注:这个在struts2.0.*版本是默认支持调用静态方法的 -->
    <constant name="struts.ognl.allowStaticMethodAccess" value="true"/>
    <!-- 默认的视图主题 -->
    <constant name="struts.ui.theme" value="simple"></constant>
    <!--Struts2集成Spring:所有action对象有Spring来负责创建-->
    <constant name="struts.objectFactory" value="spring"></constant>
    <!--全局的国际化文件命名-->
    <constant name="struts.custom.i18n.resources" value="messageResource"></constant>
   
    <package name="default" extends="struts-default">
    <!-- 找不到Action时的默认跳转地址 -->
    <default-action-ref name="error"/>
    <action name="error">
    <result>/error404.html</result>
    </action>
    </package>
   
    <!-- 引用其它struts配置文件 -->
   <include file="struts-*.xml"></include>
</struts>

前面已经说了,struts.xml文件默认是放在src目录下(假设现在是WEB-INF/src下),可能项目组希望把配置文件放在别的目录统一管理(假设希望放到WEB-INF/conf/struts),这样你需要在web.xml中配置struts.xml的存放路径:

Xml代码 
<!-- struts2 滤镜配置  --> 
    <filter> 
        <filter-name>struts2</filter-name> 
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> 
        <init-param> 
            <param-name>config</param-name> 
            <param-value>struts-default.xml,struts-plugin.xml,../conf/struts/struts.xml</param-value>             
        </init-param> 
    </filter> 
 
    <filter-mapping> 
        <filter-name>struts2</filter-name> 
        <url-pattern>/*</url-pattern> 
    </filter-mapping> 

<!-- struts2 滤镜配置  -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>struts-default.xml,struts-plugin.xml,../conf/struts/struts.xml</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

因为struts默认路径是从src根目录下找,src和conf是同级目录,所以需要加两点".."找到src上级目录WEB-INF,然后再找conf文件。



上图为配置文件的存放目录,这里还要注意的是struts.xml里面<include>标签引用的文件路径需要改变了,因为include也是从class根下面找文件。



Xml代码 
<include file="../conf/struts/struts-et.xml"></include> 
    <include file="../conf/struts/struts-exception.xml"></include> 
    <include file="../conf/struts/struts-ognl.xml"></include> 
    <include file="../conf/struts/struts-result.xml"></include> 
    <include file="../conf/struts/struts-scope.xml"></include> 

<include file="../conf/struts/struts-et.xml"></include>
   <include file="../conf/struts/struts-exception.xml"></include>
   <include file="../conf/struts/struts-ognl.xml"></include>
   <include file="../conf/struts/struts-result.xml"></include>
   <include file="../conf/struts/struts-scope.xml"></include>

也许有人为问“为什么不用通配符”,很不幸的是,如果把struts.xml转移位置后,就不支持通配符了,这个我也是很郁闷。





===获得request、session、application作用域对象===

struts2有四种方式获得作用域对象:



  不基于servlet容器 基于servlet容器
非IOC 通过ActionContext来获的
通过ServletActionContext和ServletActionContext来获得
采用IOC 实现RequestAware,SessionAware,ApplicationAware三个接口的抽象方法 实现ServletRequestAware,ServletContextAware这两个接口的抽象方法



这四种方式各有优劣,我用得比较多的是“基于servlet容器并实现IOC”的那种方式,在这稍微介绍一下这种用法:

Java代码 
public class BaseAction extends ActionSupport implements ServletRequestAware,ServletContextAware,ServletResponseAware{  
    //配置序列化标志  
    private static final long serialVersionUID = 1L;  
      
    //request,response,application,session作用域  
    protected HttpServletRequest request ;  
    protected ServletContext application;  
    protected HttpServletResponse response;  
    protected HttpSession session;  
      
    /** 
     * 依赖servlet容器的IOC设置-start 
     */ 
    @Override 
    public void setServletRequest(HttpServletRequest arg0) {  
        this.request = arg0;  
        session = this.request.getSession();  
    }  
 
    @Override 
    public void setServletContext(ServletContext arg0) {  
        this.application = arg0;  
    }  
 
    @Override 
    public void setServletResponse(HttpServletResponse arg0) {  
        this.response = arg0;  
    }  
    /** 
     * 依赖servlet容器的IOC设置-end 
     */ 
 
    //重写execute方法  
    @Override 
    public String execute() throws Exception {  
        request.setAttribute("requestKey", "requestValue");  
        session.setAttribute("sessionKey", "sessionValue");  
        application.setAttribute("applicationKey", "applicationValue");  
        return SUCCESS;  
    }  
}} 

public class BaseAction extends ActionSupport implements ServletRequestAware,ServletContextAware,ServletResponseAware{
//配置序列化标志
private static final long serialVersionUID = 1L;

//request,response,application,session作用域
protected HttpServletRequest request ;
protected ServletContext application;
protected HttpServletResponse response;
protected HttpSession session;

/**
* 依赖servlet容器的IOC设置-start
*/
@Override
public void setServletRequest(HttpServletRequest arg0) {
this.request = arg0;
session = this.request.getSession();
}

@Override
public void setServletContext(ServletContext arg0) {
this.application = arg0;
}

@Override
public void setServletResponse(HttpServletResponse arg0) {
this.response = arg0;
}
/**
* 依赖servlet容器的IOC设置-end
*/

//重写execute方法
@Override
public String execute() throws Exception {
request.setAttribute("requestKey", "requestValue");
session.setAttribute("sessionKey", "sessionValue");
application.setAttribute("applicationKey", "applicationValue");
return SUCCESS;
}
}}




===序列化标志===

serialVersionUID作用:序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
当你创建一个Action的时候,强烈建议添加一个private static final long serialVersionUID = 1L;曾经我在跑项目的时候发现页面莫名其妙出现乱码问题,我查了数据库、项目、配置文件等等,所有的都是utf-8,但是仍然出现了乱码,后来将action设置序列化以后就好了。1L是默认的,当然你也可以自己定义。



===OGNL对象图导航语言===

OGNL是一个功能强大的EL,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。因为太过复杂,这里就简单介绍几个常用的。

假设demo1.jsp页面有姓名name,年龄age这两个表单数据,它们被提交到action(action可以访问数据库保存或者比对或者更新),然后action再转发到demo2.jsp页面显示刚才输入的数据。

这是一个典型的B/S案例,我们可以将表单数据封装到一个JavaBean中(有的人喜欢叫pojo,还有的叫vo,还有的叫formbean),到demo2.jsp的时候通过ognl表达式取出来。

demo1.jsp

Html代码 
<%@ page contentType="text/html; charset=UTF-8" language="java" import="java.util.*" pageEncoding="UTF-8"%> 
<!--添加struts2标签的引用--> 
<%@ taglib prefix="s" uri="/struts-tags" %> 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
<html> 
    <head> 
    </head> 
    
    <body> 
        <s:form action="doSaveAction.action" method="post"> 
        <s:textfield  name="user.name">姓名:</s:textfield> 
        <s:textfield name="user.age">年龄:</s:textfield> 
        <s:submit value="提交"></s:submit> 
        </s:form> 
    </body> 
</html> 

<%@ page contentType="text/html; charset=UTF-8" language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!--添加struts2标签的引用-->
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
 
<body>
<s:form action="doSaveAction.action" method="post">
<s:textfield  name="user.name">姓名:</s:textfield>
<s:textfield name="user.age">年龄:</s:textfield>
   <s:submit value="提交"></s:submit>
   </s:form>
</body>
</html>
User.java

Java代码 
public class User{  
  private String name;  
  private String age;  
  ...get、set方法...  


public class User{
  private String name;
  private String age;
  ...get、set方法...
} SaveAction.java

Java代码 
public class SaveAction extends ActionSupport{  
    private static final long serialVersionUID = 1L;  
    //将User这个javabean创建set方法便能获得从jsp请求过来的user对象数据  
    //同时user对象会放在值栈中,在demo1.jsp--SaveAction--demo2.jsp这个生命周期都存在  
    private User user;  
 
    public String doSave(){  
        return SUCCESS;  
    }  
      
    public User getUser() {  
        return user;  
    }  
    public void setUser(User user) {  
        this.user = user;  
    }  


public class SaveAction extends ActionSupport{
private static final long serialVersionUID = 1L;
//将User这个javabean创建set方法便能获得从jsp请求过来的user对象数据
//同时user对象会放在值栈中,在demo1.jsp--SaveAction--demo2.jsp这个生命周期都存在
private User user;

public String doSave(){
return SUCCESS;
}

public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
} demo2.jsp

Html代码 
<s:property value="user.name"/> 
<s:property value="user.age"/> 

<s:property value="user.name"/>
<s:property value="user.age"/>



之所以命名为OGNL,就是因为它处理对象很给力,struts能够将对象层层解析,把各个对象的关系以图的样式展示出来。比如user.name,之所以能找到这个对象,就是因为OGNL会先找user对象,然后再找user对象里的name对象。假设User这个类还包含了名为Role的javabean的实例,Role里面包含字段roleName,我们要找到roleName就可以直接写<s:property value="user.role.roleName">,OGNL通过对象逐级导航找到子对象。



当然OGNL也可以像jsp一样调用后台代码,不过我发现在jsp调用后台代码的效率很低,所以不是很推荐。

ognl调用静态方法的写法如下:@类全名@静态方法名,这句话等同于java代码:类全名.静态方法名

Html代码 
运行静态方法:<s:property value="@com.bless.ssh2.action.OgnlAction@staticMethod()"/><br/> 
运行值栈对象中的方法:<s:property value="user.method()"/><br/> 
调用JDK中的静态方法:<s:property value="@java.lang.Math@floor(44.56)"/><br/> 

运行静态方法:<s:property value="@com.bless.ssh2.action.OgnlAction@staticMethod()"/><br/>
运行值栈对象中的方法:<s:property value="user.method()"/><br/>
调用JDK中的静态方法:<s:property value="@java.lang.Math@floor(44.56)"/><br/> 需要注意的是,struts2.1.*默认是不允许调用静态方法的,你需要在struts.xml配置这样一句话:

<constant name="struts.ognl.allowStaticMethodAccess" value="true"/>

猜你喜欢

转载自bj-liuhuibin.iteye.com/blog/1029923
今日推荐