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"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值