听说struts2出来了,与webwork2的差别也不是很大,robbin说迁移很easy,禁不住诱惑,我也尝试了一把,然则发现其实好像没那么容易啊,下面把一些过程记下来。
1、JDK版本,首先我们用的是JDK1.4,一直不太敢使用JDK5,因为我们开发的系统很有可能还要在用户很久以前的系统上跑,怕出兼容问题,所以struts2我们只能选用其jdk4的那个版本了。放入的jar是:
xwork-j4-2.0.1.jar、struts2-core-j4-2.0.6.jar、retrotranslator-transformer-1.2.0.jar、retrotranslator-runtime-1.2.0.jar、backport-util-concurrent-3.0.jar
2、受到一个jar包的名字的引诱,就是struts2-spring-plugin-2.0.6.jar,于是将这个jar放到了lib中,出现了版本不兼容的异常,系统不能启动,于是找到源码,用jdk4重新编译了一下,好了。然后将struts-plugin.xml也放到了classes下面。这时候还是一直启动不了。郁闷。非常郁闷,找到以前的项目不停的对比。最后发现struts2-spring-plugin-2.0.6.jar这个jar完全没用,也就是说里面的那个类StrutsSpringObjectFactory对系统来说是没用的。删掉,然后将struts-plugin.xml也删掉了。最后的各种配置文件如下:
struts.properties文件内容如下,注意的是:
struts.objectFactory = spring这句要注释掉
struts.objectFactory.spring.autoWire=name要保留
struts.configuration.files=struts-default.xml,struts.xml(里面不能有struts-plugin.xml文件)
- ### Struts default properties
- ###(can be overridden by a struts.properties file in the root of the classpath)
- ###
-
- ### Specifies the Configuration used to configure Struts
- ### one could extend org.apache.struts2.config.Configuration
- ### to build one's customize way of getting the configurations parameters into Struts
- # struts.configuration=org.apache.struts2.config.DefaultConfiguration
-
- ### 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
-
- ### 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: if you have the xwork-tiger.jar within your classpath, GenericsObjectTypeDeterminer is used by default
- ### 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
- # 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
- 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></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></action>"*/*" method="{2}" class="actions.{1}">
- struts.enable.DynamicMethodInvocation = true
-
- ### 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></action>"*/*" method="{2}" class="actions.{1}"> to match "/foo/edit" or
- ### "/foo/save".
- struts.enable.SlashesInActionNames = 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 = true
-
- ### 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=true
-
- ### Standard UI theme
- ### Change this to reflect which path should be used for JSP control tag templates by default
- struts.ui.theme=jsxhtml
- struts.ui.templateDir=template
- #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=true
-
- ### 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 = get
-
- ### 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
-
- ### See the StrutsBeanWrapper javadocs for more information
- struts.freemarker.wrapper.altMap=true
-
- ### configure the XSLTResult class to use stylesheet caching.
- ### Set to true for developers and false for production.
- struts.xslt.nocache=false
-
- ### A list of configuration files automatically loaded by Struts
- struts.configuration.files=struts-default.xml,struts.xml
- #不能加载struts-plugin.xml,在classpath下面也不能有这个文件
- ### Whether to always select the namespace to be everything before the last slash or not
- struts.mapper.alwaysSelectFullNamespace=false
struts.xml 的代码如下,规模开发时,每个人拥有自己的配置文件,避免文件提交冲突。这个文件曾经犯晕,将struts-plugin.xml文件include进来了,结果总是启动不了,报空指针异常。去掉。
- <?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>
- <include file="struts-default.xml" />
- <include file="struts-application.xml" />
- <include file="struts-common.xml" />
- <include file="struts-dym.xml" />
- <include file="struts-zxw.xml" />
- <include file="struts-hw.xml" />
- <include file="struts-zw.xml" />
- <include file="struts-lb.xml" />
- <include file="struts-lx.xml" />
- <include file="struts-cjh.xml" />
- <include file="struts-wyf.xml" />
- </struts>
下面的代码比较重要,其中相比webwork2.2.2时,增加了一个拦截器autowiring,把它放在了拦截器栈的最上面。这样就可以将spring配置文件的service示例,以名字的形式,自动注入到action中,完成action对业务service的调用。
- <?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>
- <package name="default" extends="struts-default">
- <interceptors>
-
- <interceptor name="exceptionHandler" class="com.broadtext.framework.web.interceptor.ExceptionHandleInterceptor" />
- <interceptor name="authorizationHandler" class="com.broadtext.framework.web.interceptor.AuthorizationInterceptor" />
- <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
-
- <interceptor-stack name="appDefaultStack">
- <interceptor-ref name="autowiring"/>
- <interceptor-ref name="exception"/>
- <interceptor-ref name="alias"/>
- <interceptor-ref name="servlet-config"/>
- <interceptor-ref name="prepare"/>
- <interceptor-ref name="chain"/>
- <interceptor-ref name="model-driven"/>
- <interceptor-ref name="fileUpload"/>
- <interceptor-ref name="static-params"/>
- <interceptor-ref name="params"/>
- <interceptor-ref name="conversionError"/>
- <interceptor-ref name="exceptionHandler" />
- <interceptor-ref name="authorizationHandler" />
- </interceptor-stack>
- </interceptors>
- <default-interceptor-ref name="appDefaultStack" />
-
-
- <global-results>
- <result name="appBaseError">/pages/common/appBaseError.jsp</result>
- <result name="runtimeError">/pages/common/runtimeError.jsp</result>
- <result name="unkownError">/pages/common/runtimeError.jsp</result>
- </global-results>
- </package>
- </struts>
这是userService的spring配置代码,使用的是Spring2.0.1。
- <bean id="userService" class="com.broadtext.cmshzhgl.security.service.impl.UserServiceImpl">
- <property name="dao" ref="baseDao"></property>
- <property name="utilService" ref="utilService"></property>
- <property name="roleService" ref="roleService"></property>
- </bean>
这是测试Action的 代码,用来测试一下是不是可以调用spring配置的业务service了。
- public class LoginAction extends BaseAction {
- private UserService userService;
- public String login(){
- String aaa = userService.getTestString();
- System.out.println(aaa);
- return SUCCESS;
- }
- public void setUserService(UserService userService) {
- this.userService = userService;
- }
- }
action与jsp之间的struts配置文件代码
- <?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>
- <package name="test" extends="default" namespace="/pages/test">
- <action name="login" class="com.broadtext.cmshzhgl.security.action.LoginAction" method="login">
- <result name="success">/pages/common/currentUser.jsp</result>
- </action>
- </package>
- </struts>
总体感觉是:对于具体的开发业务的配置,xwork.xml变到struts.xml比较简单,但是spring如何注入还是比较麻烦的,要改几个文件的内容,而不是简单的将webwork和xwork改成struts就ok,主要问题struts提供了好几种spring注入的选择,弄得有些犯晕。上面我只列出其中一种配置方案,更多的配置方法慢慢再体验吧。