使用S2Struts,可以容易地实现S2和Struts的连动。
因为在Action类中,service组件是自动地被设定的,所以Action类的作用仅仅是调用适当的service组件。
Action类自始自终被用作控制器,从而使得表现层和服务层(service)的角色分担也变得明确。
而且,对于Action可以实现AOP的应用。
与S2同样,S2Struts也需要JDK1.4 或者 JDK1.5的系统环境。使用Eclipse3.1环境进行动作确认。
把S2StrutsVx.x.x.zip解压缩,将得到的s2struts目录作为一个完整的Java项目引入(import)Eclipse。
当Eclipse提示是否要覆写(overwrite).classpath时,选择 '全部「Yes」' ,引入所有的内容。
这样将生成一个与本资料中提示的完全相同的开发环境。
本案例以使用
Tomcat和
Tomcat Plugin为前提条件。
请预先安装好。
案例是用S2StrutsExampleVx.x.x.zip另外提供的,请下载并解压缩。使用Eclipse,以s2struts-example为名作成一个Java项目。
请注意这不是一个Tomcat项目。将解压缩得到的s2struts-example目录完全引入这个项目中。
当Eclipse提示是否要覆写.classpath时,选择 '全部「Yes」' ,引入所有的内容。
选中s2struts-example项目,单击右键,选择属性->Tomcat。选中Tomcat项目,
应用程序URI设定为/s2struts-example。然后重新启动Tomcat,从浏览器访问
http://localhost:8080/s2struts-example/
可以看到使用S2Struts的案例。
不过如果要想看Employee Management案例的场合,请使用WEB-INF/bin目录下的runHsqldb.bat启动HSQLDB。
在S2StrutsBlankVx.x.x.zip里,含有为了使用S2Struts的所有必要的文件。
进一步而言,包括了在Mayaa,S2Dao等Web应用程序开发中用到的便利的文件。
作为开发Web应用程序的雏形利用的场合,请参照以下的文件一览表,删掉不需要的文件。
・使用S2Struts时的必要文件。
WEB-INF/
struts-config.xml
tiles-defs.xml
validation.xml
validator-rules.xml
web.xml
WEB-INF/lib
javassist-3.0.jar
commons-logging-1.0.4.jar
log4j-1.2.8.jar
ognl-2.6.5.jar
aopalliance-1.0.jar
s2-framework-2.x.x.jar
commons-beanutils-1.7.0.jar
commons-digester-1.6.jar
commons-fileupload-1.0.jar
commons-validator-1.0.4.jar
oro-2.0.8.jar
struts-1.2.8.jar
s2-struts-x.x.x.jar
WEB-INF/src
log4j.properties
application.properties
app.dicon
s2struts.dicon
・为使用S2扩张功能追加的文件。
WEB-INF/lib
jta.jar
junit-3.8.1.jar
poi-2.5-final-20040804.jar
s2-extension-2.x.x.jar
WEB-INF/src
j2ee.dicon
aop.dicon
・为使用Mayaa追加的文件。不用的话请删除。
WEB-INF/lib
jaxen-1.1-beta-8.jar
nekohtml-0.9.5.jar
rhino-1.6r2.jar
xercesImpl-2.7.1.jar
xml-apis-1.3.jar
mayaa-x.x.x.jar
・为使用S2Dao追加的文件。不用的话请删除。
WEB-INF/lib
s2-dao-x.x.x.jar
WEB-INF/src
dao.dicon
・为使用HSQLDB追加的文件。不用的话请删除。
WEB-INF/lib
hsqldb.jar
如果想用Tiger注释(annotation)的话,请把S2StrutsTigerVx.x.x.zip解压缩,得到s2struts-tiger目录。将此目录下的
- lib/s2-struts-tiger-x.x.x.jar
复制到WEB-INF/lib目录下,并且在CLASSPATH中设定该路经。
如果想用backport175注释的话,请把S2StrutsBackport175Vx.x.x.zip解压缩,得到s2struts-backport175目录,将此目录下的
- lib/s2-struts-backport175-x.x.x.jar
- lib/backport175-1.0.jar
复制到WEB-INF/lib目录下,并且在CLASSPATH中设定该路经。
让我们快点来试试看吧。
快速上手,以使用
Tomcat和
Tomcat Plugin为前提。
请预先安装好。
为了简单的利用S2Struts,我们使用S2StrutsBlankVx.x.x.zip。
把S2StrutsBlankVx.x.x.zip解压缩,得到s2struts-blank目录,作为Eclipse的一个Java项目而引入所有内容。
当Eclipse提示是否要覆写.classpath时,选择 '全部「Yes」' ,引入所有的内容。
选择s2struts-blank项目,点击右键,选择プロパティ->Tomcat。到此为止准备工作完毕。
首先做一个用于演示画面的HTML。在s2struts-blank目录下作成greetingInput.html、greeting.html。
greetingInput.html
指定时间带的画面。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-31j">
<title>Greeting Demo</title>
</head>
<body>
<form method="GET" action="greeting.html">
<table>
<tr>
<th>time</th>
<td>
<select name="time">
<option value="" selected>Please select</option>
<option value="a.m.">a.m.</option>
<option value="p.m.">p.m.</option>
</select>
</td>
</tr>
</table>
<input type="submit" value="greeting">
</form>
</body>
</html>
greeting.html
根据时间带显示不同问候语的画面。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-31j">
<title>Greeting Demo</title>
</head>
<body>
<table>
<tr>
<th>time</th>
<td>a.m.</td>
</tr>
<tr>
<th>greeting</th>
<td>Good morning</td>
</tr>
</table>
<a href="greetingInput.html">back</a>
</body>
</html>
浏览器上如果显示出greetingInput.html的话,就可以开始看应用程序的演出了。
你是否已想象得出要制作的是什么吗?
那么就开始制作吧。制作流程如下所示。
- 作一个接口(interface)
- 实装(implement)接口,作成组件
- 连接组件
这次,我们用POJO作一个Action,并使用Mayaa生成view。
在S2Struts中,用POJO生成Action的场合,必须将接口(interface)和实装(implement)分开。
详细情况请参阅「POJO作为Action时的用法」。
首先,定义GreetingInputInitAction、GreetingAction、GreetingService接口。
作为与画面的接口,还要生成一个作为ActionForm(DTO)的GreetingDto。
GreetingDto
我们将使用POJO的DTO作为ActionForm,。这一DTO将保持来自画面的项目信息内容。
package examples.dto;
public class GreetingDto {
private String time = "";
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
GreetingInputInitAction
这是为了显示greetingInput.html画面,提供必要信息的Action接口。
package examples.action;
public interface GreetingInputInitAction {
String initialize();
}
GreetingAction
这是进行问候处理的的Action接口。
package examples.action;
public interface GreetingAction {
String SUCCESS = "success";
String goGreeting();
}
GreetingService
这个接口提供不依存于Struts等表现层framework的服务(service)
package examples.service;
import java.util.List;
import examples.dto.GreetingDto;
public interface GreetingService {
List getTimeList();
String getGreeting(GreetingDto dto);
}
到此为止,一系列的接口就作好了。下面,生成实装接口的组件。
GreetingInputInitActionImpl
setGreetingService是为了注入GreetingService的setter方法。
getTimeList是为了将信息传递给画面的getter方法。
package examples.action.impl;
import java.util.List;
import examples.action.GreetingInputInitAction;
import examples.service.GreetingService;
public class GreetingInputInitActionImpl implements GreetingInputInitAction {
private GreetingService service;
private List timeList;
public String initialize() {
timeList = service.getTimeList();
return null;
}
public void setGreetingService(GreetingService service) {
this.service = service;
}
public List getTimeList() {
return timeList;
}
}
GreetingActionImpl
setGreetingService是为了注入GreetingService的setter方法。
setGreetingDto是为了从画面接收ActionForm的setter方法,getGreetingDto是为了把ActionForm传递给画面的getter方法。
getGreeting是把信息传递给画面的fetter方法。
package examples.action.impl;
import examples.action.GreetingAction;
import examples.dto.GreetingDto;
import examples.service.GreetingService;
public class GreetingActionImpl implements GreetingAction {
private GreetingService service;
private GreetingDto greetingDto;
private String greeting;
public String goGreeting() {
greeting = service.getGreeting(greetingDto);
return SUCCESS;
}
public void setGreetingService(GreetingService service) {
this.service = service;
}
public GreetingDto getGreetingDto() {
return greetingDto;
}
public void setGreetingDto(GreetingDto greetingDto) {
this.greetingDto = greetingDto;
}
public String getGreeting() {
return greeting;
}
}
GreetingServiceImpl
package examples.service.impl;
import java.util.ArrayList;
import java.util.List;
import examples.dto.GreetingDto;
import examples.service.GreetingService;
public class GreetingServiceImpl implements GreetingService {
private static final String AM = "a.m.";
private static final String PM = "p.m.";
public List getTimeList() {
List result = new ArrayList();
result.add(AM);
result.add(PM);
return result;
}
public String getGreeting(GreetingDto dto) {
if (AM.equals(dto.getTime())) {
return "Good morning";
}
if (PM.equals(dto.getTime())) {
return "Good evening";
}
return "";
}
}
到此为止,所有的实装已完成,全部组件都准备好了。下一步是将所有的组件连起来。
greeting.dicon
为了把Action和Service连起来,在examples/dicon的目录下生成greeting.dicon。
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
<include path="aop.dicon"/>
<component name="actionInterceptorChain"
class="org.seasar.framework.aop.interceptors.InterceptorChain">
<initMethod name="add"><arg>aop.traceInterceptor</arg></initMethod>
</component>
<component
class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
<property name="autoNaming">
<component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
</property>
<initMethod name="addClassPattern">
<arg>"examples.service.impl"</arg>
<arg>".*ServiceImpl"</arg>
</initMethod>
</component>
<component
class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
<property name="instanceDef">
@org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
</property>
<property name="autoNaming">
<component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
</property>
<initMethod name="addClassPattern">
<arg>"examples.action.impl"</arg>
<arg>".*ActionImpl"</arg>
</initMethod>
</component>
<component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
<property name="interceptor">actionInterceptorChain</property>
<initMethod name="addClassPattern">
<arg>"examples.action.impl"</arg>
<arg>".*ActionImpl"</arg>
</initMethod>
</component>
</components>
在app.dicon里追加include以便读取greeting.dicon。
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
<include path="s2struts.dicon"/>
<include path="examples/dicon/greeting.dicon"/>
</components>
今后,即使要追加新的Action,也无需修改greeting.dicon。因为可以利用由S2提供的组件自动登录功能。
最后,为了把画面和Action,ActionForm连接起来,我们将修改greetingInput.html、greeting.html,生成相应的mayaa文件。
关于Mayaa的详细情况,请参照「JavaServer Templates "Mayaa"」的章节。
greetingInput.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-31j">
<title>Greeting Demo</title>
</head>
<body>
<div id="appBody">
<form method="GET" action="greeting.html" id="appForm">
<table>
<tr>
<th>time</th>
<td>
<select name="time" id="time">
<option value="" selected>Please select</option>
<option value="a.m.">a.m.</option>
<option value="p.m.">p.m.</option>
</select>
</td>
</tr>
</table>
<input type="submit" value="greeting" id="goGreeting">
</form>
</div>
</body>
</html>
greetingInput.mayaa
我们使用S2Struts提供的init标签,调用GreetingInputInitAction#initialize()。
通过执行initialize(),得到显示画面所必需的timeList。
<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org"
xmlns:html="http://struts.apache.org/tags-html"
xmlns:bean="http://struts.apache.org/tags-bean"
xmlns:s2struts="http://www.seasar.org/tags-s2struts"
m:noCache="true">
<m:with id="appBody" replace="false">
<s2struts:init action="#{greetingInputInitAction.initialize}"/>
<m:doBody />
</m:with>
<html:form m:id="appForm" action="/greeting" method="POST" />
<html:select m:id="time" property="time">
<html:option value="">Please select</html:option>
<html:options name="timeList" />
</html:select>
<html:submit m:id="goGreeting" >greeting</html:submit>
</m:mayaa>
greeting.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-31j">
<title>Greeting Demo</title>
</head>
<body>
<div id="appBody">
<table>
<tr>
<th>time</th>
<td><span id="time">a.m.</span></td>
</tr>
<tr>
<th>greeting</th>
<td><span id="greeting">Good morning</span></td>
</tr>
</table>
<a href="greetingInput.html" id="goBack">back</a>
</div>
</body>
</html>
greeting.mayaa
<?xml version="1.0" encoding="UTF-8"?>
<m:mayaa xmlns:m="http://mayaa.seasar.org"
xmlns:html="http://struts.apache.org/tags-html"
xmlns:bean="http://struts.apache.org/tags-bean"
xmlns:s2struts="http://www.seasar.org/tags-s2struts"
m:noCache="true">
<m:ignore id="appBody" />
<bean:write m:id="time" name="greetingDto" property="time" />
<bean:write m:id="greeting" name="greeting" />
<html:link m:id="goBack" page="/greetingInput.html">back</html:link>
</m:mayaa>
到此为止,处理流程就结束了。
重新启动Tomcat,
请从浏览器访问http://localhost:8080/s2struts-blank/greetingInput.html确认动作是否正常。
虽然没有编辑struts-config.xml,但是系统动作是正常的。
之所以如此是因为,执行时S2Struts遵循规约,生成了struts-config信息。
在生成GreetingDto和GreetingAction的同时,也就等于完成了以下的struts-config配置。
...
<form-beans>
...
<form-bean
name="greetingDto"
type="examples.dto.GreetingDto" />
...
</form-beans>
...
<action-mappings>
...
<action
path="/greeting"
type="examples.action.GreetingAction"
name="greetingDto"
scope="request"
validate="true">
<forward name="success" path="/greeting.html" />
</action>
...
</action-mappings>
...
这次因为遵循规约所以不需要设定,不过也有不遵守规约的场合。
这种场合,可以使用注释直接指定。
关于规约和注释请参照「无设定S2Struts」的章节。
S2Struts的世界如何?
POJO的Action看起来是不是很容易测试呢?
从此我们不用再为随着应用规模的增大而不断增大的struts-config.xml文件而烦恼了。
如果想更详细地了解S2Struts的场合,请参照以下的指南。
首先,为了起动S2Container,在web.xml里要对S2ContainerServlet进行登录。
并请像下面这样设定S2ContainerFilter和S2StrutsFilter。
其次,如果是代替org.apache.struts.action.ActionServlet,请对org.seasar.struts.servlet.S2ActionServlet进行登录,
如果是代替org.apache.struts.actions.RedeployableActionServlet,请对org.seasar.struts.servlet.S2RedeployableActionServlet进行登录。
web.xml
<web-app>
<display-name>Struts Application</display-name>
<filter>
<filter-name>s2filter</filter-name>
<filter-class>
org.seasar.framework.container.filter.S2ContainerFilter
</filter-class>
</filter>
<filter>
<filter-name>s2strutsfilter</filter-name>
<filter-class>org.seasar.struts.filter.S2StrutsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>s2filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>s2strutsfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>s2container</servlet-name>
<servlet-class>
org.seasar.framework.container.servlet.S2ContainerServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Standard Action Servlet Configuration (with debugging) -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.seasar.struts.servlet.S2ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>s2container</servlet-name>
<url-pattern>/s2container</url-pattern>
</servlet-mapping>
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- The Usual Welcome File List -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
为了使S2和Struts连动,必须在struts-config.xml里,对S2用的RequestProcessor进行登录。
我们提供了S2RequestProcessor和S2TilesRequestProcessor。
它们分别对应于Struts的RequestProcessor和TilesRequestProcessor。
struts-config.xml
<struts-config>
...
<controller processorClass="org.seasar.struts.processor.S2RequestProcessor"/>
...
</struts-config>
希望连动的Action类必须在组件定义中登录。
Action类也可以个别的进行登录,不过个别登录的话,在追加Action类的时候,必须修改组件定义文件。
为了回避这一问题,推荐使用组件的自动登录功能。
Multiply.dicon
<?xml version="1.0" encoding="Shift_JIS"?>
<!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN"
"http://www.seasar.org/dtd/components21.dtd">
<components>
<component name="traceInterceptor"
class="org.seasar.framework.aop.interceptors.TraceInterceptor"/>
<component
class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
<property name="autoNaming">
<component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
</property>
<initMethod name="addClassPattern">
<arg>"org.seasar.struts.examples.multiply"</arg>
<arg>".*ServiceImpl"</arg>
</initMethod>
</component>
<component
class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
<property name="instanceDef">
@org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
</property>
<property name="autoNaming">
<component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
</property>
<initMethod name="addClassPattern">
<arg>"org.seasar.struts.examples.multiply"</arg>
<arg>".*Action"</arg>
</initMethod>
</component>
<component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
<property name="interceptor">traceInterceptor</property>
<initMethod name="addClassPattern">
<arg>"org.seasar.struts.examples.multiply"</arg>
<arg>".*Action"</arg>
</initMethod>
</component>
</components>
并且这一组件定义文件必须在全体应用程序的定义app.dicon中进行登录。
app.dicon
<components>
...
<include path="org/seasar/struts/examples/dicon/Multiply.dicon"/>
...
</components>
到此为止,由RequestProcessor生成的所有Action类才和S2形成了连动。
如果事先对接口定义setter方法,
将会自动地进行settert・注入。
还有,只有接口定义了有参数的Constructor的场合,会自动进行
Constructor・注入。
为了取得service组件,Action类要事先定义Constructor或者是setter方法。
execute()方法,由于只是将处理委托给service,所以源程序看起来非常简洁。
MultiplyAction
package org.seasar.struts.examples.multiply;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.seasar.struts.examples.form.CalculationForm;
public class MultiplyAction extends Action {
private MultiplyService multiplyService_;
public MultiplyAction(MultiplyService multiplyService) {
multiplyService_ = multiplyService;
}
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) {
CalculationForm calForm = (CalculationForm) form;
int result = multiplyService_.multiply(calForm.getArg1(), calForm.getArg2());
calForm.setResult(result);
return (mapping.findForward("success"));
}
}
我们可以把没有继承org.apache.struts.action.Action的POJO作为Action使用。
向下面这样,生成接口和实装类,在组件定义文件中定义实装类。
Action方法返回一个String类型的forward名。
并且在struts-config里,在action标签的type属性中指定接口名。
EchoAction
public interface EchoAction {
String echo();
}
EchoActionImpl
public class EchoActionImpl implements EchoAction {
private StringForm strForm;
public EchoActionImpl() {
}
public String echo() {
strForm.setResult(strForm.getInput());
return FowardNameConstants.SUCCESS;
}
public StringForm getStrForm() {
return strForm;
}
public void setStrForm(StringForm strForm) {
this.strForm = strForm;
}
}
POJO的Action类中,如果是有setter方法的场合,HttpServletRequest或者HttpSession的值会被自动绑定。
参照时的优先顺序如下所示。
(1)HttpServletRequest#getParameter(属性名)
(2)HttpServletRequest#getAttribute(属性名)
(3)HttpSession#getAttribute(属性名)
1.3.0-RC3以后,优先顺序发生了变化,如下所示(第一和第二的优先顺序互换)。
(1)HttpServletRequest#getAttribute(属性名)
(2)HttpServletRequest#getParameter(属性名)
(3)HttpSession#getAttribute(属性名)
还有,如果接收的参数带有[],类似于foo[0]=fooVal0,foo[1]=fooVal1的参数的场合,
第一参数类型为int,第二参数为含有index值的setter方法会成为自动绑定的对象。如下所示。
setFoo(int index, Object value);
getter方法的场合也是同样的,HttpServletRequest或者HttpSession会自动地被绑定到一个值。
(1)缺省时执行HttpServletRequest#setAttribute(属性名,属性值)。
(2)如果想执行HttpSession#setAttribute(属性名,属性值)的场合,必须在Action类中声明常量注释,如下所示。
public final static String 属性名_EXPORT = org.seasar.struts.Constants.SESSION;
我们也可以使用注释。如果使用注释的话,如下所示,对getter方法指定注释。
@ExportToSession()
public String getFoo() {
return foo;
}
也可以象下面这样,使用backport175注释。
/**
* @org.seasar.struts.annotation.backport175.ExportToSession()
*/
public String getFoo() {
return foo;
}
Echo.dicon
<components>
<component class="org.seasar.struts.examples.echo.EchoActionImpl" instance="request"/>
</components>
struts-config.xml
<struts-config>
...
<action-mappings>
...
<action
path="/echo"
type="org.seasar.struts.examples.echo.EchoAction"
name="strForm"
scope="request"
validate="false"
input="/pages/echoInput.jsp">
<forward name="success" path="/pages/strResult.jsp" />
</action>
...
<action-mappings>
...
</struts-config>
通过在web.xml中事先登录S2ContainerFilter,实装类的属性会自动地被绑定到request或session以及Action。
至于request和session之中的哪一个会被绑定,将根据组件定义文件中的instance属性决定的。关于ActionForm,则是由
struts-config.xml中定义的scope属性决定的。
还有,接口中有复数方法存在的场合,则与使用org.apache.struts.actions.DispatchAction的场合同样,
在struts-config.xml的action标签里,追加parameter属性,对于JSP的submit按钮,通过name属性和value属性这2个属性指定方法。
ChangeCaseAction
public interface ChangeCaseAction {
String toLowerCase();
String toUpperCase();
}
struts-config.xml
<struts-config>
...
<action-mappings>
...
<action
path="/changeCase"
type="org.seasar.struts.examples.changecase.ChangeCaseAction"
name="strForm"
scope="request"
validate="true"
parameter="command"
input="/pages/changeCaseInput.jsp">
<forward name="success" path="/pages/strResult.jsp" />
</action>
...
<action-mappings>
...
</struts-config>
changeCaseInput.jsp
...
<html:submit property="command"><bean:message key="toLowerCase"/></html:submit>
<p>
<html:submit property="command"><bean:message key="toUpperCase"/></html:submit>
...
变换成HTML,如下所示。
<input type="submit" name="command" value="toLowerCase">
<p>
<input type="submit" name="command" value="toUpperCase">
使用ProxyAction类,可以调用在组件定义文件中的Action,也可以进行委托处理。
这种情况下,struts-config和组件定义文件无需对同一类名进行定义/同期。
在struts-config的action的path属性和组件定义文件中定义的component的name属性必须一致。
详细情况请参照「关于path属性和Action类的映射」的章节。
如果只有ProxyAction类,那么在struts-config里,即使不登录S2用的RequestProcessor,也可以和S2连动。
但是,如果希望其他的Action类也和S2连动的场合,则如前所述,必须在struts-config.xml里登录S2用的RequestProcessor。
也即,为了和S2连动,只有特定的Action类是有效的。
struts-config.xml
<struts-config>
...
<action-mappings>
...
<action
path="/subtract"
type="org.seasar.struts.action.ProxyAction"
name="calcForm"
scope="request"
validate="false"
input="/pages/subtractInput.jsp">
<forward name="success" path="/pages/result.jsp" />
</action>
...
<action-mappings>
...
</struts-config>
Subtract.dicon
<components>
<component name="/subtract" class="org.seasar.struts.examples.SubtractAction"/>
<component class="org.seasar.struts.examples.SubtractServiceImpl"/>
</components>
和ProxyAction类的用法同样,只要struts-config的action的path属性和
组件定义文件中定义的component的name属性相一致,那么不使用type属性,也可以调用Action类。
详细情况请参照「关于path属性和Action类的映射」的章节。
利用这一手法是有条件的。也即,调用时不存在type属性,forward属性,include属性这3个属性。
这种情况下,struts-config和组件定义文件无需对同一个类名进行定义/同期。
struts-config.xml
<struts-config>
...
<action-mappings>
...
<action
path="/divide"
name="calcForm"
scope="request"
validate="false"
input="/pages/divideInput.jsp">
<forward name="success" path="/pages/result.jsp" />
</action>
...
<action-mappings>
...
</struts-config>
Divide.dicon
<components>
<component name="/divide" class="org.seasar.struts.examples.DivideAction"/>
<component class="org.seasar.struts.examples.DivideServiceImpl"/>
</components>
在此,我们对前面提到的,「ProxyAction类的用法」和
「在struts-config的action中,不使用type属性指定一个Action类」里,
关于path属性和Action类的映射关系,做一详细介绍。
假定存在以下的web.xml,struts-config,还有组件定义文件。
web.xml
<web-app>
...
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/foo</param-name>
<param-value>/WEB-INF/struts-config-foo.xml</param-value>
</init-param>
...
</servlet>
...
</web-app>
struts-config.xml
<struts-config>
...
<action-mappings>
...
<action path="/bar"
...
</action>
...
<action-mappings>
...
</struts-config>
struts-config-foo.xml
<struts-config>
...
<action-mappings>
...
<action path="/baz"
...
</action>
...
<action-mappings>
...
</struts-config>
组件定义文件
<components>
<component name="/bar" class="BarAction"/>
<component name="/foo/baz" class="BazAction"/>
</components>
如果是缺省的模块module(用struts-config.xml动作的模块),将在struts-config的action标签的path属性和
组件定义文件中定义的component标签的name属性之间进行映射。映射方式为下记的子模块(subModule)中的(2)的模式(pattern)。
如果是子模块(此例中,用struts-config-foo.xml动作的模块),映射方式则有2种。
(1)模块(prefix)名(/foo)+path属性(/baz)=name属性(/foo/baz)
(2)path属性(/baz)=name属性(/baz)
取得组件的优先顺序为(1)、(2)的顺序。也即,如果没有找到名字为/foo/baz的组件,那么就取得名字为/baz的组件。
还有,作成org.seasar.struts.ComponentNameCreator的实装类,经由app.dicon登录,可以替换上述的缺省映射方式。
优点・缺点
|
优点 |
缺点 |
POJOAction(推荐) |
提高了可测试性 Action类的模块切换很容易 向S2JSF等的移植很容易 |
接口定义文件有可能增加
(不过,The Seasar Foundation认为,对外接口越明确,说明可维护性越好) |
Multiply的例子 |
现有的Action,struts-config的action-mapping无需修改即可使用 |
―
|
Subtract(ProxyAction)的例子 |
为了从ActionMapping的信息(缺省为路径名)检索组件,
无需对struts-config和组件定义文件里记载的Action的类名进行同期
有着继承关系的Action类可以登录到container中 |
必须对ActionMapping的信息和组件名进行同期 |
Divide的例子 |
同上。在struts-config里,不必使用type属性(Action的类名),减少了设定内容 |
同上。但是,从Struts而言,由于是非正规的struts-config的定义方法,有可能无法取得与定义struts-config的工具之间的协调关系 |
如果没有特别的理由,推荐使用POJOAction。
正如可以对Action类实施共通的aspect一样,可以从组件取得RequestProcessor。
并且,除了实施aspect之外,也可以实施与其他的组件同样的用法。
首先,必须在web.xml里登录S2ActionServlet。
在web.xml里定义的servlet并非是org.apache.struts.action.ActionServlet,而是
org.seasar.struts.action.S2ActionServlet或者是org.seasar.struts.action.S2RedeployableActionServlet。
(S2ActionServlet继承的是ActionServlet,S2RedeployableActionServlet继承的是RedeployableActionServlet。)
web.xml
<web-app>
...
<!-- Standard Action Servlet Configuration (with debugging) -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.seasar.struts.action.S2ActionServlet</servlet-class>
...
</servlet>
...
</web-app>
这次的案例,是对S2RequestProcessor实施被称为MeasureTimeInterceptor的aspect,
能够测出各请求(request)的处理时间,并输出到stdout。
RequestProcessor.dicon
<components>
<include path="s2struts.dicon"/>
<component class="org.seasar.struts.S2RequestProcessor">
<aspect pointcut="process">
<component class="org.seasar.struts.examples.MeasureTimeInterceptor">
</aspect>
</component>
</components>
使用org.seasar.struts.action.MessageManager类,可以从任意的组件管理错误信息的显示。
MessageActionImpl.java
public class MessageActionImpl implements MessageAction {
public String execute() {
MessageManager.addGlobalError("examplemessage");
MessageManager.addGlobalError("examplemessage", "foo");
MessageManager.addGlobalError("examplemessage", "bar", "baz", "qux");
MessageManager.addError("property", "examplemessage");
MessageManager.addError("property", "examplemessage", "foo");
MessageManager.addError("property", "examplemessage", "bar", "baz", "qux");
MessageManager.saveErrors();
return FowardNameConstants.SUCCESS;
}
}
这与Struts的Action类实装的代码几乎完全相同。
ActionMessages errors = new ActionMessages();
errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage"));
errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage", "foo"));
errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage", "bar", "baz", "qux"));
errors.add("property",new ActionMessage("examplemessage"));
errors.add("property",new ActionMessage("examplemessage", "foo"));
errors.add("property",new ActionMessage("examplemessage", "bar", "baz", "qux"));
if(!errors.isEmpty()) {
saveErrors(request,errors);
}
说二者"几乎"相同,是因为上述利用资源(resource)中的关键字examplemessage里,在包含{4}的场合,其删除功能,在MessageManager里也具备。
并且,MessageManager还具有管理信息用的addGlobalMessage(),addMessage()方法和saveMessages()方法。其参数与处理错误信息的场合相同。
一旦使用S2Struts,只要遵循规约就可以对struts-config实现自动补齐功能(无设定S2Struts)。
使用注释指定struts-config,也有可能实现补齐功能。
由此,通过struts-config而省略设定成为可能。
为了利用无设定S2Struts的功能,必须在struts-config里登录AutoStrutsConfigRegisterPlugIn。
在PlugIn里因为有读取的先后顺序,所以请在ValidatorPlugIn之后再进行登录。
struts-config.xml
<struts-config>
...
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
...
</plug-in>
<plug-in className="org.seasar.struts.plugin.AutoStrutsConfigRegisterPlugIn">
<set-property property="enableJar" value="false"/>
<set-property property="jarFilePattern" value="^My.*\.jar$"/>
<set-property property="actionClassPattern" value="foo.bar.action.*Action"/>
<set-property property="formClassPattern" value="foo.bar.form.*Form"/>
<set-property property="docRoot" value="/WEB-INF/jsp"/>
<set-property property="viewExtension" value="jsp,html,view"/>
</plug-in>
...
</struts-config>
插件(plugin)的属性里可以进行值的设定。各属性的说明如下所示。各属性的定义省略时将使用缺省值。
属性 |
说明 |
缺省值 |
enableJar |
在检索无设定S2Struts里包含的类时,指定是否要检索classpath中包含的jar文件。检索的话,值为true。 |
false |
jarFilePattern |
enableJar的值为true时,指定检索对象jar文件的文件名类型。 |
无 (什么样的jar文件都是非检索对象) |
referenceClass |
检索指定的类所在的目录或者是以jar文件为基点的自动登录类。 |
无 |
actionClassPattern |
在无设定S2Struts中,指定Action类名的类型以便特定action标签的值。 |
.*Action$ |
formClassPattern |
在无设定S2Struts中,指定ActionForm类名的类型以便特定form-bean标签的值。 |
(.*Form$)|(.*Dto$) |
docRoot |
指定View模板文件的储存位置的首目录。 |
无 |
viewExtension |
指定View模板文件的扩张子。 |
jsp,html |
在无设定S2Struts中,省略可能的值将成为form-bean标签的属性,或者是action标签和该action标签内的forward标签的属性。
缺省时遵循提供的规约的场合,各属性值如下所示。
form-bean标签的属性值
以"Form"或者是"Dto"结尾的类为基准补齐设定。
属性 |
缺省值规约定义的值 |
type |
类名 |
name |
从类名检索在S2中的登录的组件,使用组件名。 |
restricted |
false |
action标签的属性值
以"Action"结尾的类为基准补齐设定。
属性 |
缺省值规约定义的值 |
type |
类名 |
path |
从类名检索在S2中登录的组件。
如果组件名以"/"开始的话使用该组件名。
不是以"/"开始的话在先头加上"/",
结尾如果是以下的值就将其删除。这些值是,"ActionImpl","Impl","Action"共3个。
没找到组件名的话,将类名的开头设定为小写文字得到的值作为组件名做如上设定。
|
name |
删除path属性的先头的"/"的值。 |
scope |
request |
validate |
true |
input |
无设定(null) |
parameter |
无设定(null) |
attribute |
无设定(null) |
forward |
无设定(null) |
include |
无设定(null) |
prefix |
无设定(null) |
suffix |
无设定(null) |
unknown |
无设定(false) |
roles |
无设定(null) |
cancellable |
false |
action标签内的forward标签的属性値
以"Action"结尾的类为基准补齐设定。
属性 |
缺省值规约定义的值 |
name |
success(不可变更) |
path |
请按以下说明的顺序设定path。
1.把包(package)名的"."更改为"/",,用该值与类名相连结(Action名的连结)。
2.类名的最后如果是以下的值删除。这些值是,"ActionImpl","Impl","Action"共3个。连结时类名的先头设为小写文字。
3.在AutoStrutsConfigRegisterPlugIn的docRoot里指定的值附加在path的先头。
4.检索以".html"和".jsp"为扩张子的文件,如果文件存在设定到path中。
5.没找到文件的场合,将package中直到第2个"/"之前的文字列全部删掉,再返回步骤"4"进行操作。
6.如果到最后还没有找到的话,不再进行设定而是输出到log。
例
类:aaa.bbb.ccc.HogeAction
AutoStrutsConfigRegisterPlugIn的docRoot:/jsp
的场合,在path里设定的文字检索顺序为
1)/jsp/aaa/bbb/ccc/hoge.jsp
2)/jsp/bbb/ccc/hoge.jsp
3)/jsp/ccc/hoge.jsp
4)/jsp/hoge.jsp
如上述步骤操作。
|
redirect |
不设定(false) |
使用Tiger注释的定义方法和使用backport175注释的定义方法都可以使用。但是不能同时使用这2种注释。
使用这两种注释时,分别需要有下表中的jar文件。
Annotation | 必要的jar文件(x.x.x表示版本) |
Tiger | s2-struts-tiger-x.x.x.jar |
backport175 | s2-struts-backport175-x.x.x.jar |
如下所示,在Action里通过定义注释可以对struts-config进行设定。
package org.seasar.struts.examples.employee.action;
import org.seasar.struts.annotation.tiger.StrutsAction;
import org.seasar.struts.annotation.tiger.StrutsActionForward;
@StrutsAction(name="employeeForm", validate=false)
public interface EmployeeEditAction {
@StrutsActionForward(path="/pages/employee/employeeEdit.jsp")
public String SUCCESS = "success";
public String execute();
}
使用backport175注释时的定义如下所示。
package org.seasar.struts.examples.employee.action;
/**
* @org.seasar.struts.annotation.backport175.StrutsAction(
* name="employeeForm", validate=false)
*/
public interface EmployeeEditAction {
/**
* @org.seasar.struts.annotation.backport175.StrutsActionForward(
* path="/pages/employee/employeeEdit.jsp")
*/
public String SUCCESS = "success";
public String execute();
}
使用常量注释时的定义如下所示。
package org.seasar.struts.examples.employee.action;
public interface EmployeeEditAction {
public static final String ACTION = "name=employeeForm, validate=false";
public static final String SUCCESS_FORWARD = "path=/pages/employee/employeeEdit.jsp";
public String SUCCESS = "success";
public String execute();
}
这与以下的定义具有相同的效果。
...
<action-mappings>
...
<action
path="/employeeEdit"
type="org.seasar.struts.examples.employee.action.EmployeeEditAction"
name="employeeForm"
scope="request"
validate="true">
<forward name="success" path="/pages/employee/employeeEdit.jsp" />
</action>
...
用StrutsAction(ACTION)可能指定的属性
属性 | 必须 |
path | × |
name | × |
scope | × |
validate | × |
input | × |
parameter | × |
attribute | × |
forward | × |
include | × |
prefix | × |
suffix | × |
unknown | × |
roles | × |
cancellable | × |
注释与struts-config的action标签的属性为1对。并且,各属性的缺省值,为无设定S2Struts中定义的值。
用StrutsActionForward(FORWARD)可能指定的属性
属性 | 必须 | 缺省值 |
path | ○ | - |
redirect | × | false |
注释与struts-config的forward标签的属性为1对。用常量值指定name属性。
并且如下所示,在Form(DTO)里通过定义注释可以对struts-config进行设定。
package org.seasar.struts.examples.employee.dto;
import org.seasar.struts.annotation.tiger.StrutsActionForm;
@StrutsActionForm(name="employeeForm")
public class EmployeeDto extends Employee {
...
}
使用backport175注释的定义如下所示。
package org.seasar.struts.examples.employee.dto;
/**
* @org.seasar.struts.annotation.backport175.StrutsActionForm(name="employeeForm")
*/
public class EmployeeDto extends Employee {
...
}
常量注释的定义如下所示。
package org.seasar.struts.examples.employee.dto;
public class EmployeeDto extends Employee {
public static final String FORM = "name=employeeForm";
...
}
这些和以下的定义具有相同效果。
...
<form-beans>
...
<form-bean
name="employeeForm"
type="org.seasar.struts.examples.employee.dto.EmployeeDto" />
...
用StrutsActionForm(FORM)可能指定的属性
注释与struts-config的form-bean标签的属性为1对。并且,各属性的缺省值,是无设定S2Struts中定义的值。
如下所示,在ActionForm的setter方法中,通过定义注释可以对validation进行设定。
public class ValidateDto implements Serializable {
private String value;
@ValidateOrder(1)
@Required
@Minlength(10)
@Maxlength(15)
@Mask(pattern="com$",messageKey="mustendcom")
@EmailType
@Args(keys="mixValue",resource=false)
public void setValue(String value) {
this.value = value;
}
使用backport175注释的定义,如下所示。
public class ValidateDto implements Serializable {
private String value;
/**
* @org.seasar.struts.validator.annotation.backport175.ValidateOrder(1)
* @org.seasar.struts.validator.annotation.backport175.Required
* @org.seasar.struts.validator.annotation.backport175.Minlength(value=10)
* @org.seasar.struts.validator.annotation.backport175.Maxlength(value=15)
* @org.seasar.struts.validator.annotation.backport175.Mask(
* pattern="com$",messageKey="mustendcom")
* @org.seasar.struts.validator.annotation.backport175.Email
* @org.seasar.struts.validator.annotation.backport175.Args(
* keys="mixValue",resource=false)
*/
public void setValue(String value) {
this.value = value;
}
}
使用常量注释的定义如下所示。
public class ValidateDto implements Serializable {
private String value;
public static final int value_VALIDATOR_ORDER = 1;
public static final String value_VALIDATOR = "required";
public static final String value_VALIDATOR_0 = "minlength, value=10";
public static final String value_VALIDATOR_1 = "maxlength, value=15";
public static final String value_VALIDATOR_2 = "mask, pattern=com$, messageKey=mustendcom";
public static final String value_VALIDATOR_3 = "email";
public static final String value_VALIDATOR_ARGS = "keys=mixValue, resource=false";
public void setValue(String value) {
this.value = value;
}
}
S2Struts中,为了设定validation提供了各种注释。
除了ValidateOrder、Args、Message以外,其余的注释在基本校验时都会用到。
ValidateOrder
用于控制验证顺序。按指定顺序显示错误信息。
属性 | 必须 | 缺省值 | 说明 |
value |
× |
999 |
指定验证顺序。 |
Args
指定信息中用到的置换参数。
属性 | 必须 | 缺省值 | 说明 |
keys |
× |
- |
指定信息中用到的置换参数。
用","分隔符可以进行复数个参数的指定。
常量注释中关于用","进行分隔的方法请参照「常量注释的补充」。 |
bundle |
× |
- |
使用缺省值以外的信息资源的场合,
指定所用到的信息资源的key。 |
resource |
× |
true |
指定是否利用由keys指定的值作为资源key。
true的场合,作为资源key使用,该值被作为置换参数。
false的场合,用keys指定的值直接被当作置换参数。 |
value |
× |
- |
用Arg注释个别指定置换参数的场合使用。
个别指定置换参数的场合,请不要指定keys,bundle,resource。 |
Arg
个别指定信息中用到的置换参数。
属性 | 必须 | 缺省值 | 说明 |
key |
○ |
- |
指定信息中用到的置换参数。 |
name |
× |
- |
指定使用置换参数的校验名。 |
bundle |
× |
- |
使用缺省值以外的信息资源的场合,
指定使用信息资源的key。 |
resource |
× |
true |
指定是否把key指定的值作为资源key使用。
true的场合作为资源key使用,使用该值作为信息。
false的场合用key指定的值直接作为信息。 |
position |
× |
- |
指定置换参数的位置。 |
常量注释如下所示,用属性名_VALIDATOR_ARG进行指定。
复数指定的场合,常量名的最后附上以0开头的INDEX。
public static final String value_VALIDATOR_0 = "required";
public static final String value_VALIDATOR_1 = "integer";
public static final String value_VALIDATOR_ARG_0 = "form.value";
public static final String value_VALIDATOR_ARG_1 = "form.value.def";
public static final String value_VALIDATOR_ARG_2 = "form.value.req, name = required, position = 1";
public void setValue(String value) {
this.value = value;
}
Messages
想指定复数个Message注释的场合使用。
属性 | 必须 | 缺省值 | 说明 |
value |
○ |
- |
指定复数个Message注释。 |
Message
想显示个别信息以代替缺省信息的场合指定。
属性 | 必须 | 缺省值 | 说明 |
key |
○ |
- |
指定信息key或者信息。 |
name |
○ |
- |
指定一个指定信息的校验名。 |
bundle |
× |
- |
使用缺省值以外的信息资源的场合,
指定使用信息资源的key。 |
resource |
× |
true |
指定是否把key指定的值作为资源key使用。
true的场合作为资源key使用,使用该值作为信息。
false的场合使用key指定的值直接作为信息。 |
Required
确认该值是否含有空白以外的文字。
无参数。
Mask
确认该值是否与pattern指定的正规表现一致。
属性 | 必须 | 缺省值 | 说明 |
pattern |
○ |
- |
指定正规表现。 |
messageKey |
× |
- |
指定取得信息用的key。 |
resource |
× |
true |
指定是否把key指定的值作为资源key使用。
true的场合作为资源key使用,使用该值作为置换参数。
false的场合使用key指定的值直接作为置换参数。 |
IntRange, LongRange, FloatRange, DoubleRange
确认值是否处于min和max指定的范围内。
属性 | 必须 | 缺省值 | 说明 |
min |
○ |
- |
指定值范围内的最小值。 |
max |
○ |
- |
指定值范围内的最大值。 |
Maxlength
确认值的文字数是否在value以下。
属性 | 必须 | 缺省值 | 说明 |
value |
○ |
- |
指定值的长度的上限值。 |
Minlength
确认值的文字数是否在value以上。
属性 | 必须 | 缺省值 | 说明 |
value |
○ |
- |
指定值的长度的下限值。 |
Maxbytelength
确认值的字节数是否在value以下。
属性 | 必须 | 缺省值 | 说明 |
value |
○ |
- |
指定值的长度的上限值。 |
charset |
× |
- |
指定用字节数验证时的文字set。 不指定的场合,使用platform的缺省文字set。 |
Minbytelength
确认值的字节数是否在value以上。
属性 | 必须 | 缺省值 | 说明 |
value |
○ |
- |
指定值的长度的下限值。 |
charset |
× |
- |
指定用字节数验证时的文字set。 不指定的场合,使用platform的缺省文字set。 |
ByteType, ShortType, IntegerType, LongType, FloatType, DoubleType
确认值是否能够变换成指定的型。
无属性。
DateType
确认值是否可表示有效的日期。
属性 | 必须 | 缺省值 | 说明 |
pattern |
× |
s2struts.dion的dateConfigRegister组件定义时指定的类型(pattern) |
指定日期的类型(pattern)。 |
CreditCardType
确认值是否为有效的信用卡号码。
无属性。
EmailType
确认值是否为有效的邮件地址。
无属性。
UrlType
确认值是否为有效的URL。
属性 | 必须 | 缺省值 | 说明 |
allowallschemes |
× |
false |
指定是否允许scheme。 如果设定为true,全部的scheme都得到允许。
|
allow2slashes |
× |
false |
指定是否允许双斜线(//)。 如果为true,允许。
|
nofragments |
× |
false |
指定是否允许URL的分割。 如果为false,允许。
|
schemes |
× |
http,https,ftp |
指定用,(逗号)分隔允许的scheme。
|
NoValidate
指定不要自动校验。
无属性。
常量注释,利用「,」(逗号)作为属性的分割文字。
在值里,指定「,」的场合,像下面这样,把値用「'」(单引号)或者「"」(双引号)括起来。
public static final String value_VALIDATOR = "mask, pattern='(^[0-9]{1,2}$)', messageKey=comma";
public static final String value_VALIDATOR = "mask, pattern=\"(^[0-9]{1,2}$)\", messageKey=comma";
S2Struts中,提供了ButtonTag和SubmitTag。
二者均为Struts的标签的扩张形式。
org.seasar.struts.taglib.html.ButtonTag(标签名:button)
http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#button
在上述基础上追加的属性,如下所示。
属性名 | 必须 | rtexprvalue | 说明 |
type |
× |
false |
以下的值,指定按钮的种类。
"button":一般按钮。
"submit":执行按钮。
"reset":复位按钮。
在HTML4.01 中 submit是作为规定值被定义的, 在IE6.0 或 Netscape 的实装中,规定值是 button 。 |
indexId |
× |
false |
用logic:iterate标签的id属性等指定变量名。
在button的value属性的值里,设定为这一变量值。
(变量值为32位的Integer的话,变换后的html例子:<button ... value="32" ...>) |
org.seasar.struts.taglib.html.SubmitTag(标签名:submit)
http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#submit
在上述基础上追加的属性,如下所示。
属性名 | 必须 | rtexprvalue | 说明 |
action |
× |
- |
根据action="#{component.method}"的定义,submit时可以指定执行的组件和方法。
组件必须用这一属性指定的名字在S2Container中登录。
没有指定indexId属性的场合,调用无参数的指定method。
例如,定义为<s2struts:submit action="{hogeAction.create}">
的按钮被按下的场合,
会调用String create()
方法
指定indexId属性的场合,调用int型的index为参数的方法。
例如,定义为<s2struts:submit action="{hogeAction.create}" indexId="index">
的按钮被按下的场合,
会调用String create(int index)
方法。
S2Struts1.3.0-RC3以后,将使用与指定组件对应的ActionMapping。
ActionMapping指的是,缺省时从ActionPathNamingRule组件得到path作为keye而被决定。
明确指定的场合在调用方法(method)中,请指定BINDING_METHOD注释。
|
indexId |
× |
false |
用logic:iterate标签的id属性指定已定义了的变量名。
将被变换成propertyName[变量值]那样。
(变量值是32位的Integer的场合,变换后的html例子:<... foo[32]="bar"...>) |
cancel |
× |
false |
指定为true的场合,将无视与form相关的ActionForm的validate,
调用Action。 |
org.seasar.struts.taglib.html.CancelTag(标签名:cancel)
http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#cancel
对上述cancel进行扩张,不利用Request参数实现Cancel功能的标签。
没有追加的属性。
org.seasar.struts.taglib.html.ImageTag(标签名:image)
http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#image
在上述基础上追加的属性,如下所示。
属性名 | 必须 | rtexprvalue | 说明 |
action |
× |
- |
根据action="#{component.method}"的定义,提交(submit)时可以指定执行组件和方法。
组件必须用这一属性指定的名字在S2Container中进行登录。
S2Struts1.3.0-RC3以后,使用与指定的组件相对应的ActionMapping。
ActionMapping指的是,缺省时从ActionPathNamingRule组件得到path作为key而决定。
明确指定的场合在调用方法(method)中,请指定BINDING_METHOD注释。
|
cancel |
× |
false |
指定为true的场合,将无视与form相关的ActionForm的validate,
调用Action。 |
org.seasar.struts.taglib.html.CheckboxTag(标签名:checkbox)
http://struts.apache.org//struts-doc-1.2.8/userGuide/struts-html.html#checkbox
对上述checkbox进行扩张,即使没有check的场合,与form相关连的ActionForm的属性里也可以设定为false。
没有追加的属性。
org.seasar.struts.taglib.html.PageTag(标签名:page)
根据这个标签在JSP里的定义,可以对struts-config的input属性进行无设定化处理(错误时重新显示自身画面)。
需要在form标签中进行定义。如果有复数个form存在的场合,必须分别定义。
属性名 | 必须 | rtexprvalue | 说明 |
- |
- |
- |
无属性。 |
org.seasar.struts.taglib.InitializeTag(标签名:init)
使用这一标签,可以进行画面的初始化处理。在显示JSP的时候,执行action属性中定义的MethodBinding。
属性名 | 必须 | rtexprvalue | 说明 |
action |
× |
- |
根据action="#{component.method}"里的定义,显示JSP时,可以指定执行组件和方法。
组件必须用这一属性指定的名字在S2Container中进行登录。 |
S2Struts1.3.0-RC3以后可以利用。
BINDING_METHOD注释,对于用submit标签或者image标签指定的action,为了显示指定ActionMapping而被使用。
常量注释
在Action里,以下列形式作为static字段定义。
public static final String 方法名_BINDING_METHOD = "path=ActionMapping的path"
标签和Java的定义例子如下所示。
<s2struts:submit action="#{modAction.mod}" property="submit" value="提交(submit)"/>
public static final String mod_BINDING_METHOD = "path=/hoge";
public String mod() {
...
}
Tiger注释
在Action方法中以下列形式指定注释。
@BindingMethod(path = "ActionMapping的路径")
标签和Java的定义例子如下所示。
<s2struts:submit action="#{modAction.mod}" property="submit" value="提交(submit)"/>
@BindingMethod(path = "/hoge")
public String mod() {
...
}
|