首页 > 代码库 > Strurs2总结
Strurs2总结
- 必备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包
- web.xml文件配置
- <!-- struts2 滤镜配置 -->
- <filter>
- <filter-name>struts2</filter-name>
- <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
- <init-param>
- <param-name>config</param-name>
- <param-value>
- struts-default.xml,
- struts-plugin.xml,
- <!-- 核心struts.xml文件 -->
- ../conf/common/struts2/struts.xml,
- </param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>struts2</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- struts.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=http://www.mamicode.com/"UTF-8"></constant>
- <!--该属性指定需要Struts 2处理的请求后缀,该属性的默认值是action,即所有匹配*.action的请求都由Struts 2处理
- 如果用户需要制定多个请求后缀,则多个后缀之间以英文逗号隔开-->
- <constant name="struts.action.extension" value=http://www.mamicode.com/"action,do"></constant>
- <!--设置浏览器是否缓存静态内容,默认值为true,生产环境下使用,开发阶段最好关闭 -->
- <constant name="struts.serve.static.browserCache" value=http://www.mamicode.com/"false"></constant>
- <!--当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false,生产环境下使用,开发阶段最好打开 -->
- <constant name="struts.configuration.xml.reload" value=http://www.mamicode.com/"true"></constant>
- <!--开发模式下使用,可以打印出更详细的错误信息 -->
- <constant name="struts.devMode" value=http://www.mamicode.com/"true" />
- <!-- 动态方法调用 false为不允许 -->
- <constant name="struts.enable.DynamicMethodInvocation" value=http://www.mamicode.com/"true" />
- <!-- 默认的视图主题,标签不支持label ; theme属性包括xhtml,html,simple,ajax ,默认是xhtml-->
- <constant name="struts.ui.theme" value=http://www.mamicode.com/"simple"></constant>
- <!--Struts2集成Spring:所有action对象由Spring来负责创建-->
- <constant name="struts.objectFactory" value=http://www.mamicode.com/"spring"></constant>
- <!-- 支持页面使用静态方法和属性 -->
- <constant name="struts.ognl.allowStaticMethodAccess" value=http://www.mamicode.com/"true"></constant>
- <!-- 跳转到登录页 -->
- <package name="CommonPackage" extends="struts-default" namespace="/common">
- <action name="toLoginPage">
- <result>/Web/login/page/login.jsp</result>
- </action>
- </package>
- <!-- 指定其它的配置文件路径 -->
- <include file="../conf/common/struts2/interceptor-common-exception.xml"></include>
- </struts>
- 获取Servlet内置对象
- //取得HttpServletRequest对象
- HttpServletRequest request = ServletActionContext. getRequest();
- //取得HttpSession对象
- HttpSession session = ServletActionContext. getRequest().getSession();
- 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;
- }
- }}
- OGNL对象图导航语言
OGNL是一个功能强大的EL,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。因为太过复杂,这里就简单介绍几个常用的。
假设demo1.jsp页面有姓名name,年龄age这两个表单数据,它们被提交到action(action可以访问数据库保存或者比对或者更新),然后action再转发到demo2.jsp页面显示刚才输入的数据。
这是一个典型的B/S案例,我们可以将表单数据封装到一个JavaBean中(有的人喜欢叫pojo,还有的叫vo,还有的叫formbean),到demo2.jsp的时候通过ognl表达式取出来。
【demo1.jsp】
- <%@ 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=http://www.mamicode.com/"提交"></s:submit>
- </s:form>
- </body>
- </html>
【User.java】
- public class User{
- private String name;
- private String age;
- ...get、set方法...
- }
- 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;
- }
- }
- <s:property value=http://www.mamicode.com/"user.name"/>
- <s:property value=http://www.mamicode.com/"user.age"/>
当然OGNL也可以像jsp一样调用后台代码,不过我发现在jsp调用后台代码的效率很低,所以不是很推荐。
ognl调用静态方法的写法如下:@类全名@静态方法名,这句话等同于java代码:类全名.静态方法名
- 运行静态方法:<s:property value=http://www.mamicode.com/"@com.bless.ssh2.action.OgnlAction@staticMethod()"/><br/>
- 运行值栈对象中的方法:<s:property value=http://www.mamicode.com/"user.method()"/><br/>
- 调用JDK中的静态方法:<s:property value=http://www.mamicode.com/"@java.lang.Math@floor(44.56)"/><br/>
<constant name="struts.ognl.allowStaticMethodAccess" value="http://www.mamicode.com/true"/>
下面这个是早前自己写的Struts2标签库的例子,内容肯定不全:
- <body>
- <!-- "%{}"表示支持ognl表达式,"#u"表示从值栈的actioncontex中查找值 -->
- <s:form action="doTags.action">
- <h3>常用标签库</h3>
- <table>
- <tr>
- <td>编号:</td>
- <!-- 直接获取后台的值 -->
- <td><s:property value=http://www.mamicode.com/"tagBean.id"></s:property></td>
- </tr>
- <tr>
- <td>姓名:</td>
- <!-- 文本框 -->
- <td><s:textfield name="tagBean.name"></s:textfield></td>
- </tr>
- <tr>
- <td>密码:</td>
- <!-- 密码框 -->
- <td><s:password name="tagBean.password"></s:password></td>
- </tr>
- <tr>
- <td>生日:</td>
- <td>
- <!-- 在文本框中格式化时间 -->
- <s:textfield name="tagBean.birthday">
- <s:param name="value">
- <s:date name="tagBean.birthday" format="yyyy-MM-dd hh:MM:ss" />
- </s:param>
- </s:textfield>
- </td>
- <td>生日:</td>
- <!-- 时间标签,可以格式化滴 -->
- <td><s:date name="tagBean.birthday" format="yyyy年MM月dd日"></s:date></td>
- </tr>
- <tr>
- <td>性别:</td>
- <td><s:radio name="tagBean.sex" list="#request.lstSex" listKey="sexId" listValue=http://www.mamicode.com/"sexValue"></s:radio></td>
- </tr>
- <tr>
- <td>城市:</td>
- <!-- listKey:下拉列表被选中后的真实值,listValue:下拉列表被选中后的显示值,headerKey:默认值,headerValue:默认显示值,emptyOption:是否在默认值和实际值下拉列表之间加一个空行 -->
- <td><s:select name="tagBean.city" list="#request.lstCity" listKey="cityId" listValue=http://www.mamicode.com/"cityValue" headerKey="0" headerValue=http://www.mamicode.com/"--请选择--" emptyOption="true"></s:select></td>
- </tr>
- <tr>
- <!-- 此标签等同于:struts2.tags.ListAddress la = new struts2.tags.ListAddress(); -->
- <!-- 此标签需要启用struts2的一个配置常量:<constant name="struts.enable.DynamicMethodInvocation" value="http://www.mamicode.com/true" />,通常不推荐使用此法,在这只是做个例子 -->
- <s:bean name="struts2.tags.ListAddress" id="la"></s:bean>
- <td>地区:</td>
- <!-- s:checkboxlist标签支持多个checkbox, s:checkbox只支持单个checkbox-->
- <td><s:checkboxlist name="tagBean.address" list="#la.lstAddress" listKey="addressId" listValue=http://www.mamicode.com/"addressValue"></s:checkboxlist></td>
- </tr>
- </table>
- <!-- hidden标签存放隐藏值 -->
- <s:hidden></s:hidden>
- <s:submit value=http://www.mamicode.com/"确定"></s:submit>
- <s:reset value=http://www.mamicode.com/"重置"></s:reset>
- <hr/>
- <h3>OGNL</h3>
- <table>
- <!-- #符号: 获取值栈中的作用域 [parameters]路径中传参,[request][session][application]这几个不用说,[attr]表示从parameters到application依次找-->
- <!-- %{}符号:可以获取值栈中的对象,可以使用ognl表达式 -->
- <!-- 如果需要用到直接调用静态方法,需要启用struts2的一个配置常量:<constant name="struts.ognl.allowStaticMethodAccess" value="http://www.mamicode.com/true"/> -->
- <tr>
- <td>直接调用静态方法:</td>
- <td><s:property value=http://www.mamicode.com/"@struts2.tags.Ognl@staticMethod()"/></td>
- </tr>
- <tr>
- <td>直接调用静态属性:</td>
- <td><s:property value=http://www.mamicode.com/"@struts2.tags.Ognl@STATIC"/></td>
- </tr>
- <tr>
- <td>调用值栈对象中的普通方法:</td>
- <td><s:property value=http://www.mamicode.com/"tagBean.normalMethod()"/></td>
- </tr>
- <tr>
- <td>调用JDK的静态方法(带参):</td>
- <td><s:property value=http://www.mamicode.com/"@java.lang.Math@floor(11.11)"/></td>
- <td>吓死你:</td>
- <!-- 如果第一个@后不带任何类,就默认表示java.lang.Math这个工具类,其它类不能这样写 -->
- <td><s:property value=http://www.mamicode.com/"@@floor(22.22)"/></td>
- </tr>
- <tr>
- <td>new一个对象:</td>
- <td><s:property value=http://www.mamicode.com/"new struts2.tags.Ognl(‘构造参数‘).result"></s:property></td>
- </tr>
- <tr>
- <td>#获取request数据:</td>
- <td><s:property value=http://www.mamicode.com/"#request.lstCity"></s:property></td>
- </tr>
- <tr>
- <td>#获取session数据:</td>
- <td><s:property value=http://www.mamicode.com/"#session.sess"></s:property></td>
- </tr>
- <tr>
- <td>下标-获取List集合第一条数据:</td>
- <td><s:property value=http://www.mamicode.com/"#request.lstCity[0]"></s:property></td>
- <!-- 注:Set集合是无序的所以不能通过下标获取数据;Map集合是键值对的,获取的时候应该根据key找value:map[‘key‘] -->
- </tr>
- <tr>
- <td>获取List数据总条数:</td>
- <td><s:property value=http://www.mamicode.com/"#request.lstCity.size"></s:property></td>
- </tr>
- <tr>
- <td>投影技术获取List中指定对象数组:</td>
- <td><s:property value=http://www.mamicode.com/"#request.lstCity.{cityValue}"></s:property></td>
- </tr>
- <tr>
- <td>投影技术+下标获取一个值:</td>
- <td><s:property value=http://www.mamicode.com/"#request.lstCity.{cityValue}[0]"></s:property></td>
- </tr>
- <tr>
- <td>选择器:</td>
- <td><s:property value=http://www.mamicode.com/"#request.lstCity.{#this.cityId<=2}"></s:property></td>
- </tr>
- <tr>
- <td>选择器(?)+投影</td>
- <!-- ?表示获得所有满足条件的对象 -->
- <td><s:property value=http://www.mamicode.com/"#request.lstCity.{?#this.cityId<=2}.{cityId}"></s:property></td>
- </tr>
- <tr>
- <td>选择器(^)+投影</td>
- <!-- ^表示取得第一个满足条件的元素 -->
- <td><s:property value=http://www.mamicode.com/"#request.lstCity.{^#this.cityId<=2}.{cityId}"></s:property></td>
- </tr>
- <tr>
- <td>选择器($)+投影</td>
- <!-- $表示取得最后一个满足条件的元素 -->
- <td><s:property value=http://www.mamicode.com/"#request.lstCity.{$#this.cityId<=2}.{cityId}"></s:property></td>
- </tr>
- <tr>
- <td>Top语法:</td>
- <!-- .top取栈中的对象 ,[n]表示获取栈中第几个对象(从0开始)-->
- <td><s:property value=http://www.mamicode.com/"[0].top.locale"></s:property></td>
- </tr>
- <tr>
- <td>[n]语法:</td>
- <!-- [n]表示获取栈中第几个对象(从0开始)-->
- <td><s:property value=http://www.mamicode.com/"[0].locale"></s:property></td>
- </tr>
- </table>
- <hr/>
- <h3>逻辑,迭代标签</h3>
- <!-- test代码块中支持其它数据类型,如果是int的可以这样:test="#request.if==1" -->
- --if标签--
- <s:if test="#request.if==‘if‘">
- 这里是if模块
- </s:if><s:elseif test="#request.if==‘elseif‘">
- 这里是elseif模块
- </s:elseif><s:else>
- 这里是else模块
- </s:else>
- <br/><br/>
- --循环标签①--
- <!-- first表示起始值,last表示结束值 iterator表示内部循环代码-->
- <s:bean name="org.apache.struts2.util.Counter" id="counter">
- <s:param name="first" value=http://www.mamicode.com/"3" />
- <s:param name="last" value=http://www.mamicode.com/"10" />
- <s:iterator>
- <s:property/>
- </s:iterator>
- </s:bean>
- <br/><br/>
- --循环标签②--
- <s:iterator begin="1" end="10">
- <s:property/>
- </s:iterator>
- <br/><br/>
- --迭代list--
- <!-- 等同于for(int i=1;i<=lstCity.size;i++) 标签同样从0开始计数 -->
- <s:iterator value=http://www.mamicode.com/"#request.lstCity" status="st" var="value" begin="1" end="#request.lstCity.length">
- [<s:property value=http://www.mamicode.com/"%{#attr.st.index+1}"/>]
- <s:property value=http://www.mamicode.com/"%{#attr.value.cityValue}"/>
- <!-- 或者使用EL表达式取值:${value.cityId} -->
- </s:iterator>
- </s:form>
- <s:debug></s:debug>
- </body>
- <tr>
- <td>生日:</td>
- <td>
- <!-- 在文本框中格式化时间 -->
- <s:textfield name="tagBean.birthday">
- <s:param name="value">
- <s:date name="tagBean.birthday" format="yyyy-MM-dd hh:MM:ss" />
- </s:param>
- </s:textfield>
- </td>
- <td>生日:</td>
- <!-- 时间标签,可以格式化滴 -->
- <td><s:date name="tagBean.birthday" format="yyyy年MM月dd日"></s:date></td>
- </tr>
- 拦截器
- <struts>
- <package name="bless-default" extends="struts-default" >
- <interceptors>
- <!--定义一个名为privilege的拦截器-->
- <interceptor
- class="....ExceptionHandler"
- name="exceptionInterceptor"/>
- <!--①定义一个包含异常处理的拦截器栈-->
- <interceptor-stack name="exceptionStack">
- <!-- 默认的拦截器 -->
- <interceptor-ref name="defaultStack"/>
- <!-- 异常拦截器 -->
- <interceptor-ref name="exceptionInterceptor"/>
- </interceptor-stack>
- <!-- ③需要用到chain跳转的拦截器栈 -->
- <interceptor-stack name="chainStack">
- <interceptor-ref name="chain"/>
- <interceptor-ref name="basicStack"/>
- <interceptor-ref name="exceptionInterceptor"/>
- </interceptor-stack>
- </interceptors>
- <!-- 默认运行的拦截器栈 -->
- <default-interceptor-ref name="exceptionStack" />
- <global-results>
- <result name="error" >/Web/common/page/error.jsp</result>
- </global-results>
- <global-exception-mappings>
- <exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
- </global-exception-mappings>
- </package>
- </struts>
- public class ExceptionHandler extends AbstractInterceptor {
- private static final long serialVersionUID = 1L;
- public String intercept(ActionInvocation actioninvocation) {
- String result = null; // Action的返回值
- try {
- // 运行被拦截的Action,期间如果发生异常会被catch住
- result = actioninvocation.invoke();
- return result;
- } catch (Exception e) {
- /**
- * 处理异常
- */
- String errorCode = null; // ospms的异常
- int errorId = -1; // 达运的异常
- if (e instanceof FunctionException) {
- // OSPMS异常
- FunctionException fe = (FunctionException) e;
- errorCode = fe.getErrorCode();
- fe.printStackTrace();
- }...........
- /**
- * 发送错误消息到页面
- */
- ...........
- /**
- * log4j记录日志
- */
- ...........
- return "error";
- }// ...end of catch
- }
- }
- 总结
Strurs2总结