一点说明:
由于最近在学习Groovy相关的东西,就想是否有Groovy和Struts2集成的解决方案,网上一搜,果然有一个插件,可以使Groovy写的类直接作为Struts的Action。
但是,该插件所依赖的Groovy版本是1.0的,Groovy1.0+Struts2.1.1+s2ss(0.2版本)集成测试通过,而最新版的Groovy1.7.6无论如何都会出现如下异常:groovy.util.ResourceException: Cannot open URL:...
无奈之下,将groovy插件的源码下下来,改了源码,问题解决,更改后的Jar包在附件中(struts2-groovy-plugin-0.3.jar)
使用ss2s插件的好处是,可以将Groovy类文件直接放在classes下无需编译成JVM字节码,这样,就可以动态更改groovy文件,不像Java类那样,编译后重启Web服务器。坏处是运行效率问题。
软件包:
软件如下:
Struts2-Groovy插件: s2sss(Struts2 Scripting Support):struts-groovy-plugin-0.3.jar
Eclipse 3.6.1 JEE版本
Eclipse-Groovy插件: Groovy-Eclipse 2.1.1.xx-20101215-2100-e36(IDE,代码提示)
Groovy: groovy-binary-1.7.6.zip
Struts2: struts-2.2.1.1-all.zip
Tomcat: apache-tomcat-7.0.5
集成
打开Eclipse新建Dynamic Web Project,名为Struts2Groovy(注意创建工程是,将生成部署描述符文件选项打钩)
将以下以来的Jar包放进WEB-INF/lib目录下:
S2SS:
struts2-groovy-plugin-0.3.jar
Groovy:(S2SS依赖)
antlr-2.7.7.jar
asm-3.2.jar
groovy-1.7.6.jar
Struts2:
commons-fileupload-1.2.1.jar
commons-io-1.3.2.jar
commons-logging-1.0.4.jar
freemarker-2.3.16.jar
javassist-3.7.ga.jar
ognl-3.0.jar
struts2-core-2.2.1.1.jar
xwork-core-2.2.1.1.jar
1. 在web.xml中配置struts2过滤器:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Struts2Groovy</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
2. 在struts.xml文件中配置ObjectFactory,加入:
<constant name="struts.objectFactory" value="groovy" />
3. 在Struts2中配置Groovy类和平常的Java Action差不多,只不过必须加.groovy后缀
<!-- 匹配groovy类 --> <action name="*_2*" class="org.rsljdkt.struts2.struts2groovy.action.{1}Action.groovy" method="{2}"> <result> success.jsp</result> </action>
完整的struts.xml配置如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="false" /> <constant name="struts.configuration.xml.reload " value="true" /> <!-- 配置对象工厂,以使用Groovy类作为Action --> <constant name="struts.objectFactory" value="groovy" /> <package name="test" namespace="/" extends="struts-default"> <!-- 匹配Java类 --> <action name="*_1*" class="org.rsljdkt.struts2.struts2groovy.action.{1}Action" method="{2}"> <result> success.jsp</result> </action> <!-- 匹配Groovy类 --> <action name="*_2*" class="org.rsljdkt.struts2.struts2groovy.action.{1}Action.groovy" method="{2}"> <result> success.jsp</result> </action> </package> </struts>
4. 编写BookAction.groovy类:
package org.rsljdkt.struts2.struts2groovy.action; class BookAction{ def message def Add(){ message = "book added successfully!" "success" } def Delete(){ message = "book deleted successfully!" "success" } }
5. 编写UserAction.java类,作为比较:
package org.rsljdkt.struts2.struts2groovy.action;
public class UserAction {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String Add(){
message = "user added successfully!";
return "success";
}
public String Delete(){
message = "user deleted successfully!";
return "success";
}
}
6. 创建index.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>Index</title>
</head>
<body>
<h3>Java类作为Action</h3>
<s:a action="User_1Add">添加用户</s:a>
<s:a action="User_1Delete">删除用户</s:a>
<hr>
<h3>Groovy类作为Action</h3>
<s:a action="Book_2Add">添加书籍</s:a>
<s:a action="Book_2Delete">删除书籍</s:a>
</body>
</html>
7. 创建success.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>操作成功</title>
</head>
<body>
<s:property value = "message"/>
</body>
</html>
关于S2SS的改动
使用Eclipse+Maven来构建S2SS
m2eclipse插件更新安装地址:
http://m2eclipse.sonatype.org/sites/m2e
S2SS源码的下载地址:
http://code.google.com/p/s2ss/
本人做了两处改动:
1. 修改struts-plugin.xml文件
将Bean的name属性改为“groovy”(原为"groovyObjectFactory“),这样,在struts.xml配置文件配置struts.objectFactory常量,可以输入value属性为"groovy"(像集成Spring时的"spring"那样)
<struts> <bean type="com.opensymphony.xwork2.ObjectFactory" scope="singleton" name="groovy" class="com.googlecode.s2ss.plugin.groovy.GroovyObjectFactory" /> </struts>
2. 修改GroovyObjectFactory.getClassInstance方法为:
@Override
public Class getClassInstance(String className) throws ClassNotFoundException {
if (!className.endsWith(GROOVY_EXTENSION)) {
return super.getClassInstance(className);
} else {
Class clz = null;
try {
className = className.substring(0, className.length() - GROOVY_EXTENSION.length());
className = className.replace(".", "/");
className += GROOVY_EXTENSION;
clz = getScript(className);
} catch (Exception e) {
logger.error(e);
}
return clz;
}
}
参考:
http://www.blogjava.net/puras/archive/2007/09/03/142221.html
http://code.google.com/p/s2ss/