<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    空間站

    北極心空

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks

    zhipingch 原創

        去年初,正好負責一個醫藥信息系統的設計開發,架構設計時,采用Struts+JDBC(自定義采用適配器模式封裝了HashMap動態VO實現的持久層)。后來ajax熱潮興起,正好系統中有很多地方需要和服務器端交互數據,如采購銷售系統中的訂單頭/訂單明細等主從表結構的維護。
        [color=blue]數據交互過程[/color],我們考慮采用xml來組織數據結構,更新/保存:前臺封裝需要的xml,通過ajax提交---〉action解析xml ---〉改造原有的持久層實現xml持久化;
        查詢時:持久層根據實際需要返回xml,document對象,---〉action 處理 --〉前臺自己封裝js庫來解析xml,并刷新部分頁面。

        ajax:已經有很多方法實現跨瀏覽器的方式,這里只介紹最簡單的方式,同步模式下提交xmlStr給action(*.do)。

    1. /**
    2.  * 將數據同步傳遞給后臺請求url
    3.  *  @return 返回xmlhttp 響應的信息
    4.  *  @param-url = '/web/module/xxx.do?p1=YY&p2=RR';
    5.  *  @param-xmlStr:xml格式的字符串 <data><xpath><![CDATA[數據信息]]></xpath></data>
    6.  * @author zhipingch
    7.  * @date 2005-03-17
    8.  */
    9. function sendData(urlStr, xmlStr) {
    10.     var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    11.     xmlhttp.open("POST", urlStr, false);
    12.     xmlhttp.setRequestHeader("Content-Type""application/x-www-form-urlencoded");
    13.     if (xmlStr) {
    14.         xmlhttp.send(xmlStr);
    15.     } else {
    16.         xmlhttp.send();
    17.     }
    18.     return xmlhttp.responseXml;
    19. }



        struts中我們擴展了Action,實現了xmlStr轉化成document對象(dom4j),并且完善了轉發方式。如
    [quote]
    1.DispatchAction
         以一個Controller響應一組動作絕對是Controller界的真理,Struts的DispatchAction同樣可以做到這點。

    [list]
    <action path="/admin/user" name="userForm" scope="request" parameter="method" validate="false">
        <forward name="list" path="/admin/userList.jsp"/>
    </action>
    [/list]
        其中parameter="method" 設置了用來指定響應方法名的url參數名為method,即/admin/user.do?method=list 將調用UserAction的public ActionForward list(....) 函數。   

        public ActionForward unspecified(....) 函數可以指定不帶method方法時的默認方法。[/quote]
        但是這樣需要在url后多傳遞參數[size=18][color=red]method=list [/color][/size];并且action節點配置中的[color=red]parameter="method" [/color]
    也沒有被充分利用,反而覺得是累贅!

        因此我們直接在BaseDispatchAction中增加xml字符串解析,并充分利用action節點配置中的[color=red]parameter="targetMethod" [/color],使得轉發的時候,action能夠直接轉發到子類的相應方法中,減少了url參數傳遞,增強了配置信息可讀性,方便團隊開發。
        同樣以上述為例,擴展后的配置方式如下:
    [quote]
    <action path="/admin/user" scope="request" [color=red]parameter="list"[/color] validate="false">
        <forward name="list" path="/admin/userList.jsp"/>
    </action>  
     [/quote]
        其中[color=red]parameter="list"[/color] 設置了用來指定響應url=/admin/user.do的方法名,它將調用UserAction的public ActionForward list(....) 函數。 
         BaseDispatchDocumentAction 的代碼如下,它做了三件重要的事情:
         1、采用dom4j直接解析xml字符串,并返回document,如果沒有提交xml數據,或者采用form形式提交的話,返回null;
         2、采用模版方法處理系統異常,減少了子類中無盡的try{...}catch(){...};其中異常處理部分另作描述(你可以暫時去掉異常處理,實現xml提交和解析,如果你有興趣,我們可以進一步交流);

     

     

         3、提供了Spring配置Bean的直接調用,雖然她沒有注入那么優雅,但是實現了ajaxstrutsspring的結合。
    BaseDispatchDocumentAction 的源碼如下:

    1. package com.ufida.haisheng.struts;
    2. import java.io.IOException;
    3. import java.io.PrintWriter;
    4. import java.lang.reflect.InvocationTargetException;
    5. import java.lang.reflect.Method;
    6. import java.math.BigDecimal;
    7. import java.sql.Timestamp;
    8. import java.util.Date;
    9. import java.util.HashMap;
    10. import javax.servlet.http.HttpServletRequest;
    11. import javax.servlet.http.HttpServletResponse;
    12. import javax.servlet.http.HttpSession;
    13. import org.apache.commons.beanutils.ConvertUtils;
    14. import org.apache.commons.beanutils.converters.BigDecimalConverter;
    15. import org.apache.commons.beanutils.converters.ClassConverter;
    16. import org.apache.commons.beanutils.converters.IntegerConverter;
    17. import org.apache.commons.beanutils.converters.LongConverter;
    18. import org.apache.log4j.Logger;
    19. import org.apache.struts.action.Action;
    20. import org.apache.struts.action.ActionForm;
    21. import org.apache.struts.action.ActionForward;
    22. import org.apache.struts.action.ActionMapping;
    23. import org.apache.struts.util.MessageResources;
    24. import org.dom4j.Document;
    25. import org.dom4j.io.SAXReader;
    26. import org.hibernate.HibernateException;
    27. import org.springframework.beans.BeansException;
    28. import org.springframework.context.ApplicationContext;
    29. import org.springframework.dao.DataAccessException;
    30. import org.springframework.web.context.support.WebApplicationContextUtils;
    31. import com.ufida.haisheng.constants.Globals;
    32. import com.ufida.haisheng.converter.DateConverter;
    33. import com.ufida.haisheng.converter.TimestampConverter;
    34. import com.ufida.haisheng.exp.ExceptionDTO;
    35. import com.ufida.haisheng.exp.ExceptionDisplayDTO;
    36. import com.ufida.haisheng.exp.exceptionhandler.ExceptionHandlerFactory;
    37. import com.ufida.haisheng.exp.exceptionhandler.ExceptionUtil;
    38. import com.ufida.haisheng.exp.exceptionhandler.IExceptionHandler;
    39. import com.ufida.haisheng.exp.exceptions.BaseAppException;
    40. import com.ufida.haisheng.exp.exceptions.MappingConfigException;
    41. import com.ufida.haisheng.exp.exceptions.NoSuchBeanConfigException;
    42. /**
    43.  * 系統的Ajax轉發基類。增加模版處理異常信息。
    44.  * 
    45.  * @author 陳志平 chenzp
    46.  * @desc BaseDispatchDocumentAction.java
    47.  * 
    48.  * @說明: web 應用基礎平臺
    49.  * @date 2005-03-02 11:18:01 AM
    50.  * @版權所有: All Right Reserved 2006-2008
    51.  */
    52. public abstract class BaseDispatchDocumentAction extends Action {
    53.     protected Class clazz = this.getClass();
    54.     protected static Logger log = Logger.getLogger(BaseDispatchDocumentAction.class);
    55.     /**
    56.      * 異常信息
    57.      */
    58.     protected static ThreadLocal<ExceptionDisplayDTO> 
      expDisplayDetails = new ThreadLocal<ExceptionDisplayDTO>();
    59.     
    60.     private static final Long defaultLong = null;
    61.     private static ApplicationContext ctx = null;
    62.     /**
    63.      * 注冊轉換的工具類 使得From中的string --
    64.      * Model中的對應的類型(Date,BigDecimal,Timestamp,Double...)
    65.      */
    66.     static {
    67.         ConvertUtils.register(new ClassConverter(), Double.class);
    68.         ConvertUtils.register(new DateConverter(), Date.class);
    69.         ConvertUtils.register(new DateConverter(), String.class);
    70.         ConvertUtils.register(new LongConverter(defaultLong), Long.class);
    71.         ConvertUtils.register(new IntegerConverter(defaultLong), Integer.class);
    72.         ConvertUtils.register(new TimestampConverter(), Timestamp.class);
    73.         ConvertUtils.register(new BigDecimalConverter(defaultLong), BigDecimal.class);
    74.     }
    75.     /**
    76.      * The message resources for this package.
    77.      */
    78.     protected static MessageResources messages = MessageResources.getMessageResources("org.apache.struts.actions.LocalStrings");
    79.     /**
    80.      * The set of Method objects we have introspected for this class, keyed by
    81.      * method name. This collection is populated as different methods are
    82.      * called, so that introspection needs to occur only once per method name.
    83.      */
    84.     protected HashMap<StringMethod> methods = new HashMap<StringMethod>();
    85.     /**
    86.      * The set of argument type classes for the reflected method call. These are
    87.      * the same for all calls, so calculate them only once.
    88.      */
    89.     protected Class[] types = { ActionMapping.class, ActionForm.classDocument.classHttpServletRequest.class,
    90.             HttpServletResponse.class };
    91.     /**
    92.      * Process the specified HTTP request, and create the corresponding HTTP
    93.      * response (or forward to another web component that will create it).
    94.      * Return an <code>ActionForward</code> instance describing where and how
    95.      * control should be forwarded, or <code>null</code> if the response has
    96.      * already been completed.
    97.      * 
    98.      * @param mapping
    99.      *            The ActionMapping used to select this instance
    100.      * @param form
    101.      *            The optional ActionForm bean for this request (if any)
    102.      * @param request
    103.      *            The HTTP request we are processing
    104.      * @param response
    105.      *            The HTTP response we are creating
    106.      * 
    107.      * @exception Exception
    108.      *                if an exception occurs
    109.      */
    110.     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
    111.             HttpServletResponse response) throws Exception {
    112.         response.setContentType("text/html; charset=UTF-8");
    113.         ExceptionDisplayDTO expDTO = null;
    114.         try {
    115.             Document doc = createDocumentFromRequest(request);
    116.             /*
    117.              * 這里直接調用mapping的parameter配置
    118.              */
    119.             String actionMethod = mapping.getParameter();
    120.             /*
    121.              * 校驗配置的方法是否正確、有效
    122.              */
    123.             isValidMethod(actionMethod);
    124.             return dispatchMethod(mapping, form, doc, request, response, actionMethod);
    125.         } catch (BaseAppException ex) {
    126.             expDTO = handlerException(request, response, ex);
    127.         } catch (Exception ex) {
    128.             ExceptionUtil.logException(this.getClass(), ex);
    129.             renderText(response,"[Error :對不起,系統出現錯誤了,請向管理員報告以下異常信息." + ex.getMessage() + "]");
    130.             request.setAttribute(Globals.ERRORMSG, "對不起,系統出現錯誤了,請向管理員報告以下異常信息." + ex.getMessage());
    131.             expDTO = handlerException(request,response, ex);
    132.         } finally {
    133.             expDisplayDetails.set(null);
    134.         }
    135.         return null == expDTO ? null : (expDTO.getActionForwardName() == null ? null : mapping.findForward(expDTO.getActionForwardName()));
    136.     }
    137.     /**
    138.      * 直接輸出純字符串
    139.      */
    140.     public void renderText(HttpServletResponse response, String text) {
    141.         PrintWriter out = null;
    142.         try {
    143.             out = response.getWriter();
    144.             response.setContentType("text/plain;charset=UTF-8");
    145.             out.write(text);
    146.         } catch (IOException e) {
    147.             log.error(e);
    148.         } finally {
    149.             if (out != null) {
    150.                 out.flush();
    151.                 out.close();
    152.                 out = null;
    153.             }
    154.         }
    155.     }
    156.     
    157.     /**
    158.      * 直接輸出純HTML
    159.      */
    160.     public void renderHtml(HttpServletResponse response, String text) {
    161.         PrintWriter out = null;
    162.         try {
    163.             out = response.getWriter();
    164.             response.setContentType("text/html;charset=UTF-8");
    165.             out.write(text);
    166.         } catch (IOException e) {
    167.             log.error(e);
    168.         } finally {
    169.             if (out != null) {
    170.                 out.flush();
    171.                 out.close();
    172.                 out = null;
    173.             }
    174.         }
    175.     }
    176.     /**
    177.      * 直接輸出純XML
    178.      */
    179.     public void renderXML(HttpServletResponse response, String text) {
    180.         PrintWriter out = null;
    181.         try {
    182.             out = response.getWriter();
    183.             response.setContentType("text/xml;charset=UTF-8");
    184.             out.write(text);
    185.         } catch (IOException e) {
    186.             log.error(e);
    187.         } finally {
    188.             if (out != null) {
    189.                 out.flush();
    190.                 out.close();
    191.                 out = null;
    192.             }
    193.         }
    194.     }
    195.     /**
    196.      * 異常處理
    197.      * @param request
    198.      * @param out
    199.      * @param ex
    200.      * @return ExceptionDisplayDTO異常描述對象
    201.      */
    202.     private ExceptionDisplayDTO handlerException(HttpServletRequest request,HttpServletResponse response, Exception ex) {
    203.         ExceptionDisplayDTO expDTO = (ExceptionDisplayDTO) expDisplayDetails.get();
    204.         if (null == expDTO) {            
    205.             expDTO = new ExceptionDisplayDTO(null,this.getClass().getName());
    206.         }
    207.         IExceptionHandler expHandler = ExceptionHandlerFactory.getInstance().create();
    208.         ExceptionDTO exDto = expHandler.handleException(expDTO.getContext(), ex);
    209.         request.setAttribute("ExceptionDTO", exDto);
    210.         renderText(response,"[Error:" + (exDto == null ? "ExceptionDTO is null,請檢查expinfo.xml配置文件." : exDto.getMessageCode())
    211.                 + "]");
    212.         return expDTO;
    213.     }
    214.     private void isValidMethod(String actionMethod) throws MappingConfigException {
    215.         if (actionMethod == null || "execute".equals(actionMethod) || "perform".equals(actionMethod)) {
    216.             log.error("[BaseDispatchAction->error] parameter = " + actionMethod);
    217.             expDisplayDetails.set(new ExceptionDisplayDTO(null"MappingConfigException"));
    218.             throw new MappingConfigException("對不起,配置的方法名不能為 " + actionMethod);
    219.         }
    220.     }
    221.   /**
    222.      * 解析xml
    223.      * @param request
    224.      * @return Document對象
    225.      */
    226.     protected static Document createDocumentFromRequest(HttpServletRequest request) throws Exception {
    227.         try {
    228.             request.setCharacterEncoding("UTF-8");
    229.             Document document = null;
    230.             SAXReader reader = new SAXReader();
    231.             document = reader.read(request.getInputStream());
    232.             return document;
    233.         } catch (Exception ex) {
    234.             log.warn("TIPS:沒有提交獲取XML格式數據流! ");
    235.             return null;
    236.         }
    237.     }
    238.     /**
    239.      * Dispatch to the specified method.
    240.      * 
    241.      * @since Struts 1.1
    242.      */
    243.     protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, Document doc,HttpServletRequest request, 
      HttpServletResponse response, String name) throws Exception {
    244.         Method method = null;
    245.         try {
    246.             method = getMethod(name);
    247.         } catch (NoSuchMethodException e) {
    248.             String message = messages.getMessage("dispatch.method", mapping.getPath(), name);
    249.             log.error(message, e);
    250.             expDisplayDetails.set(new ExceptionDisplayDTO(null"MappingConfigException"));
    251.             throw new MappingConfigException(message, e);
    252.         }
    253.         ActionForward forward = null;
    254.         try {
    255.             Object args[] = { mapping, form, doc, request, response };
    256.             log.debug("[execute-begin] -> " + mapping.getPath() + "->[" + clazz.getName() + "->" + name + "]");
    257.             forward = (ActionForward) method.invoke(this, args);
    258.             log.debug(" [execute-end] -> " + (null == forward ? "use ajax send to html/htm" : forward.getPath()));
    259.         } catch (ClassCastException e) {
    260.             String message = messages.getMessage("dispatch.return", mapping.getPath(), name);
    261.             log.error(message, e);
    262.             throw new BaseAppException(message, e);
    263.         } catch (IllegalAccessException e) {
    264.             String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
    265.             log.error(message, e);
    266.             throw new BaseAppException(message, e);
    267.         } catch (InvocationTargetException e) {
    268.             Throwable t = e.getTargetException();
    269.             String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
    270.             throw new BaseAppException(message, t);
    271.         }
    272.         return (forward);
    273.     }
    274.     /**
    275.      * Introspect the current class to identify a method of the specified name
    276.      * that accepts the same parameter types as the <code>execute</code>
    277.      * method does.
    278.      * 
    279.      * @param name
    280.      *            Name of the method to be introspected
    281.      * 
    282.      * @exception NoSuchMethodException
    283.      *                if no such method can be found
    284.      */
    285.     protected Method getMethod(String name) throws NoSuchMethodException {
    286.         synchronized (methods) {
    287.             Method method = (Method) methods.get(name);
    288.             if (method == null) {
    289.                 method = clazz.getMethod(name, types);
    290.                 methods.put(name, method);
    291.             }
    292.             return (method);
    293.         }
    294.     }
    295.   /**
    296.    * 返回spring bean對象
    297.    * @param name Spring Bean的名稱
    298.    * @exception BaseAppException
    299.    */
    300.     protected Object getSpringBean(String name) throws BaseAppException {
    301.         if (ctx == null) {
    302.             ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServlet().getServletContext());
    303.         }
    304.         Object bean = null;
    305.         try {
    306.             bean = ctx.getBean(name);
    307.         } catch (BeansException ex) {
    308.             throw new NoSuchBeanConfigException("對不起,您沒有配置名為:" + name + "的bean。請檢查配置文件!", ex.getRootCause());
    309.         }
    310.         if (null == bean) {
    311.             throw new NoSuchBeanConfigException("對不起,您沒有配置名為:" + name + "的bean。請檢查配置文件!");
    312.         }
    313.         return bean;
    314.     }
    315. }


     

     

     

    開發人員只需要繼承它就可以了,我們寫個簡單的示例action,如下:

    1. /**
    2.  * 帶Ajax提交xml數據的action類模版
    3.  * 
    4.  * @author 陳志平 chenzp
    5.  * 
    6.  * @說明: web 應用基礎平臺
    7.  * @date Aug 1, 2006 10:52:13 AM
    8.  * @版權所有: All Right Reserved 2006-2008
    9.  */
    10. public class UserAction extends BaseDispatchDocumentAction {
    11.          /**
    12.           * 這里 actionForm 和 doc 參數必有一個為空,請聰明的你分析一下
    13.           * @param mapping --轉發的映射對象
    14.           [color=blue]* @param actionForm --仍然支持表單提交,此時doc == null
    15.           * @param doc document對象,解析xml后的文檔對象[/color]
    16.           * @param request --請求
    17.           * @param response --響應
    18.           */
    19.     public ActionForward list(ActionMapping mapping, ActionForm actionForm, [color=red]Document doc[/color],HttpServletRequest request, HttpServletResponse response) throws BaseAppException {
    20.         /**
    21.          * 轉發的名稱 userAction.search: 系統上下文 用于異常處理
    22.          */
    23.         expDisplayDetails.set(new ExceptionDisplayDTO(null"userAction.search"));
    24.         /**
    25.          * 處理業務邏輯部分:
    26.          * 
    27.          * 獲取各種類型的參數 RequestUtil.getStrParameter(request,"ParameterName");
    28.          * 
    29.          * 調用父類的 getSpringBean("serviceID")方法獲取spring的配置bean
    30.          * 
    31.          */
    32.         UserManager userManager = (LogManager) getSpringBean("userManager");
    33.         //返回xml對象到前臺
    34.         renderXML(response, userManager.findUsersByDoc(doc));        
    35.                      return null;
    36.     }



    至此,我們成功實現了ajax--struts--spring的無縫結合,下次介紹spring的開發應用。歡迎大家拍磚!

     

     

         3、提供了Spring配置Bean的直接調用,雖然她沒有注入那么優雅,但是實現了ajaxstrutsspring的結合。
    BaseDispatchDocumentAction 的源碼如下:

    1. package com.ufida.haisheng.struts;
    2. import java.io.IOException;
    3. import java.io.PrintWriter;
    4. import java.lang.reflect.InvocationTargetException;
    5. import java.lang.reflect.Method;
    6. import java.math.BigDecimal;
    7. import java.sql.Timestamp;
    8. import java.util.Date;
    9. import java.util.HashMap;
    10. import javax.servlet.http.HttpServletRequest;
    11. import javax.servlet.http.HttpServletResponse;
    12. import javax.servlet.http.HttpSession;
    13. import org.apache.commons.beanutils.ConvertUtils;
    14. import org.apache.commons.beanutils.converters.BigDecimalConverter;
    15. import org.apache.commons.beanutils.converters.ClassConverter;
    16. import org.apache.commons.beanutils.converters.IntegerConverter;
    17. import org.apache.commons.beanutils.converters.LongConverter;
    18. import org.apache.log4j.Logger;
    19. import org.apache.struts.action.Action;
    20. import org.apache.struts.action.ActionForm;
    21. import org.apache.struts.action.ActionForward;
    22. import org.apache.struts.action.ActionMapping;
    23. import org.apache.struts.util.MessageResources;
    24. import org.dom4j.Document;
    25. import org.dom4j.io.SAXReader;
    26. import org.hibernate.HibernateException;
    27. import org.springframework.beans.BeansException;
    28. import org.springframework.context.ApplicationContext;
    29. import org.springframework.dao.DataAccessException;
    30. import org.springframework.web.context.support.WebApplicationContextUtils;
    31. import com.ufida.haisheng.constants.Globals;
    32. import com.ufida.haisheng.converter.DateConverter;
    33. import com.ufida.haisheng.converter.TimestampConverter;
    34. import com.ufida.haisheng.exp.ExceptionDTO;
    35. import com.ufida.haisheng.exp.ExceptionDisplayDTO;
    36. import com.ufida.haisheng.exp.exceptionhandler.ExceptionHandlerFactory;
    37. import com.ufida.haisheng.exp.exceptionhandler.ExceptionUtil;
    38. import com.ufida.haisheng.exp.exceptionhandler.IExceptionHandler;
    39. import com.ufida.haisheng.exp.exceptions.BaseAppException;
    40. import com.ufida.haisheng.exp.exceptions.MappingConfigException;
    41. import com.ufida.haisheng.exp.exceptions.NoSuchBeanConfigException;
    42. /**
    43.  * 系統的Ajax轉發基類。增加模版處理異常信息。
    44.  * 
    45.  * @author 陳志平 chenzp
    46.  * @desc BaseDispatchDocumentAction.java
    47.  * 
    48.  * @說明: web 應用基礎平臺
    49.  * @date 2005-03-02 11:18:01 AM
    50.  * @版權所有: All Right Reserved 2006-2008
    51.  */
    52. public abstract class BaseDispatchDocumentAction extends Action {
    53.     protected Class clazz = this.getClass();
    54.     protected static Logger log = Logger.getLogger(BaseDispatchDocumentAction.class);
    55.     /**
    56.      * 異常信息
    57.      */
    58.     protected static ThreadLocal<ExceptionDisplayDTO> 
      expDisplayDetails = new ThreadLocal<ExceptionDisplayDTO>();
    59.     
    60.     private static final Long defaultLong = null;
    61.     private static ApplicationContext ctx = null;
    62.     /**
    63.      * 注冊轉換的工具類 使得From中的string --
    64.      * Model中的對應的類型(Date,BigDecimal,Timestamp,Double...)
    65.      */
    66.     static {
    67.         ConvertUtils.register(new ClassConverter(), Double.class);
    68.         ConvertUtils.register(new DateConverter(), Date.class);
    69.         ConvertUtils.register(new DateConverter(), String.class);
    70.         ConvertUtils.register(new LongConverter(defaultLong), Long.class);
    71.         ConvertUtils.register(new IntegerConverter(defaultLong), Integer.class);
    72.         ConvertUtils.register(new TimestampConverter(), Timestamp.class);
    73.         ConvertUtils.register(new BigDecimalConverter(defaultLong), BigDecimal.class);
    74.     }
    75.     /**
    76.      * The message resources for this package.
    77.      */
    78.     protected static MessageResources messages = MessageResources.getMessageResources("org.apache.struts.actions.LocalStrings");
    79.     /**
    80.      * The set of Method objects we have introspected for this class, keyed by
    81.      * method name. This collection is populated as different methods are
    82.      * called, so that introspection needs to occur only once per method name.
    83.      */
    84.     protected HashMap<StringMethod> methods = new HashMap<StringMethod>();
    85.     /**
    86.      * The set of argument type classes for the reflected method call. These are
    87.      * the same for all calls, so calculate them only once.
    88.      */
    89.     protected Class[] types = { ActionMapping.class, ActionForm.classDocument.classHttpServletRequest.class,
    90.             HttpServletResponse.class };
    91.     /**
    92.      * Process the specified HTTP request, and create the corresponding HTTP
    93.      * response (or forward to another web component that will create it).
    94.      * Return an <code>ActionForward</code> instance describing where and how
    95.      * control should be forwarded, or <code>null</code> if the response has
    96.      * already been completed.
    97.      * 
    98.      * @param mapping
    99.      *            The ActionMapping used to select this instance
    100.      * @param form
    101.      *            The optional ActionForm bean for this request (if any)
    102.      * @param request
    103.      *            The HTTP request we are processing
    104.      * @param response
    105.      *            The HTTP response we are creating
    106.      * 
    107.      * @exception Exception
    108.      *                if an exception occurs
    109.      */
    110.     public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
    111.             HttpServletResponse response) throws Exception {
    112.         response.setContentType("text/html; charset=UTF-8");
    113.         ExceptionDisplayDTO expDTO = null;
    114.         try {
    115.             Document doc = createDocumentFromRequest(request);
    116.             /*
    117.              * 這里直接調用mapping的parameter配置
    118.              */
    119.             String actionMethod = mapping.getParameter();
    120.             /*
    121.              * 校驗配置的方法是否正確、有效
    122.              */
    123.             isValidMethod(actionMethod);
    124.             return dispatchMethod(mapping, form, doc, request, response, actionMethod);
    125.         } catch (BaseAppException ex) {
    126.             expDTO = handlerException(request, response, ex);
    127.         } catch (Exception ex) {
    128.             ExceptionUtil.logException(this.getClass(), ex);
    129.             renderText(response,"[Error :對不起,系統出現錯誤了,請向管理員報告以下異常信息." + ex.getMessage() + "]");
    130.             request.setAttribute(Globals.ERRORMSG, "對不起,系統出現錯誤了,請向管理員報告以下異常信息." + ex.getMessage());
    131.             expDTO = handlerException(request,response, ex);
    132.         } finally {
    133.             expDisplayDetails.set(null);
    134.         }
    135.         return null == expDTO ? null : (expDTO.getActionForwardName() == null ? null : mapping.findForward(expDTO.getActionForwardName()));
    136.     }
    137.     /**
    138.      * 直接輸出純字符串
    139.      */
    140.     public void renderText(HttpServletResponse response, String text) {
    141.         PrintWriter out = null;
    142.         try {
    143.             out = response.getWriter();
    144.             response.setContentType("text/plain;charset=UTF-8");
    145.             out.write(text);
    146.         } catch (IOException e) {
    147.             log.error(e);
    148.         } finally {
    149.             if (out != null) {
    150.                 out.flush();
    151.                 out.close();
    152.                 out = null;
    153.             }
    154.         }
    155.     }
    156.     
    157.     /**
    158.      * 直接輸出純HTML
    159.      */
    160.     public void renderHtml(HttpServletResponse response, String text) {
    161.         PrintWriter out = null;
    162.         try {
    163.             out = response.getWriter();
    164.             response.setContentType("text/html;charset=UTF-8");
    165.             out.write(text);
    166.         } catch (IOException e) {
    167.             log.error(e);
    168.         } finally {
    169.             if (out != null) {
    170.                 out.flush();
    171.                 out.close();
    172.                 out = null;
    173.             }
    174.         }
    175.     }
    176.     /**
    177.      * 直接輸出純XML
    178.      */
    179.     public void renderXML(HttpServletResponse response, String text) {
    180.         PrintWriter out = null;
    181.         try {
    182.             out = response.getWriter();
    183.             response.setContentType("text/xml;charset=UTF-8");
    184.             out.write(text);
    185.         } catch (IOException e) {
    186.             log.error(e);
    187.         } finally {
    188.             if (out != null) {
    189.                 out.flush();
    190.                 out.close();
    191.                 out = null;
    192.             }
    193.         }
    194.     }
    195.     /**
    196.      * 異常處理
    197.      * @param request
    198.      * @param out
    199.      * @param ex
    200.      * @return ExceptionDisplayDTO異常描述對象
    201.      */
    202.     private ExceptionDisplayDTO handlerException(HttpServletRequest request,HttpServletResponse response, Exception ex) {
    203.         ExceptionDisplayDTO expDTO = (ExceptionDisplayDTO) expDisplayDetails.get();
    204.         if (null == expDTO) {            
    205.             expDTO = new ExceptionDisplayDTO(null,this.getClass().getName());
    206.         }
    207.         IExceptionHandler expHandler = ExceptionHandlerFactory.getInstance().create();
    208.         ExceptionDTO exDto = expHandler.handleException(expDTO.getContext(), ex);
    209.         request.setAttribute("ExceptionDTO", exDto);
    210.         renderText(response,"[Error:" + (exDto == null ? "ExceptionDTO is null,請檢查expinfo.xml配置文件." : exDto.getMessageCode())
    211.                 + "]");
    212.         return expDTO;
    213.     }
    214.     private void isValidMethod(String actionMethod) throws MappingConfigException {
    215.         if (actionMethod == null || "execute".equals(actionMethod) || "perform".equals(actionMethod)) {
    216.             log.error("[BaseDispatchAction->error] parameter = " + actionMethod);
    217.             expDisplayDetails.set(new ExceptionDisplayDTO(null"MappingConfigException"));
    218.             throw new MappingConfigException("對不起,配置的方法名不能為 " + actionMethod);
    219.         }
    220.     }
    221.   /**
    222.      * 解析xml
    223.      * @param request
    224.      * @return Document對象
    225.      */
    226.     protected static Document createDocumentFromRequest(HttpServletRequest request) throws Exception {
    227.         try {
    228.             request.setCharacterEncoding("UTF-8");
    229.             Document document = null;
    230.             SAXReader reader = new SAXReader();
    231.             document = reader.read(request.getInputStream());
    232.             return document;
    233.         } catch (Exception ex) {
    234.             log.warn("TIPS:沒有提交獲取XML格式數據流! ");
    235.             return null;
    236.         }
    237.     }
    238.     /**
    239.      * Dispatch to the specified method.
    240.      * 
    241.      * @since Struts 1.1
    242.      */
    243.     protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, Document doc,HttpServletRequest request, 
      HttpServletResponse response, String name) throws Exception {
    244.         Method method = null;
    245.         try {
    246.             method = getMethod(name);
    247.         } catch (NoSuchMethodException e) {
    248.             String message = messages.getMessage("dispatch.method", mapping.getPath(), name);
    249.             log.error(message, e);
    250.             expDisplayDetails.set(new ExceptionDisplayDTO(null"MappingConfigException"));
    251.             throw new MappingConfigException(message, e);
    252.         }
    253.         ActionForward forward = null;
    254.         try {
    255.             Object args[] = { mapping, form, doc, request, response };
    256.             log.debug("[execute-begin] -> " + mapping.getPath() + "->[" + clazz.getName() + "->" + name + "]");
    257.             forward = (ActionForward) method.invoke(this, args);
    258.             log.debug(" [execute-end] -> " + (null == forward ? "use ajax send to html/htm" : forward.getPath()));
    259.         } catch (ClassCastException e) {
    260.             String message = messages.getMessage("dispatch.return", mapping.getPath(), name);
    261.             log.error(message, e);
    262.             throw new BaseAppException(message, e);
    263.         } catch (IllegalAccessException e) {
    264.             String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
    265.             log.error(message, e);
    266.             throw new BaseAppException(message, e);
    267.         } catch (InvocationTargetException e) {
    268.             Throwable t = e.getTargetException();
    269.             String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
    270.             throw new BaseAppException(message, t);
    271.         }
    272.         return (forward);
    273.     }
    274.     /**
    275.      * Introspect the current class to identify a method of the specified name
    276.      * that accepts the same parameter types as the <code>execute</code>
    277.      * method does.
    278.      * 
    279.      * @param name
    280.      *            Name of the method to be introspected
    281.      * 
    282.      * @exception NoSuchMethodException
    283.      *                if no such method can be found
    284.      */
    285.     protected Method getMethod(String name) throws NoSuchMethodException {
    286.         synchronized (methods) {
    287.             Method method = (Method) methods.get(name);
    288.             if (method == null) {
    289.                 method = clazz.getMethod(name, types);
    290.                 methods.put(name, method);
    291.             }
    292.             return (method);
    293.         }
    294.     }
    295.   /**
    296.    * 返回spring bean對象
    297.    * @param name Spring Bean的名稱
    298.    * @exception BaseAppException
    299.    */
    300.     protected Object getSpringBean(String name) throws BaseAppException {
    301.         if (ctx == null) {
    302.             ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServlet().getServletContext());
    303.         }
    304.         Object bean = null;
    305.         try {
    306.             bean = ctx.getBean(name);
    307.         } catch (BeansException ex) {
    308.             throw new NoSuchBeanConfigException("對不起,您沒有配置名為:" + name + "的bean。請檢查配置文件!", ex.getRootCause());
    309.         }
    310.         if (null == bean) {
    311.             throw new NoSuchBeanConfigException("對不起,您沒有配置名為:" + name + "的bean。請檢查配置文件!");
    312.         }
    313.         return bean;
    314.     }
    315. }


     

     


    請記住本文永久地址:
    http://www.javaresource.org/struts/struts-75614.html
    posted on 2007-04-19 16:03 蘆葦 閱讀(763) 評論(0)  編輯  收藏 所屬分類: SpringJAVAStruts
    主站蜘蛛池模板: 亚洲人成色77777在线观看| 国产免费卡一卡三卡乱码| 久久精品国产亚洲| 两个人看的www免费视频| 亚洲熟妇av一区二区三区| caoporm超免费公开视频| 亚洲国产婷婷综合在线精品| 日韩电影免费在线观看网址| 亚洲成a人一区二区三区| 亚洲第一视频在线观看免费| 在线日韩日本国产亚洲| 免费观看男人吊女人视频| 少妇中文字幕乱码亚洲影视| 亚洲电影在线免费观看| 亚洲人成7777| 国产又大又黑又粗免费视频 | 亚洲啪AV永久无码精品放毛片| 成年大片免费视频| 久久久久久亚洲精品无码| 波多野结衣免费视频观看| 黄床大片免费30分钟国产精品 | 色播精品免费小视频| 国产午夜亚洲精品| 亚洲av无码专区在线观看素人| 三年在线观看免费观看完整版中文 | 无码精品人妻一区二区三区免费| 亚洲伊人色欲综合网| 91香蕉国产线在线观看免费 | 窝窝影视午夜看片免费| 亚洲成人免费在线| 日韩精品视频免费在线观看| 日日摸夜夜添夜夜免费视频| 久久精品国产精品亚洲蜜月| 日本免费网址大全在线观看| 暖暖免费中文在线日本| 亚洲色欲色欲综合网站| 韩国欧洲一级毛片免费| 永久免费av无码网站yy| 亚洲综合一区国产精品| 亚洲精品无码专区在线在线播放| 天天影视色香欲综合免费|