窍门 2. 覆盖 RequestProcessor(二)

窍门 2. 覆盖 RequestProcessor

     将 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");
  }
}
      

    在清单 4 中,您可以了解到如何创建 Struts 动作。在 (1) 处,我创建了一个 JavaBean 属性。DelegatingRequestProcessor自动地配置这种属性。这种设计使 Struts 动作并不知道它正被 Spring 管理,并且使您能够利用 Sping 的动作管理框架的所有优点。由于您的 Struts 动作注意不到 Spring 的存在,所以您不需要重写您的 Struts 代码就可以使用其他控制反转容器来替换掉 Spring。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值