Struts2之Action与配置文件
一.Struts2配置文件
1.struts.properties
在学习Action之前先学下Struts2的配置文件,与Struts2相关的配置文件有好几个,常用的有Struts.xml,web.xml,这两个在MyStruts2的项目中也有使用,其实还有一个可选的配置文件,主要配置Struts2的一些属性,struts.properties.它主要用来配置一些参数,每个可配置的参数都有默认值,如无需修改修改参数任何值,可不添加。默认属性位于包org/apache/struts2下的default.properyies.用户可以在WEB-INF/classes下创建struts.properties覆盖默认的属性。
# # $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. # ### START SNIPPET: complete_file ### Struts default properties ###(can be overridden by a struts.properties file in the root of the classpath) ### ### This can be used to set your default locale and encoding scheme # struts.locale=en_US struts.i18n.encoding=UTF-8 ### if specified, the default object factory can be overridden here ### Note: short-hand notation is supported in some cases, such as "spring" ### Alternatively, you can provide a com.opensymphony.xwork2.ObjectFactory subclass name here # struts.objectFactory = spring ### specifies the autoWiring logic when using the SpringObjectFactory. ### valid values are: name, type, auto, and constructor (name is the default) struts.objectFactory.spring.autoWire = name ### indicates to the struts-spring integration if Class instances should be cached ### this should, until a future Spring release makes it possible, be left as true ### unless you know exactly what you are doing! ### valid values are: true, false (true is the default) struts.objectFactory.spring.useClassCache = true ### ensures the autowire strategy is always respected. ### valid values are: true, false (false is the default) struts.objectFactory.spring.autoWire.alwaysRespect = false ### By default SpringObjectFactory doesn't support AOP ### This flag was added just temporally to check if nothing is broken ### See https://issues.apache.org/jira/browse/WW-4110 struts.objectFactory.spring.enableAopSupport = false ### if specified, the default object type determiner can be overridden here ### Note: short-hand notation is supported in some cases, such as "tiger" or "notiger" ### Alternatively, you can provide a com.opensymphony.xwork2.util.ObjectTypeDeterminer implementation name here ### Note: By default, com.opensymphony.xwork2.util.DefaultObjectTypeDeterminer is used which handles type detection ### using generics. com.opensymphony.xwork2.util.GenericsObjectTypeDeterminer was deprecated since XWork 2, it's ### functions are integrated in DefaultObjectTypeDeterminer now. ### To disable tiger support use the "notiger" property value here. #struts.objectTypeDeterminer = tiger #struts.objectTypeDeterminer = notiger ### Parser to handle HTTP POST requests, encoded using the MIME-type multipart/form-data # struts.multipart.parser=cos # struts.multipart.parser=pell # struts.multipart.parser=jakarta-stream struts.multipart.parser=jakarta # uses javax.servlet.context.tempdir by default struts.multipart.saveDir= struts.multipart.maxSize=2097152 ### Load custom property files (does not override struts.properties!) # struts.custom.properties=application,org/apache/struts2/extension/custom ### How request URLs are mapped to and from actions #struts.mapper.class=org.apache.struts2.dispatcher.mapper.DefaultActionMapper ### Used by the DefaultActionMapper ### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp,do ### The blank extension allows you to match directory listings as well as pure action names ### without interfering with static resources, which can be specified as an empty string ### prior to a comma e.g. struts.action.extension=, or struts.action.extension=x,y,z,, struts.action.extension=action,, ### Used by FilterDispatcher ### If true then Struts serves static content from inside its jar. ### If false then the static content must be available at <context_path>/struts struts.serve.static=true ### Used by FilterDispatcher ### This is good for development where one wants changes to the static content be ### fetch on each request. ### NOTE: This will only have effect if struts.serve.static=true ### If true -> Struts will write out header for static contents such that they will ### be cached by web browsers (using Date, Cache-Content, Pragma, Expires) ### headers). ### If false -> Struts will write out header for static contents such that they are ### NOT to be cached by web browser (using Cache-Content, Pragma, Expires ### headers) struts.serve.static.browserCache=true ### Set this to false if you wish to disable implicit dynamic method invocation ### via the URL request. This includes URLs like foo!bar.action, as well as params ### like method:bar (but not action:foo). ### An alternative to implicit dynamic method invocation is to use wildcard ### mappings, such as <action name="*/*" method="{2}" class="actions.{1}"> struts.enable.DynamicMethodInvocation = false ### Set this to true if you wish to allow slashes in your action names. If false, ### Actions names cannot have slashes, and will be accessible via any directory ### prefix. This is the traditional behavior expected of WebWork applications. ### Setting to true is useful when you want to use wildcards and store values ### in the URL, to be extracted by wildcard patterns, such as ### <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or ### "/foo/save". struts.enable.SlashesInActionNames = false ### Disables support for action: prefix struts.mapper.action.prefix.enabled = false ### Blocks access to actions in other namespace than current with action: prefix struts.mapper.action.prefix.crossNamespaces = false ### use alternative syntax that requires %{} in most places ### to evaluate expressions for String attributes for tags struts.tag.altSyntax=true ### when set to true, Struts will act much more friendly for developers. This ### includes: ### - struts.i18n.reload = true ### - struts.configuration.xml.reload = true ### - raising various debug or ignorable problems to errors ### For example: normally a request to foo.action?someUnknownField=true should ### be ignored (given that any value can come from the web and it ### should not be trusted). However, during development, it may be ### useful to know when these errors are happening and be told of ### them right away. struts.devMode = false ### when set to true, resource bundles will be reloaded on _every_ request. ### this is good during development, but should never be used in production ### struts.i18n.reload=false ### Standard UI theme ### Change this to reflect which path should be used for JSP control tag templates by default struts.ui.theme=xhtml struts.ui.templateDir=template ### Change this to use a different token to indicate template theme expansion struts.ui.theme.expansion.token=~~~ #sets the default template type. Either ftl, vm, or jsp struts.ui.templateSuffix=ftl ### Configuration reloading ### This will cause the configuration to reload struts.xml when it is changed ### struts.configuration.xml.reload=false ### Location of velocity.properties file. defaults to velocity.properties struts.velocity.configfile = velocity.properties ### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext struts.velocity.contexts = ### Location of the velocity toolbox struts.velocity.toolboxlocation= ### used to build URLs, such as the UrlTag struts.url.http.port = 80 struts.url.https.port = 443 ### possible values are: none, get or all struts.url.includeParams = none ### Load custom default resource bundles # struts.custom.i18n.resources=testmessages,testmessages2 ### workaround for some app servers that don't handle HttpServletRequest.getParameterMap() ### often used for WebLogic, Orion, and OC4J struts.dispatcher.parametersWorkaround = false ### configure the Freemarker Manager class to be used ### Allows user to plug-in customised Freemarker Manager if necessary ### MUST extends off org.apache.struts2.views.freemarker.FreemarkerManager #struts.freemarker.manager.classname=org.apache.struts2.views.freemarker.FreemarkerManager ### Enables caching of FreeMarker templates ### Has the same effect as copying the templates under WEB_APP/templates ### struts.freemarker.templatesCache=false ### Enables caching of models on the BeanWrapper struts.freemarker.beanwrapperCache=false ### See the StrutsBeanWrapper javadocs for more information struts.freemarker.wrapper.altMap=true ### maxStrongSize for MruCacheStorage for freemarker, when set to 0 SoftCacheStorage which performs better in heavy loaded application ### check WW-3766 for more details struts.freemarker.mru.max.strong.size=0 ### configure the XSLTResult class to use stylesheet caching. ### Set to true for developers and false for production. struts.xslt.nocache=false ### Whether to always select the namespace to be everything before the last slash or not struts.mapper.alwaysSelectFullNamespace=false ### Whether to allow static method access in OGNL expressions or not struts.ognl.allowStaticMethodAccess=false ### Whether to throw a RuntimeException when a property is not found ### in an expression, or when the expression evaluation fails struts.el.throwExceptionOnFailure=false ### Logs as Warnings properties that are not found (very verbose) struts.ognl.logMissingProperties=false ### Caches parsed OGNL expressions, but can lead to memory leaks ### if the application generates a lot of different expressions struts.ognl.enableExpressionCache=true ### Indicates if Dispatcher should handle unexpected exceptions by calling sendError() ### or simply rethrow it as a ServletException to allow future processing by other frameworks like Spring Security struts.handle.exception=true ### END SNIPPET: complete_file
2.struts.xml
struts.xml里面配置Action、JSP、Exception、Intercepter等。struts.properties的配置也可以配置在里面。下面的struts.xml是struts2.5中demo自带的配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN" "http://struts.apache.org/dtds/struts-2.5.dtd"> <!-- START SNIPPET: xworkSample --> <struts> <!-- Some or all of these can be flipped to true for debugging --> <constant name="struts.i18n.reload" value="false" /> <constant name="struts.enable.DynamicMethodInvocation" value="true" /> <constant name="struts.devMode" value="false" /> <constant name="struts.configuration.xml.reload" value="false" /> <constant name="struts.custom.i18n.resources" value="globalMessages" /> <constant name="struts.action.extension" value="action,," /> <constant name="struts.convention.package.locators.basePackage" value="org.apache.struts2.showcase" /> <constant name="struts.convention.result.path" value="/WEB-INF" /> <!-- Necessary for Showcase because default includes org.apache.struts2.* --> <constant name="struts.convention.exclude.packages" value="org.apache.struts.*,org.springframework.web.struts.*,org.springframework.web.struts2.*,org.hibernate.*"/> <constant name="struts.freemarker.manager.classname" value="customFreemarkerManager" /> <constant name="struts.serve.static" value="true" /> <constant name="struts.serve.static.browserCache" value="false" /> <include file="struts-interactive.xml" /> <include file="struts-hangman.xml" /> <include file="struts-tags.xml"/> <include file="struts-validation.xml" /> <include file="struts-actionchaining.xml" /> <include file="struts-fileupload.xml" /> <include file="struts-person.xml" /> <include file="struts-wait.xml" /> <include file="struts-token.xml" /> <include file="struts-model-driven.xml" /> <include file="struts-filedownload.xml" /> <include file="struts-conversion.xml" /> <include file="struts-freemarker.xml" /> <include file="struts-tiles.xml" /> <include file="struts-xslt.xml" /> <package name="default" extends="struts-default"> <interceptors> <interceptor-stack name="crudStack"> <interceptor-ref name="checkbox" /> <interceptor-ref name="params" /> <interceptor-ref name="staticParams" /> <interceptor-ref name="defaultStack" /> </interceptor-stack> </interceptors> <default-action-ref name="showcase" /> <action name="showcase"> <result>/WEB-INF/showcase.jsp</result> </action> <action name="help"> <result>/WEB-INF/help.jsp</result> </action> <action name="viewSource" class="org.apache.struts2.showcase.source.ViewSourceAction"> <result>/WEB-INF/viewSource.jsp</result> </action> <action name="date" class="org.apache.struts2.showcase.DateAction" method="browse"> <result name="success">/WEB-INF/date.jsp</result> </action> </package> <package name="skill" extends="default" namespace="/skill"> <default-interceptor-ref name="crudStack"/> <action name="list" class="org.apache.struts2.showcase.action.SkillAction" method="list"> <result>/WEB-INF/empmanager/listSkills.jsp</result> <interceptor-ref name="basicStack"/> </action> <action name="edit" class="org.apache.struts2.showcase.action.SkillAction"> <result>/WEB-INF/empmanager/editSkill.jsp</result> <interceptor-ref name="params" /> <interceptor-ref name="basicStack"/> </action> <action name="save" class="org.apache.struts2.showcase.action.SkillAction" method="save"> <result name="input">/WEB-INF/empmanager/editSkill.jsp</result> <result type="redirect">list.action</result> </action> <action name="delete" class="org.apache.struts2.showcase.action.SkillAction" method="delete"> <result name="error">/WEB-INF/empmanager/editSkill.jsp</result> <result type="redirect">list.action</result> </action> </package> <package name="employee" extends="default" namespace="/employee"> <default-interceptor-ref name="crudStack"/> <action name="list" class="org.apache.struts2.showcase.action.EmployeeAction" method="list"> <result>/WEB-INF/empmanager/listEmployees.jsp</result> <interceptor-ref name="basicStack"/> </action> <action name="edit-*" class="org.apache.struts2.showcase.action.EmployeeAction"> <param name="empId">{1}</param> <result>/WEB-INF/empmanager/editEmployee.jsp</result> <interceptor-ref name="crudStack"><param name="validation.excludeMethods">execute</param></interceptor-ref> </action> <action name="save" class="org.apache.struts2.showcase.action.EmployeeAction" method="save"> <result name="input">/WEB-INF/empmanager/editEmployee.jsp</result> <result type="redirect">list.action</result> </action> <action name="delete" class="org.apache.struts2.showcase.action.EmployeeAction" method="delete"> <result name="error">/WEB-INF/empmanager/editEmployee.jsp</result> <result type="redirect">list.action</result> </action> </package> </struts> <!-- END SNIPPET: xworkSample -->
<constant>配置struts2的属性,与struts.properties一样。<include>配置多个struts.xml文件,每个都是独立的,作用格式与struts.xml一样。也要有<!DOCTYPE>和根元素<struts>。package里面配置action等。也可以使用<bean>配置POJO类。
3.配置package
Struts2的Action、JSP等都配置在package中,<package>类似于对象,具有可继承性,默认继承struts-default,name属性指定名称,用于继承时引用。如果子package继承父package,子package可以引用父package的所有资源,也可以重新定义一些资源。package还可以配置命名空间,如配置了命名空间,访问时需加上namespace/*.action.
二、Action
一、Action的形式
Struts2中Action的实现方式有几种,比较灵活。
1.继承ActionSupport类
自定义Action一般直接继承ActionSupport,并定义变量,重写execute(),变量的值会被Struts2通过setter自动赋值,execute()直接使用,返回值为<result>配置。ActionSupport中实现了其他方法,继承它可直接使用数据校验等Struts2集成的方法。
2.实现Action接口
其实ActionSupport是实现Action接口,所以自定义Action也可以直接实现Action接口,只是Action接口里只有一个execute(),以及几个常用的结果名称(success、none、error、input、login等)。
3.不继承任何类的Action
Struts2的Action并不一定实现Action接口,任何的POJO都可以做Action,只要这个Action具有public String execute()方法。如果Struts2发现没有实现Action接口,会通过反射来调用execute()方法。
二、Action的可执行方法
execute()是Action的默认方法,它也可执行其他方法,只要方法没有参数,返回值String类型,里面可以有throw声明也可以没有,Struts2会在运行时根据方法特征判断是否是可执行方法(返回值、参数),并通过反射执行。
三、Action方法的执行
1.通过URL执行
执行非默认方法,可以使用action!method.action的URL形式访问,action为struts.xml中配置的Action名字,method为Action的方法名,中间用!隔开。
2.将执行方法配置到action
也可以把方法用method配置到action中,省去!符号,这时的Action名称可以随便指定,也可以为每个方法定义一种action,然后使用action名称对应的访问方式访问Action。这样就是同一个action需要重复配置多次。
四、Action中使用POJO
上面的都是理论,下面通过例子来验证上面的理论。
1.创建POJO,这里把model和action的操作分离开来,建了两个类一个User一个UserAction。
package com.cyw.test; import java.util.Date; public class User { private String name; private int age; private Date birthDay; public Date getBirthDay() { return birthDay; } public void setBirthDay(Date birthDay) { this.birthDay = birthDay; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
package com.cyw.test; import java.util.*; public class UserAction { private static List<User> userList=new ArrayList<User>(); public List<User> getUserList() { return userList; } private String title; private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String initAdd() { return "initAdd"; } public String Add() { userList.add(user); setTitle("添加成功"); return "list"; } public String list() { return "list"; } public String clear() { userList.clear(); setTitle("清除"); return "list"; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
2.在Struts.xml中增加配置
<package name="user" extends="struts-default"> <action name="*User" class="com.cyw.test.UserAction" method="{1}" > <result name="list">/listuser.jsp</result> <result name="initAdd">/inituser.jsp</result> <allowed-methods>initAdd,Add,list,clear</allowed-methods> <!-- <allowed-methods>*</allowed-methods> --> </action> </package>
这里有一个坑看网上使用通配符配置的时候总是提示找不到对应的action,这个问题纠结了好久,费了好久时间才找到原因,原来是struts2版本的问题,我用的是2.5的,在使用通配符时,需要使用<allowed-methods>来配置下允许访问的方法,使用<allowed-methods>*</allowed-methods>都不行。
3.创建listuser.jsp、inituser.jsp页面,一个用来提交表单,一个用来显示列表。
inituser.jsp页面提交表单数据
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="struts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<struts:a href="addUser.action">添加用户</struts:a>
<struts:a href="listUser">用户列表</struts:a>
<struts:a href="clearUser">清空用户</struts:a>
<struts:form action="AddUser">
<struts:textfield name="user.name" label="姓名"></struts:textfield>
<struts:textfield name="user.age" label="年龄"></struts:textfield>
<struts:textfield name="user.birthDay" label="出生日期"></struts:textfield>
<struts:submit value="添加"></struts:submit>
</struts:form>
</body>
</html>
listuser.jsp显示数据
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="struts" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><struts:property value="title"/></title>
</head>
<body>
<table>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>出生日期</th>
</tr>
<struts:iterator value="UserList">
<tr>
<td><struts:property value="name" /></td>
<td><struts:property value="age" /></td>
<td><struts:property value="birthDay" /></td>
</tr>
</struts:iterator>
</table>
</body>
</html>
这里也有一个坑,由于刚开始接触struts2,所以一些标签都还接触,<struts:iterator>的使用也费了好大的功夫,网上好多都是用id属性,通过id来访问,可我采用这种方法一直没成功。刚才去外面吃完饭回来运行又好了,我也纳闷这是怎么回事。
这里算是对action了解各大概,至于一些细节部分,比如action与jsp之间的传值等以后会慢慢总结。
作者:社会主义接班人
出处:http://www.cnblogs.com/5ishare/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
如果文中有什么错误,欢迎指出。以免更多的人被误导。