Google Prettify

2015-05-10

Struts1昇級有問題? 如何將.do導頁到.action

緣起

Struts 是一個老牌的Java web framework。有多老,老到Struts1 已經停止維護了。 Struts2看似是Struts1的延伸,不過Struts2是不向下相容於Struts1。 所謂的不向下相容,並不是指Struts1與Struts2 framework不能同時存在於一個web application裡面,而是使用struts1寫的程式,沒有辦法僅僅拿掉struts1的jar檔、加上struts2的jar檔,web.xml設一設就可以用了。 那些原本struts1寫的程式,還是需要進行相當程度的改寫。 除了將struts1的程式改為使用struts2的架構外,許許多多的連結也需要換掉。 因為struts1預設副檔名是使用.do,struts2的副檔名是使用.action,在昇級的時候,如果不是一次到位,就會導致系統裡面,Struts1的jar檔與Struts2的jar檔同時存在,.do的連結指向struts1的功能,.action的連結就會使用struts2的功能。 然而在一個已經上線的系統上,也似乎必需得這麼做,讓系統一支作業一支作業的昇級...

現在問題來了。 如果一支作業已經由struts1昇級到struts2,但是我們無法確認外部系統對內的所有的.do連結,是否已經全部換成.action。 一個折衷的辦法,就是讓.do的連結再forward到.action。 這就是我們今天要講的,如何讓指向struts1的.do連結導到struts2的.action。

請注意,以下方法適用於servlet 2.4以上

如何做?

Struts2 是使用filter的方式來install的,所以我們唯一要做的,只要在web.xml的地方增加forward dispatcher;struts1的action則直接使用config的方式forward到struts2的連結,就可以讓struts2在forward時觸發。

struts-config.xml.

<action path="/struts1moreaction" forward="/struts2action.action" />

strus.xml

<package name="taichitech" extends="struts-default" namespace="/" >
    <action name="struts2action" class="taichitech.struts1to2.Struts2Action" method="execute">
        <result name="success">/submitted2.jsp</result>
    </action>
</package>

web.xml

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

我剛看了小小小?

如果看不懂到目前為止的程式碼,接下來我會有更詳細的描述。

基本上,一個系統的架設可以有很多種方法。我這裡demo的是使用Maven的方法建立的。 當然,你也可以自己直接手動將jar檔放入相關的位置。

Dependency

Struts1 與Struts2所使相關的lib檔,可以透過Maven直接設定取得。 Pom.xml的設定是這樣的:

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.3.16.3</version>
</dependency>
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts-core</artifactId>
    <version>1.3.10</version>
</dependency>
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts-extras</artifactId>
    <version>1.3.10</version>
</dependency>
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts-taglib</artifactId>
    <version>1.3.10</version>
</dependency>

Web.xml

Struts framework(不管是1或2)都有龐大的功能,與相對應的組態。這裡展示最基本的設定。這個web.xml同時設定了 Struts1與Struts2。 其實Struts1與Struts2是可以同時放在相同一個app裡的。

web.xml

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <display-name>Servlet 2.5 Web Application</display-name>
    <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>*.action</url-pattern>
<!-- Here is point -->
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  <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/classes/struts-config.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

請注意struts2的那個filter-mapping。在一般的教學中,struts2的設定檔都不會告訴你需要使用<dispatcher>。這是servlet 2.4以後的規格。 預設是REQUEST所以在一般的情況下,是不需要額外設定。 不過我們這裡的策略是讓struts1的url link(也就是*.do) 經過struts1 framework後再forward到 struts2 framework,所以需要再額外指定<dispatcher>FORWARD</dispatcher>讓struts2的filter可以在forward的時候被觸發。

struts-config.xml

這是struts1的預設設定檔。 它長的像是這個樣子。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">
<struts-config>
    <action-mappings>
        <action path="/struts1action" type="taichitech.struts1to2.Struts1Action"
            parameter="method" scope="request">
            <forward name="success" path="/struts2action.action" />
        </action>
        <action path="/struts1moreaction" forward="/struts2action.action" />
    </action-mappings>
</struts-config>

我示範了2種手法。 第一種,仍然經過struts1 action。 不過success這個ActionForwardpath是指向struts2的url。看,url的後綴是.action

第2個更省事,連struts1的class也不用,直接forward到struts2。 Action這個tag,什麼也沒做,甚至連class也不指定了,直接forward 到struts2的url。

struts.xml

Struts2的設定檔,預設檔名是struts.xml。這與一般教學是一樣的,沒什麼特別的差異。 最後會導到/submitted2.jsp

<?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.devMode" value="false" />
    <constant name="struts.ui.theme" value="simple" />
    <package name="taichitech" extends="struts-default" namespace="/" >
        <action name="struts2action" class="taichitech.struts1to2.Struts2Action" method="execute">
            <result name="success">/submitted2.jsp</result>
        </action>
    </package>      
</struts>

Action

  • Struts1

Struts1 的action 範例:

public class Struts1Action extends DispatchAction {

    public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        Logger logger = LoggerFactory.getLogger(getClass());
        logger.debug("Execute Struts1Action.execute");
        return mapping.findForward("success");

    }
}
  • Struts2

Struts2 action的範例:

public class Struts2Action extends BaseAction {
    public String execute() {
        Logger logger = LoggerFactory.getLogger(getClass());
        logger.debug("Execute Struts2Action.execute");
        return Action.SUCCESS;
    }
}
  • index.jsp
<body>
    <a href="${pageContext.request.contextPath}/struts1action.do">Here
        is an .do link-</a> <br/>
    <a href="${pageContext.request.contextPath}/struts1moreaction.do">Here
        is an more .do link-</a>
</body>

  • submitted2.jsp
<body>A page that submitted!!
</body>

由於是採用forward的方式,url還是.do

結論

在系統改版時,可以一次到位,將所有的struts1的action重新改成struts2、struts1的jar檔可以一次被抽換掉,當然是最好。 如果不行的話,這樣的一個折衷的保險措施是必需要的。 當然一個系統的昇版並不是那麼簡單,還有許多的的部份,例如action form如何轉換、validationaction erroraction message如何修改,這些都是考驗著我們的智慧。

沒有留言 :

您或許對這些有興趣

Related Posts with Thumbnails

最後

謝謝您的閱讀,希望您可以有豐富的收獲。