Hello world
Now that the Convention plugin has been added to your application, let's start with a very simple example. This example will use an actionless result that isidentified鉴定by the URL. By default, the Convention plugin
assumes承担 that all of the results are stored inWEB-INF/content. This can be changed by setting the propertystruts.convention.result.pathin
the Struts properties file to the new location. Don't worry about trailing slashes斜杠, the Convention plugin handles this for you. Here is our hello world JSP:
<html>
<body>
Hello world!
</body>
</html>
If you start Tomcat (or whichever J2EE container容器 you are using) and type inhttp://localhost:8080/hello-worldinto
your browser you should get this result:
This illustrates说明 that the Convention plugin will find results even when no actionexists存在 and it is all based on the URL passed to Struts.
Code behind hello world
Let's expand on详述 this example and add a code behind class. In order to do this we need to
ensure保证 that the Convention plugin is able to find our action classes. By default, the Convention plugin will find all action classes that implementcom.opensymphony.xwork2.Actionor
whose name ends with the wordActionin specific packages.
These packages are located处于 by the Convention plugin using a search methodology. First the Convention plugin finds packages namedstruts,struts2,actionoractions.
Any packages that match those names are considered the root packages for the Convention plugin. Next, the plugin looks at all of the classes in those packages as well as sub-packages and determines if the classes implementcom.opensymphony.xwork2.Actionor
if their name ends withAction(i.e. FooAction). Here's an example of a few classes that
the Convention plugin will find:
com.example.actions.MainAction
com.example.actions.products.Display (implements com.opensymphony.xwork2.Action)
com.example.struts.company.details.ShowCompanyDetailsAction
Each of the action classes that the plugin finds will be configured to
respond响应to specific URLs. The URL is based on the package name that the class is defined in and the class name itself. First the plugin determines the namespace of the URL using the package names between the root package and the package
the class is defined in. For our examples above, the namespaces would be:
com.example.actions.MainAction -> /
com.example.actions.products.Display -> /products
com.example.struts.company.details.ShowCompanyDetailsAction -> /company/details
Next, the plugin determines the URL of the resource using the class name. It first removes the wordActionfrom the end of the class name and then converts camel case names to dashes. In our example the full URLs would
be:
com.example.actions.MainAction -> /main
com.example.actions.products.Display -> /products/display
com.example.struts.company.details.ShowCompanyDetailsAction -> /company/details/show-company-details
You can tell the Convention plugin to ignore certain packages using the propertystruts.convention.exclude.packages. You can also tell the plugin to use different strings to locate root packages using the propertystruts.convention.package.locators.
Finally, you can tell the plugin to search specific root packages using the propertystruts.convention.action.packages.
Here is our code behind action class:
package com.example.actions;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorld extends ActionSupport {
private String message;
public String getMessage() {
return message;
}
public String execute() {
message = "Hello World!";
return SUCCESS;
}
}
If you compile this class and place it into your application in the WEB-INF/classes, the Convention plugin will find the class and map the URL/hello-worldto it. Next, we need to update our JSP to print out the message
we setup in the action class. Here is the new JSP:
<html>
<body>
The message is ${message}
</body>
</html>
If start up the application server and open uphttp://localhost:8080/hello-worldin our browser, we should get this result:
The message is Hello World!
Results and result codes
The Convention Plugin will pre-configure all of you action classes when Struts is started. By default, this configuration will also contain results for any JSPs that it can find within the application. The JSPs have an additional feature that allows different
JSPs to be used based on the result code of the action. Since action methods return Strings and these Strings are traditionally used to locate results for the action, the Convention plugin allows you to define different results based on the result code.
Building on our example from above, let's say we want to provide a different result if the result code from our action is the Stringzerorather thansuccess. First, we update the action class to return
different result codes:
package com.example.actions;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorld extends ActionSupport {
private String message;
public String getMessage() {
return message;
}
public String execute() {
if (System.currentTimeMillis() % 2 == 0) {
message = "It's 0";
return "zero";
}
message = "It's 1";
return SUCCESS;
}
}
Next, we add a new JSP to the application namedWEB-INF/content/hello-world-zero.jsp. Notice that the first part of the file name is the same as the URL of the action and the last part of the name is the result code. This is the convention
that the plugin uses to determine which results to render. Here is our new JSP:
<html>
<body>
The error message is ${message}
</body>
</html>
Now, if you compile the action and restart the application, based on the current time, you'll either see the result fromWEB-INF/content/hello-world.jsporWEB-INF/content/hello-world-zero.jsp.
The result type is based on the extension of the file. The supported extensions are: jsp,ftl,vm,html,html. Examples of Action and Result to Template mapping:
URL
Result
File that could match
Result Type
/hello |
success |
/WEB-INF/content/hello.jsp |
Dispatcher |
/hello |
success |
/WEB-INF/content/hello-success.htm |
Dispatcher |
/hello |
success |
/WEB-INF/content/hello.ftl |
FreeMarker |
/hello-world |
input |
/WEB-INF/content/hello-world-input.vm |
Velocity |
/test1/test2/hello |
error |
/WEB-INF/content/test/test2/hello-error.html |
Dispatcher |
Chaining
If one action returns the name of another action in the same package, they will be chained together, if the first action doesn't have any result defined for that code. In the following example:
package com.example.actions;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport {
@Action("foo")
public String foo() {
return "bar";
}
@Action("foo-bar")
public String bar() {
return SUCCESS;
}
}
The "foo" action will be executed, because no result is found, the Convention plugin tries to find an action named "foo-bar" on the same package where "foo" is defined. If such an action is found, it will be invoked using the "chain" result.
XWork packages
Actions are placed on a custom XWork package which prevents conflicts. The name of this package is based on the Java package the action is defined in, the namespace part of the URL for the action and the parent XWork package for the action. The parent XWork
package is determined based on the property namedstruts.convention.default.parent.package(defaults toconvention-default), which is a custom XWork package that extendsstruts-default.
Therefore the naming for XWork packages used by the Convention plugin are in the form:
<java-package>#<namespace>#<parent-package>
Using our example from above, the XWork package for our action would be:
com.example.actions#/#conventionDefault
Annotation reference
The Convention plugin uses a number of different annotations to override the default conventions that are used to map actions to URLs and locate results. In addition, you can modify the parent XWork package that actions are configured with.
Action annotation
The Convention plugin allows action classes to change the URL that they are mapped to using theActionannotation. This annotation can also be used inside theActionsannotation
to allow multiple URLs to map to a single action class. This annotation must be defined on action methods like this:
package com.example.actions;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
public class HelloWorld extends ActionSupport {
@Action("/different/url")
public String execute() {
return SUCCESS;
}
}
Our action class will now map to the URL/different/urlrather than/hello-world. If no@Result(see next section) is specified, then the namespace of the action will
be used as the path to the result, on our last example it would be/WEB-INF/content/different/url.jsp.
A single method within an action class can also map to multiple URLs using theActionsannotation like this:
package com.example.actions;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
public class HelloWorld extends ActionSupport {
@Actions({
@Action("/different/url"),
@Action("/another/url")
})
public String execute() {
return SUCCESS;
}
}
Another usage of theActionorActionsannotation is to define multiple action methods within a single action class, each of which respond to a different URL. Here is an example
of multiple action methods:
package com.example.actions;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
public class HelloWorld extends ActionSupport {
@Action("/different/url")
public String execute() {
return SUCCESS;
}
@Action("url")
public String doSomething() {
return SUCCESS;
}
}
The previous example defines a second URL that is not fully qualified. This means that the namespace for the URL is determined using the Java package name rather than the Action annotation.
Interceptor and interceptor stacks can be specified using theinterceptorRefsattribute. The following example applies thevalidationinterceptor and thedefaultStackinterceptor
stack to the action:
package com.example.actions;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
public class HelloWorld extends ActionSupport {
@Action(interceptorRefs={@InterceptorRef("validation"), @InterceptorRef("defaultStack")})
public String execute() {
return SUCCESS;
}
@Action("url")
public String doSomething() {
return SUCCESS;
}
}
Parameters can be passed to results using theparamsattribute. The value of this attribute is a string array with an even number of elements in the form {"key0", "value0, "key1", "value1" ... "keyN", "valueN"}. For
example:
package com.example.actions;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Actions;
public class HelloWorld extends ActionSupport {
@Action(interceptorRefs=@InterceptorRef(value="validation",params={"programmatic", "false", "declarative", "true}))
public String execute() {
return SUCCESS;
}
@Action("url")
public String doSomething() {
return SUCCESS;
}
}
If interceptors are not specified, the default stack is applied.
|
You can specify className parameter which can be especially useful when Spring Framework is used to instantiate actions. |
Applying @Action and @Actions at the class level
There are circumstances when this is desired, like when usingDynamic Method Invocation. If anexecutemethod
is defined in the class, then it will be used for the action mapping, otherwise the method to be used will be determined when a request is made (by Dynamic Method Invocation for example)
分享到:
相关推荐
Struts2 Convention Plugin 是从 Struts2.1 版本开始引入的一个插件,它的主要目标是实现 Struts2 框架的零配置。通过约定优于配置的原则,开发者可以更加专注于业务逻辑,减少大量的 XML 配置工作。以下是 ...
Struts2 Convention Plugin是Apache Struts框架的一个重要组成部分,它为开发者提供了一种更为便捷的配置方式,使得在Struts2应用中实现MVC模式变得更加简单。这个测试项目旨在帮助我们理解和掌握如何在实际开发中...
然而,随着版本的更新,Struts2引入了一个名为Convention Plugin的新特性,旨在简化配置过程,实现所谓的“零配置”开发。 **什么是Struts2 Convention Plugin?** Convention Plugin是Struts2的一个插件,它基于...
Struts2 Convention Plugin是Apache Struts框架的一个重要插件,主要目标是简化MVC(Model-View-Controller)架构中的配置工作。这个插件引入了一种约定优于配置(Convention over Configuration)的理念,允许...
### Struts2 Convention Plugin详解 #### 一、引言 从Struts2的2.1版本开始,Convention Plugin被引入,旨在替代原有的Codebehind Plugin,实现Struts2框架下的零配置理念。这一转变简化了应用程序的开发流程,...
Struts2.1引入了Convention Plugin,以实现框架的零配置目标,替代之前的Codebehind Plugin。这个插件通过约定优于配置的原则简化了Struts2的应用开发,减少了XML配置文件的需求。以下是对Convention Plugin主要特性...
在这个版本中,Struts引入了两个重要的插件:Convention Plugin和JSON Plugin,使得JSON支持和配置简化成为可能。接下来,我们将深入探讨这两个插件的功能和如何在实际项目中应用它们。 **Convention Plugin**: ...
Struts Convention 插件是 Apache Struts 框架的一部分,它主要负责自动发现和配置控制器(actions)以及相关的资源,极大地简化了基于 Struts 的Web应用开发。这个插件的核心功能是在应用运行时扫描指定的类路径,...
Struts2 Convention Plugin 应用详解 Struts2 是一个非常流行的开源 Java 框架,用于构建基于 Model-View-Controller(MVC)架构的Web应用程序。它提供了丰富的功能和灵活性,使得开发者能够更高效地开发Web应用。...
Struts2 Convention Plugin 是从 Struts2.1 版本开始引入的一个重要组件,它的主要目标是实现 Struts2 框架的零配置。这个插件通过一系列约定,简化了应用程序的配置过程,允许开发者更加专注于业务逻辑,而不是框架...
<artifactId>struts2-convention-plugin <version>2.1.6 ``` #### 转换Codebehind项目至Convention模式 若希望在现有项目中融入Convention插件,特别是在结合RESTful设计时,可在项目的struts.xml中加入特定...
struts2-convention-plugin-2.3.24.1
struts2-convention-plugin-2.3.15.1.jar
struts2-convention-plugin-2.1.6.jar
struts2-convention-plugin-2.3.1.jar,使用注解的方式代替xml配置action,必须要引用这个包。
struts2-convention-plugin-2.1.8.jar
Struts开始使用convention-plugin代替codebehind-plugin来实现struts的零配置,使用Convention插件,你需要此JAR文件