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
View Code

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 -->
View Code

<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;
    }


}
View Code
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;
    }
}
View Code

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>
View Code

这里有一个坑看网上使用通配符配置的时候总是提示找不到对应的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>
View Code

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>
View Code

这里也有一个坑,由于刚开始接触struts2,所以一些标签都还接触,<struts:iterator>的使用也费了好大的功夫,网上好多都是用id属性,通过id来访问,可我采用这种方法一直没成功。刚才去外面吃完饭回来运行又好了,我也纳闷这是怎么回事。

这里算是对action了解各大概,至于一些细节部分,比如action与jsp之间的传值等以后会慢慢总结。

原文地址:https://www.cnblogs.com/5ishare/p/6613699.html