热门文章 | 热门软件| 热门源码 | 热门电影 | 知识库 | 联系我们
软件 源码 教程 影视 健康 招聘
  HTML | JavaScript | ASP | PHP | JSP | NET | VB | VC | VF | Windows | Linux | Mysql | Mssql | Oracle | Struts 
当前位置: 创世纪计算机资源网 -> 文章频道 ->jsp 
站内搜索:
用Spring更好地处理Struts动作三种整合(2)
作者:黄洁 来源:ChinaITLab 整理日期:2007-7-30

    利用了 <controller> 标记来用 DelegatingRequestProcessor 覆盖默认的 Struts RequestProcessor。下一步是在的 Spring 配置文件中注册该动作,如清单 3 所示:


清单 3. 在 Spring 配置文件中注册一个动作

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
  <bean name="/searchSubmit"
    class="ca.nexcel.books.actions.SearchSubmit"> |(1)
     <property name="bookService">
        <ref bean="bookService"/>
     </property>
  </bean>
</beans>
     
注意:在 (1) 处,使用名称属性注册了一个 bean,以匹配 struts-config 动作映射名称。SearchSubmit 动作揭示了一个 JavaBean 属性,允许 Spring 在运行时填充属性,如清单 4 所示:


清单 4. 具有 JavaBean 属性的 Struts 动作

package ca.nexcel.books.actions;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;
public class SearchSubmit extends Action {
 
  private BookService bookService;
  public BookService getBookService() {
    return bookService;
  }
  public void setBookService(BookService bookService) { | (1)
    this.bookService = bookService;
  }
  public ActionForward execute(
    ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response)
    throws IOException, ServletException {
    DynaActionForm searchForm = (DynaActionForm) form;
    String isbn = (String) searchForm.get("isbn");
 
  Book book = getBookService().read(isbn.trim());  |(2)
    if (null == book) {
      ActionErrors errors = new ActionErrors();
      errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound"));
      saveErrors(request, errors);
      return mapping.findForward("failure") ;
  }
      request.setAttribute("book", book);
      return mapping.findForward("success");
  }
}
      
     在清单 4 中,您可以了解到如何创建 Struts 动作。在 (1) 处,创建了一个 JavaBean 属性。DelegatingRequestProcessor自动地配置这种属性。这种设计使 Struts 动作并不知道它正被 Spring 管理,并且使您能够利用 Sping 的动作管理框架的所有优点。由于您的 Struts 动作注意不到 Spring 的存在,所以您不需要重写您的 Struts 代码就可以使用其他控制反转容器来替换掉 Spring。

  DelegatingRequestProcessor 方法的确比第一种方法好,但是仍然存在一些问题。如果您使用一个不同的 RequestProcessor,则需要手动整合 Spring 的 DelegatingRequestProcessor。添加的代码会造成维护的麻烦并且将来会降低您的应用程序的灵活性。此外,还有过一些使用一系列命令来代替 Struts RequestProcessor 的传闻。 这种改变将会对这种解决方法的使用寿命造成负面的影响。


窍门 3. 将动作管理委托给 Spring

   一个更好的解决方法是将 Strut 动作管理委托给 Spring。您可以通过在 struts-config 动作映射中注册一个代理来实现。代理负责在 Spring 环境中查找 Struts 动作。由于动作在 Spring 的控制之下,所以它可以填充动作的 JavaBean 属性,并为应用诸如 Spring 的 AOP 拦截器之类的特性带来了可能。

清单 5 中的 Action 类与清单 4 中的相同。但是 struts-config 有一些不同:


清单 5. Spring 整合的委托方法

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
 <form-beans>
    <form-bean name="searchForm"
      type="org.apache.struts.validator.DynaValidatorForm">
               <form-property name="isbn"    type="java.lang.String"/>
    </form-bean>
  </form-beans>
 <global-forwards type="org.apache.struts.action.ActionForward">
     <forward   name="welcome"                path="/welcome.do"/>
     <forward   name="searchEntry"            path="/searchEntry.do"/>
     <forward   name="searchSubmit"           path="/searchSubmit.do"/>
 </global-forwards>
 <action-mappings>
    <action    path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
    <action    path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
    <action    path="/searchSubmit"
             type="org.springframework.web.struts.DelegatingActionProxy" |(1)
             input="/searchEntry.do"
             validate="true"
             name="searchForm">
             <forward name="success" path="/WEB-INF/pages/detail.jsp"/>
             <forward name="failure" path="/WEB-INF/pages/search.jsp"/>
    </action> 
 </action-mappings>
 <message-resources parameter="ApplicationResources"/>
 <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property
    property="pathnames"
    value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
 </plug-in>
 <plug-in
    className="org.springframework.web.struts.ContextLoaderPlugIn">
    <set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/>
 </plug-in>
</struts-config>
      
   清单 5 是一个典型的 struts-config.xml 文件,只有一个小小的差别。它注册 Spring 代理类的名称,而不是声明动作的类名,如(1)处所示。DelegatingActionProxy 类使用动作映射名称查找 Spring 环境中的动作。这就是们使用 ContextLoaderPlugIn 声明的环境。

    将一个 Struts 动作注册为一个 Spring bean 是非常直观的,如清单 6 所示。利用动作映射使用 <bean> 标记的名称属性(在这个例子中是 "/searchSubmit")简单地创建了一个 bean。这个动作的 JavaBean 属性像任何 Spring bean 一样被填充:


清单 6. 在 Spring 环境中注册一个 Struts 动作

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
 "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
  <bean name="/searchSubmit"  
        class="ca.nexcel.books.actions.SearchSubmit">
     <property name="bookService">
        <ref bean="bookService"/>
     </property>
  </bean>
</beans>
     
 
     将 Spring 从 Struts 动作中分离是一个更巧妙的设计选择。分离的一种方法是使用 org.springframework.web.struts.DelegatingRequestProcessor 类来覆盖 Struts 的 RequestProcessor 处理程序,如清单 2 所示:


清单 2. 通过 Spring 的 DelegatingRequestProcessor 进行整合

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
 <form-beans>
    <form-bean name="searchForm"
      type="org.apache.struts.validator.DynaValidatorForm">
               <form-property name="isbn"    type="java.lang.String"/>
    </form-bean>
  </form-beans>
 <global-forwards type="org.apache.struts.action.ActionForward">
     <forward   name="welcome"                path="/welcome.do"/>
     <forward   name="searchEntry"            path="/searchEntry.do"/>
     <forward   name="searchSubmit"           path="/searchSubmit.do"/>
 </global-forwards>
 <action-mappings>
    <action    path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
    <action    path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
    <action    path="/searchSubmit"
               type="ca.nexcel.books.actions.SearchSubmit"
               input="/searchEntry.do"
               validate="true"
               name="searchForm">
              <forward name="success" path="/WEB-INF/pages/detail.jsp"/>
              <forward name="failure" path="/WEB-INF/pages/search.jsp"/>
    </action> 
 </action-mappings>
 <message-resources parameter="ApplicationResources"/>
 <controller processorClass="org.springframework.web.struts.
   DelegatingRequestProcessor"/> |(1)
 <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
    <set-property property="pathnames"
      value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
 </plug-in>
 <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
    <set-property property="csntextConfigLocation" value="/WEB-INF/beans.xml"/>
 </plug-in>
</struts-config>
 

    利用了 <controller> 标记来用 DelegatingRequestProcessor 覆盖默认的 Struts RequestProcessor。下一步是在的 Spring 配置文件中注册该动作,如清单 3 所示:


清单 3. 在 Spring 配置文件中注册一个动作

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
  <bean name="/searchSubmit"
    class="ca.nexcel.books.actions.SearchSubmit"> |(1)
     <property name="bookService">
        <ref bean="bookService"/>
     </property>
  </bean>
</beans>
      
    注意:在 (1) 处,使用名称属性注册了一个 bean,以匹配 struts-config 动作映射名称。SearchSubmit 动作揭示了一个 JavaBean 属性,允许 Spring 在运行时填充属性,如清单 4 所示:


清单 4. 具有 JavaBean 属性的 Struts 动作

package ca.nexcel.books.actions;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import ca.nexcel.books.beans.Book;
import ca.nexcel.books.business.BookService;
public class SearchSubmit extends Action {
 
  private BookService bookService;
  public BookService getBookService() {
    return bookService;
  }
  public void setBookService(BookService bookService) { | (1)
    this.bookService = bookService;
  }
  public ActionForward execute(
    ActionMapping mapping,
    ActionForm form,
    HttpServletRequest request,
    HttpServletResponse response)
    throws IOException, ServletException {
    DynaActionForm searchForm = (DynaActionForm) form;
    String isbn = (String) searchForm.get("isbn");
 
  Book book = getBookService().read(isbn.trim());  |(2)
    if (null == book) {
      ActionErrors errors = new ActionErrors();
      errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound"));
      saveErrors(request, errors);
      return mapping.findForward("failure") ;
  }
      request.setAttribute("book", book);
      return mapping.findForward("success");
  }
}
     

[1]  [2]  [3]  
相关文章