Struts2简介:
主页:http://struts.apache.org/
在用户请求和模块化处理方面以及页面的展现这块,Struts2 发挥的屌炸天作用;
相对于传统的 Jsp+Servlet 模式,Struts2 更适合企业级团队开发,方便系统的维护;
废话不多说,直接先把框架搭好:
第一步:eclipse建立一个 web project,导入Struts2的8个核心包(选什么版本自己开心就好):
commons-fileupload-1.3.1.jar commons-io-2.2.jar commons-lang3-3.1.jar freemarker-2.3.19.jar
javassist-3.11.0.GA.jar ognl-3.0.6.jar struts2-core-2.3.16.3.jar xwork-core-2.3.16.3.jar
第二步:编写web.xml 加入Struts2的核心拦截器:
<filter>
<filter-name>Struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
第三步:编写struts.xml文件 及 HelloStruts测试类
struts.xml文件模板(以HelloStruts为例):
<?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> <package name="helloStruts" extends="struts-default"> <!-- helloStruts --> <action name="hello" class="com.tao.demo1.Demo1"> <result name="success">helloStruts.jsp</result> </action> </package> </struts>
Demo1(HelloStruts测试类):
package com.tao.demo1; import com.opensymphony.xwork2.ActionSupport; /** * * @author TaoGG * */ public class Demo1 extends ActionSupport{ private static final long serialVersionUID = 1L; @Override public String execute() throws Exception { return super.execute(); } }
访问项目:成功显示helloStruts.jsp 框架搭建成功。
关于Struts2的设值 取值问题:
1.单独属性的取值:
配置好struts.xml 表单填好 请求对应action 获取值。
下面例子类似 主要展示关键配置,看不懂请移步其他文章。
2.对象设置值:
3.模型驱动
优点:获取数据设置数据脱离Action
缺点:只能设置单一类型
4.数组类型的接收 前台传多个值时:
5.接收多个对象时对于集合类型的处理:
struts.xml文件配置:
1.分模块的配置
2.通配符的使用:
struts2还有一种动态方法调用 可以不用指定method,直接用 包名!方法名 就可以调用对应action;
不过可能存在sql注入的风险。
开启动态方法调用:<constant name="struts.enable.DynamicMethodInvocation" value="true" />
Action的生命周期:
Struts2的每一次请求会new 一个新的线程实例,所以不会有线程安全问题,但是会有资源浪费的情况。
关于Struts2的 result 配置:
1,type 默认是 dispatcher 内部转发; 2,type 为 redirect 重定向;
3,type 为 chain 链条;
4,type 为 redirectAction 重定向到 action; 上面 4 个常用,一定要掌握;其他 freemarker freemarker 模版
httpheader 返回一个已配置好的 HTTP 头信息响应 stream 将原始数据作为流传递回浏览器端, velocity 呈现 Velocity 模板
xslt 该 XML 可以通过 XSL 模板进行转换 plaintext 返回普通文本类容
package com.tao.struts01; import com.opensymphony.xwork2.Action; public class HelloStruts2 implements Action{ private String name; private String error; public String getError() { return error; } public void setError(String error) { this.error = error; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String execute() throws Exception { System.out.println("执行了Struts2的默认方法!"); if(name==null || "".equals(name)) { this.error="name为空"; return ERROR; } return SUCCESS; } /** *result 配置 type为内部转发的 默认就是转发 */ public String d() { return "d"; } /** *result 配置 type为重定向 */ public String r() { return "r"; } /** *result 配置 type为链条 */ public String c() { return "c"; } /** * result 配置 redirectAction 重定向到 action */ public String ra() { return "ra"; } }
package com.tao.struts01; import com.opensymphony.xwork2.ActionSupport; public class HelloStruts02 extends ActionSupport{ private static final long serialVersionUID = 1L; private String name2; public String getName2() { return name2; } public void setName2(String name2) { this.name2 = name2; } @Override public String execute() throws Exception { this.name2="你好啊!"; return super.execute(); } }
Struts2 拦截器:
Struts2 拦截器是在访问某个 Action 或 Action 的某个方法,字段之前或之后实施拦截,并且 Struts2 拦截器是可 插拔的,拦截器是AOP的一种实现.
优点:通用功能的封装,提供了可重用性;struts-default.xml文件:
<?xml version="1.0" encoding="UTF-8" ?> <!-- /* * $Id$ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ --> <!-- When declaring beans in this file you must either use name="struts" or don't name the bean at all. The name="struts" must be used when alias was defined in {@link org.apache.struts2.config.DefaultBeanSelectionProvider} - it is then the default bean's name and {@link org.apache.struts2.config.DefaultBeanSelectionProvider} links name "struts" with "default" (aliasing it) If name won't be defined then the "default" value will be used {@link com.opensymphony.xwork2.inject.Container#DEFAULT_NAME} and {@link com.opensymphony.xwork2.inject.Inject} --> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <bean class="com.opensymphony.xwork2.ObjectFactory" name="struts"/> <bean type="com.opensymphony.xwork2.factory.ResultFactory" name="struts" class="org.apache.struts2.factory.StrutsResultFactory" /> <bean type="com.opensymphony.xwork2.factory.ActionFactory" name="struts" class="com.opensymphony.xwork2.factory.DefaultActionFactory" /> <bean type="com.opensymphony.xwork2.factory.ConverterFactory" name="struts" class="com.opensymphony.xwork2.factory.DefaultConverterFactory" /> <bean type="com.opensymphony.xwork2.factory.InterceptorFactory" name="struts" class="com.opensymphony.xwork2.factory.DefaultInterceptorFactory" /> <bean type="com.opensymphony.xwork2.factory.ValidatorFactory" name="struts" class="com.opensymphony.xwork2.factory.DefaultValidatorFactory" /> <bean type="com.opensymphony.xwork2.FileManager" class="com.opensymphony.xwork2.util.fs.DefaultFileManager" name="system" scope="singleton"/> <bean type="com.opensymphony.xwork2.FileManagerFactory" class="com.opensymphony.xwork2.util.fs.DefaultFileManagerFactory" name="struts" scope="singleton"/> <bean type="com.opensymphony.xwork2.ActionProxyFactory" name="struts" class="org.apache.struts2.impl.StrutsActionProxyFactory"/> <bean type="com.opensymphony.xwork2.ActionProxyFactory" name="prefix" class="org.apache.struts2.impl.PrefixBasedActionProxyFactory"/> <bean type="com.opensymphony.xwork2.conversion.ObjectTypeDeterminer" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultObjectTypeDeterminer"/> <bean type="com.opensymphony.xwork2.util.PatternMatcher" name="struts" class="com.opensymphony.xwork2.util.WildcardHelper" /> <bean type="com.opensymphony.xwork2.util.PatternMatcher" name="namedVariable" class="com.opensymphony.xwork2.util.NamedVariablePatternMatcher"/> <bean type="com.opensymphony.xwork2.util.PatternMatcher" name="regex" class="org.apache.struts2.util.RegexPatternMatcher"/> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="struts" class="org.apache.struts2.dispatcher.mapper.DefaultActionMapper" /> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="composite" class="org.apache.struts2.dispatcher.mapper.CompositeActionMapper" /> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful" class="org.apache.struts2.dispatcher.mapper.RestfulActionMapper" /> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="restful2" class="org.apache.struts2.dispatcher.mapper.Restful2ActionMapper" /> <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="jakarta" class="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest" scope="default"/> <bean type="org.apache.struts2.views.TagLibraryDirectiveProvider" name="s" class="org.apache.struts2.views.DefaultTagLibrary" /> <bean type="org.apache.struts2.views.TagLibraryModelProvider" name="s" class="org.apache.struts2.views.DefaultTagLibrary" /> <bean class="org.apache.struts2.views.freemarker.FreemarkerThemeTemplateLoader" /> <bean class="org.apache.struts2.views.freemarker.FreemarkerManager" name="struts" /> <bean class="org.apache.struts2.views.velocity.VelocityManager" name="struts" optional="true" /> <bean class="org.apache.struts2.components.template.TemplateEngineManager" /> <bean type="org.apache.struts2.components.template.TemplateEngine" name="ftl" class="org.apache.struts2.components.template.FreemarkerTemplateEngine" /> <bean type="org.apache.struts2.components.template.TemplateEngine" name="vm" class="org.apache.struts2.components.template.VelocityTemplateEngine" /> <bean type="org.apache.struts2.components.template.TemplateEngine" name="jsp" class="org.apache.struts2.components.template.JspTemplateEngine" /> <bean type="com.opensymphony.xwork2.conversion.impl.XWorkConverter" name="struts" class="com.opensymphony.xwork2.conversion.impl.XWorkConverter" /> <bean type="com.opensymphony.xwork2.conversion.ConversionPropertiesProcessor" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor" /> <bean type="com.opensymphony.xwork2.conversion.ConversionFileProcessor" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionFileProcessor" /> <bean type="com.opensymphony.xwork2.conversion.ConversionAnnotationProcessor" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultConversionAnnotationProcessor" /> <bean type="com.opensymphony.xwork2.conversion.TypeConverterCreator" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterCreator" /> <bean type="com.opensymphony.xwork2.conversion.TypeConverterHolder" name="struts" class="com.opensymphony.xwork2.conversion.impl.DefaultTypeConverterHolder" /> <bean class="com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter" /> <bean type="com.opensymphony.xwork2.conversion.impl.CollectionConverter" name="struts" class="com.opensymphony.xwork2.conversion.impl.CollectionConverter" scope="singleton"/> <bean type="com.opensymphony.xwork2.conversion.impl.ArrayConverter" name="struts" class="com.opensymphony.xwork2.conversion.impl.ArrayConverter" scope="singleton"/> <bean type="com.opensymphony.xwork2.conversion.impl.DateConverter" name="struts" class="com.opensymphony.xwork2.conversion.impl.DateConverter" scope="singleton"/> <bean type="com.opensymphony.xwork2.conversion.impl.NumberConverter" name="struts" class="com.opensymphony.xwork2.conversion.impl.NumberConverter" scope="singleton"/> <bean type="com.opensymphony.xwork2.conversion.impl.StringConverter" name="struts" class="com.opensymphony.xwork2.conversion.impl.StringConverter" scope="singleton"/> <bean type="com.opensymphony.xwork2.TextProvider" name="struts" class="com.opensymphony.xwork2.TextProviderSupport" scope="default" /> <bean type="com.opensymphony.xwork2.LocaleProvider" name="struts" class="com.opensymphony.xwork2.DefaultLocaleProvider" scope="singleton" /> <bean type="org.apache.struts2.components.UrlRenderer" name="struts" class="org.apache.struts2.components.ServletUrlRenderer"/> <bean type="org.apache.struts2.views.util.UrlHelper" name="struts" class="org.apache.struts2.views.util.DefaultUrlHelper"/> <bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="struts" class="com.opensymphony.xwork2.ognl.OgnlValueStackFactory" /> <bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="struts" class="com.opensymphony.xwork2.ognl.OgnlReflectionProvider" /> <bean type="com.opensymphony.xwork2.util.reflection.ReflectionContextFactory" name="struts" class="com.opensymphony.xwork2.ognl.OgnlReflectionContextFactory" /> <bean type="com.opensymphony.xwork2.TextProvider" name="system" class="com.opensymphony.xwork2.DefaultTextProvider" /> <bean type="com.opensymphony.xwork2.conversion.NullHandler" name="java.lang.Object" class="com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler" /> <bean type="com.opensymphony.xwork2.validator.ActionValidatorManager" name="struts" class="com.opensymphony.xwork2.validator.AnnotationActionValidatorManager" /> <bean type="com.opensymphony.xwork2.validator.ActionValidatorManager" name="no-annotations" class="com.opensymphony.xwork2.validator.DefaultActionValidatorManager" /> <bean type="com.opensymphony.xwork2.validator.ValidatorFactory" class="com.opensymphony.xwork2.validator.DefaultValidatorFactory"/> <bean type="com.opensymphony.xwork2.validator.ValidatorFileParser" class="com.opensymphony.xwork2.validator.DefaultValidatorFileParser" /> <bean class="com.opensymphony.xwork2.ognl.OgnlUtil" /> <bean type="com.opensymphony.xwork2.util.TextParser" name="struts" class="com.opensymphony.xwork2.util.OgnlTextParser" scope="singleton"/> <bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" /> <bean type="ognl.PropertyAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.ObjectAccessor" /> <bean type="ognl.PropertyAccessor" name="java.util.Iterator" class="com.opensymphony.xwork2.ognl.accessor.XWorkIteratorPropertyAccessor" /> <bean type="ognl.PropertyAccessor" name="java.util.Enumeration" class="com.opensymphony.xwork2.ognl.accessor.XWorkEnumerationAccessor" /> <bean type="ognl.PropertyAccessor" name="java.util.List" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" /> <bean type="ognl.PropertyAccessor" name="java.util.Set" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" /> <bean type="ognl.PropertyAccessor" name="java.util.Map" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" /> <bean type="ognl.PropertyAccessor" name="java.util.Collection" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" /> <bean type="ognl.PropertyAccessor" name="com.opensymphony.xwork2.ognl.ObjectProxy" class="com.opensymphony.xwork2.ognl.accessor.ObjectProxyPropertyAccessor" /> <bean type="ognl.MethodAccessor" name="java.lang.Object" class="com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor" /> <bean type="ognl.MethodAccessor" name="com.opensymphony.xwork2.util.CompoundRoot" class="com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor" /> <bean class="org.apache.struts2.views.jsp.ui.OgnlTool" /> <bean type="org.apache.struts2.dispatcher.StaticContentLoader" class="org.apache.struts2.dispatcher.DefaultStaticContentLoader" name="struts" /> <bean type="com.opensymphony.xwork2.UnknownHandlerManager" class="com.opensymphony.xwork2.DefaultUnknownHandlerManager" name="struts" /> <!-- Silly workarounds for OGNL since there is currently no way to flush its internal caches --> <bean type="ognl.PropertyAccessor" name="java.util.ArrayList" class="com.opensymphony.xwork2.ognl.accessor.XWorkListPropertyAccessor" /> <bean type="ognl.PropertyAccessor" name="java.util.HashSet" class="com.opensymphony.xwork2.ognl.accessor.XWorkCollectionPropertyAccessor" /> <bean type="ognl.PropertyAccessor" name="java.util.HashMap" class="com.opensymphony.xwork2.ognl.accessor.XWorkMapPropertyAccessor" /> <package name="struts-default" abstract="true"> <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/> <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/> <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/> <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/> <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/> <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/> <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/> <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/> <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" /> <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" /> </result-types> <interceptors> <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/> <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/> <interceptor name="chain" class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/> <interceptor name="conversionError" class="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor"/> <interceptor name="cookie" class="org.apache.struts2.interceptor.CookieInterceptor"/> <interceptor name="cookieProvider" class="org.apache.struts2.interceptor.CookieProviderInterceptor"/> <interceptor name="clearSession" class="org.apache.struts2.interceptor.ClearSessionInterceptor" /> <interceptor name="createSession" class="org.apache.struts2.interceptor.CreateSessionInterceptor" /> <interceptor name="debugging" class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" /> <interceptor name="execAndWait" class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/> <interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/> <interceptor name="fileUpload" class="org.apache.struts2.interceptor.FileUploadInterceptor"/> <interceptor name="i18n" class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/> <interceptor name="logger" class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/> <interceptor name="modelDriven" class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> <interceptor name="scopedModelDriven" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor"/> <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/> <interceptor name="actionMappingParams" class="org.apache.struts2.interceptor.ActionMappingParametersInteceptor"/> <interceptor name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/> <interceptor name="staticParams" class="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor"/> <interceptor name="scope" class="org.apache.struts2.interceptor.ScopeInterceptor"/> <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/> <interceptor name="timer" class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/> <interceptor name="token" class="org.apache.struts2.interceptor.TokenInterceptor"/> <interceptor name="tokenSession" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/> <interceptor name="validation" class="org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor"/> <interceptor name="workflow" class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor"/> <interceptor name="store" class="org.apache.struts2.interceptor.MessageStoreInterceptor" /> <interceptor name="checkbox" class="org.apache.struts2.interceptor.CheckboxInterceptor" /> <interceptor name="profiling" class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" /> <interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor" /> <interceptor name="annotationWorkflow" class="com.opensymphony.xwork2.interceptor.annotations.AnnotationWorkflowInterceptor" /> <interceptor name="multiselect" class="org.apache.struts2.interceptor.MultiselectInterceptor" /> <interceptor name="deprecation" class="org.apache.struts2.interceptor.DeprecationInterceptor" /> <!-- Basic stack --> <interceptor-stack name="basicStack"> <interceptor-ref name="exception"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="deprecation"/> </interceptor-stack> <!-- Sample validation and workflow stack --> <interceptor-stack name="validationWorkflowStack"> <interceptor-ref name="basicStack"/> <interceptor-ref name="validation"/> <interceptor-ref name="workflow"/> </interceptor-stack> <!-- Sample file upload stack --> <interceptor-stack name="fileUploadStack"> <interceptor-ref name="fileUpload"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample model-driven stack --> <interceptor-stack name="modelDrivenStack"> <interceptor-ref name="modelDriven"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample action chaining stack --> <interceptor-stack name="chainStack"> <interceptor-ref name="chain"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- Sample i18n stack --> <interceptor-stack name="i18nStack"> <interceptor-ref name="i18n"/> <interceptor-ref name="basicStack"/> </interceptor-stack> <!-- An example of the paramsPrepareParams trick. This stack is exactly the same as the defaultStack, except that it includes one extra interceptor before the prepare interceptor: the params interceptor. This is useful for when you wish to apply parameters directly to an object that you wish to load externally (such as a DAO or database or service layer), but can't load that object until at least the ID parameter has been loaded. By loading the parameters twice, you can retrieve the object in the prepare() method, allowing the second params interceptor to apply the values on the object. --> <interceptor-stack name="paramsPrepareParamsStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="i18n"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="params"> <param name="excludeParams">^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="servletConfig"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> </interceptor-stack> <!-- A complete stack with all the common interceptors in place. Generally, this stack should be the one you use, though it may do more than you need. Also, the ordering can be switched around (ex: if you wish to have your servlet-related objects applied before prepare() is called, you'd need to move servletConfig interceptor up. This stack also excludes from the normal validation and workflow the method names input, back, and cancel. These typically are associated with requests that should not be validated. --> <interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="i18n"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"> <param name="excludeParams">^action:.*,^method:.*</param> </interceptor-ref> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="debugging"/> <interceptor-ref name="deprecation"/> </interceptor-stack> <!-- The completeStack is here for backwards compatibility for applications that still refer to the defaultStack by the old name --> <interceptor-stack name="completeStack"> <interceptor-ref name="defaultStack"/> </interceptor-stack> <!-- Sample execute and wait stack. Note: execAndWait should always be the *last* interceptor. --> <interceptor-stack name="executeAndWaitStack"> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> <interceptor-ref name="defaultStack"/> <interceptor-ref name="execAndWait"> <param name="excludeMethods">input,back,cancel</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultStack"/> <default-class-ref class="com.opensymphony.xwork2.ActionSupport" /> </package> </struts>
简单拦截器实例:
业务场景:用户登录后才可以看到角色列表,否则提示错误信息。
分析:登陆后将用户信息放置session,进行角色列表请求时拦截 session中没有用户信息就拦截,有就放行。
//登录界面: <form action="user/user_login" method="post"> <table> <tr> <td>用户名:</td> <td><input type="text" name="user.userName"></td> </tr> <tr> <td>密 码:</td> <td><input type="password" name="user.passWord"></td> </tr> <tr> <td><input type="submit" value="登录"></td> <td><input type="button" value="重置"></td> </tr> </table> </form>
错误页面: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 错误信息:${errorMsg}<br /> <a href="${pageContext.request.contextPath}/userLogin.jsp">返回登陆界面</a> </body> </html>
用户的struts.xml配置 <struts> <package name="user" namespace="/user" extends="struts-default"> <!-- 全局错误配置 --> <global-results> <result name="error">${pageContext.request.contextPath}/error.jsp</result> </global-results> <!-- 用户列表展示处理 --> <action name="user_*" class="com.tao.user.UserAction" method="{1}"> <result name="success">${pageContext.request.contextPath}/success.jsp</result> </action> </package> </struts>
角色的struts.xml配置: <struts> <package name="role" extends="struts-default" namespace="/role"> <!-- 拦截器配置 --> <interceptors> <!-- 自定义拦截器 --> <interceptor name="LoginInterceptor" class="com.tao.interceptor.LoginInterceptor"></interceptor> <!-- 拦截器栈(只会包含你引用的拦截器 我们这边只有一个 所有要把默认拦截器也添加进去) --> <interceptor-stack name="myStack"> <interceptor-ref name="LoginInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- 修改默认引用拦截器配置 引用自己的拦截器栈 如果哪个action 不想用自己的拦截器栈 那就直接引用系统默认的--> <default-interceptor-ref name="myStack"></default-interceptor-ref> <!-- 全局错误统一配置 --> <global-results> <result name="error">${pageContext.request.contextPath}/error.jsp</result> </global-results> <action name="role_*" class="com.tao.role.RoleAction" method="{1}"> <result name="success">${pageContext.request.contextPath}/success.jsp</result> </action> </package> </struts>
用户拦截器: public class UserAction extends ActionSupport{ private User user; private String errorMsg; public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } private static final long serialVersionUID = 1L; //展示所有用户的方法 public String list(){ System.out.println("执行了UserAction的默认方法"); return SUCCESS; } public String login(){ if("admin".equals(user.getUserName()) && "admin".equals(user.getPassWord())){ Map<String, Object> session = ActionContext.getContext().getSession(); session.put("currentUser", user); return SUCCESS; }else{ this.errorMsg = "用户名或密码错误,请重新输入"; return ERROR; } } }
登录拦截器: public class LoginInterceptor implements Interceptor{ private static final long serialVersionUID = 1L; @Override public void destroy() { System.out.println("登录拦截器销毁"); } @Override public void init() { System.out.println("登录拦截器初始化"); } @Override public String intercept(ActionInvocation invocation) throws Exception { ActionContext actionContext = invocation.getInvocationContext(); //获取session Map<String, Object> session = actionContext.getSession(); Object currentUser = session.get("currentUser"); String result = null; if(currentUser!=null){ result = invocation.invoke(); }else{ //获取ServletRequest HttpServletRequest request= (HttpServletRequest) actionContext.get(ServletActionContext.HTTP_REQUEST); request.setAttribute("errorMsg", "请先登录"); result = "error"; } return result; } }
角色的Action: public class RoleAction extends ActionSupport{ private static final long serialVersionUID = 1L; //角色列表查看功能 public String list() throws Exception { System.out.println("查看了角色列表"); return super.execute(); } }
登录成功后才可访问到roleAction的list 方法 否则拦截 跳转错误页面 显示错误信息。
Struts值栈与OGNL表达式:
值栈是对应每个请求对象的一套内存数据的封装,Struts2 会给每个请求创建一个新的值栈。
值栈能够线程安全地为每个请求提供公共的数据存取服务。OGNL 是对象图导航语言 Object-Graph Navigation Language 的缩写,它是一种功能强大的表达式语言。
OGNL 访问 ValueStack 数据
<s:property value=”account” />
OGNL 访问 ActionContext 数据
访问某个范围下的数据要用#
#parameters 请求参数 request.getParameter(...);
#request 请求作用域中的数据 request.getAttribute(...);
#session 会话作用域中的数据 session.getAttribute(...);
#application 应用程序作用域中的数据 application.getAttribute(...);
#attr 按照 page request session application 顺序查找值
后台action方法:
前台取值:
OGNL 访问复杂对象:
1,访问 javaBean 对象;
2,访问集合对象;
3,访问 Map 对象;后台Action定义对象 集合 Map 并提供get set方法
进行赋值操作:
前台获取:
OGNL 访问静态方法和属性:
自定义一个类:
前台取值:<s:property value="@类完整路径名@属性名/方法名"/>
注意 strtus默认不允许访问静态方法,需要在strtus.xml中配置开启:
1、条件标签:用于执行基本的条件流转
<s:if>拥有一个test属性,其表达式的值用来决定标签里的内容是否显示,
<s:if test="#request.username=='hzd'">北京欢迎你</s:if> <selseif test="#request.username=='清风'">上海欢迎你</s:elseif> <s:else>同上
2、迭代标签:用于遍历集合(java.util.Collection)或者枚举值(java.util.Iterator)类型的对象,value属性表示集合或枚举对象,status属性表示当前循环的对象,在循环体内部可以引用该对象的属性
<s:iterator value="userList" status="user"> 姓名:<s:property value="user.userName" /> 年龄:<s:property value="user.age" /> </s:iterator>3、组合标签:用于将多个枚举值对象进行叠加,形成一个新的枚举值列表,如将3个列表对象进行了组合,形成新的列表对象
<s:append var="newIteratorList"> <s:param value="%{myList1}" /> <s:param value="%{myList2}" /> <s:param value="%{myList3}" /> </s:append> 输出: <s:iterator value="%{#newIteratorList}"> <s:property /> </s:iterator>4、分割标签:用于将一个字符串进行分割,产生一个枚举值列表,下面的代码将分割成三个字符串,然后输出
<s:generator val="%{'aaa,bbb,ccc'}"> <s:iterator> <s:property /> </s:iterator> </s:generator>5、合并标签;用于将多个枚举值按照数组的索引位置进行合并
<s:merge var="newMergeList"> <s:param value="%{mylist1}">--设mylist1列表中有a,b,c三个元素 <s:param value="%{mylist2}">--设mylist2列表中有1,2,3三个元素 </s:merge> 合并后新的列表的元素及其顺序为:a,1,b,2,c,3 <s:iterator value="%{#newMergeList}"> <s:property /> </s:iterator>6、排序标签:用于对一组枚举值进行排序,属性comparator指向一个继承java.util.Comparator的比较器,该比较器可以是对action页面中的一个比较器变量,source指定要排序的列表对象
<s:sort comparator="myComparator" source="myList"> <s:iterator> <s:property value="..."/> </s:iterator> </s:sort>7、子集标签;用于取得一个枚举列表的子集,source用于指定检索的列表对象,start用于指定起始检索的索引位置,count用于指定检索的结果输数量,decider属性必须是一个org.apache.struts2.util.SubsetIteratorFilter.Decider类的子类实例,用以指定检索的条件。例如在Action中提供了以下方法用来取得一个Decider对象:
public Decider getDecider(){ return new Decider(){ public boolean decide(Object element) throws Exception{ int i=((Integer)element).intValue(); return (((i%2)==0)?true:false); } }; } 然后引用该对象筛选子集: <s:subset source="myList" decider="decider"> </s:subset> 或者不使用Decider对象: <s:subset source="myList" count="13" start="3"> </s:subset>