zhipingch 原創
去年初,正好負責一個醫藥信息系統的設計開發,架構設計時,采用Struts+JDBC(自定義采用適配器模式封裝了HashMap動態VO實現的持久層)。后來ajax熱潮興起,正好系統中有很多地方需要和服務器端交互數據,如采購銷售系統中的訂單頭/訂單明細等主從表結構的維護。
[color=blue]數據交互過程[/color],我們考慮采用xml來組織數據結構,更新/保存:前臺封裝需要的xml,通過ajax提交---〉action解析xml ---〉改造原有的持久層實現xml持久化;
查詢時:持久層根據實際需要返回xml,document對象,---〉action 處理 --〉前臺自己封裝js庫來解析xml,并刷新部分頁面。
ajax:已經有很多方法實現跨瀏覽器的方式,這里只介紹最簡單的方式,同步模式下提交xmlStr給action(*.do)。
- /**
- * 將數據同步傳遞給后臺請求url
- * @return 返回xmlhttp 響應的信息
- * @param-url = '/web/module/xxx.do?p1=YY&p2=RR';
- * @param-xmlStr:xml格式的字符串 <data><xpath><![CDATA[數據信息]]></xpath></data>
- * @author zhipingch
- * @date 2005-03-17
- */
- function sendData(urlStr, xmlStr) {
- var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
- xmlhttp.open("POST", urlStr, false);
- xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- if (xmlStr) {
- xmlhttp.send(xmlStr);
- } else {
- xmlhttp.send();
- }
- return xmlhttp.responseXml;
- }
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的直接調用,雖然她沒有注入那么優雅,但是實現了ajax、struts、spring的結合。
BaseDispatchDocumentAction 的源碼如下:
- package com.ufida.haisheng.struts;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.math.BigDecimal;
- import java.sql.Timestamp;
- import java.util.Date;
- import java.util.HashMap;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import org.apache.commons.beanutils.ConvertUtils;
- import org.apache.commons.beanutils.converters.BigDecimalConverter;
- import org.apache.commons.beanutils.converters.ClassConverter;
- import org.apache.commons.beanutils.converters.IntegerConverter;
- import org.apache.commons.beanutils.converters.LongConverter;
- import org.apache.log4j.Logger;
- import org.apache.struts.action.Action;
- import org.apache.struts.action.ActionForm;
- import org.apache.struts.action.ActionForward;
- import org.apache.struts.action.ActionMapping;
- import org.apache.struts.util.MessageResources;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.hibernate.HibernateException;
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.dao.DataAccessException;
- import org.springframework.web.context.support.WebApplicationContextUtils;
- import com.ufida.haisheng.constants.Globals;
- import com.ufida.haisheng.converter.DateConverter;
- import com.ufida.haisheng.converter.TimestampConverter;
- import com.ufida.haisheng.exp.ExceptionDTO;
- import com.ufida.haisheng.exp.ExceptionDisplayDTO;
- import com.ufida.haisheng.exp.exceptionhandler.ExceptionHandlerFactory;
- import com.ufida.haisheng.exp.exceptionhandler.ExceptionUtil;
- import com.ufida.haisheng.exp.exceptionhandler.IExceptionHandler;
- import com.ufida.haisheng.exp.exceptions.BaseAppException;
- import com.ufida.haisheng.exp.exceptions.MappingConfigException;
- import com.ufida.haisheng.exp.exceptions.NoSuchBeanConfigException;
- /**
- * 系統的Ajax轉發基類。增加模版處理異常信息。
- *
- * @author 陳志平 chenzp
- * @desc BaseDispatchDocumentAction.java
- *
- * @說明: web 應用基礎平臺
- * @date 2005-03-02 11:18:01 AM
- * @版權所有: All Right Reserved 2006-2008
- */
- public abstract class BaseDispatchDocumentAction extends Action {
- protected Class clazz = this.getClass();
- protected static Logger log = Logger.getLogger(BaseDispatchDocumentAction.class);
- /**
- * 異常信息
- */
- protected static ThreadLocal<ExceptionDisplayDTO>
expDisplayDetails = new ThreadLocal<ExceptionDisplayDTO>(); - private static final Long defaultLong = null;
- private static ApplicationContext ctx = null;
- /**
- * 注冊轉換的工具類 使得From中的string --
- * Model中的對應的類型(Date,BigDecimal,Timestamp,Double...)
- */
- static {
- ConvertUtils.register(new ClassConverter(), Double.class);
- ConvertUtils.register(new DateConverter(), Date.class);
- ConvertUtils.register(new DateConverter(), String.class);
- ConvertUtils.register(new LongConverter(defaultLong), Long.class);
- ConvertUtils.register(new IntegerConverter(defaultLong), Integer.class);
- ConvertUtils.register(new TimestampConverter(), Timestamp.class);
- ConvertUtils.register(new BigDecimalConverter(defaultLong), BigDecimal.class);
- }
- /**
- * The message resources for this package.
- */
- protected static MessageResources messages = MessageResources.getMessageResources("org.apache.struts.actions.LocalStrings");
- /**
- * The set of Method objects we have introspected for this class, keyed by
- * method name. This collection is populated as different methods are
- * called, so that introspection needs to occur only once per method name.
- */
- protected HashMap<String, Method> methods = new HashMap<String, Method>();
- /**
- * The set of argument type classes for the reflected method call. These are
- * the same for all calls, so calculate them only once.
- */
- protected Class[] types = { ActionMapping.class, ActionForm.class, Document.class, HttpServletRequest.class,
- HttpServletResponse.class };
- /**
- * Process the specified HTTP request, and create the corresponding HTTP
- * response (or forward to another web component that will create it).
- * Return an <code>ActionForward</code> instance describing where and how
- * control should be forwarded, or <code>null</code> if the response has
- * already been completed.
- *
- * @param mapping
- * The ActionMapping used to select this instance
- * @param form
- * The optional ActionForm bean for this request (if any)
- * @param request
- * The HTTP request we are processing
- * @param response
- * The HTTP response we are creating
- *
- * @exception Exception
- * if an exception occurs
- */
- public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
- HttpServletResponse response) throws Exception {
- response.setContentType("text/html; charset=UTF-8");
- ExceptionDisplayDTO expDTO = null;
- try {
- Document doc = createDocumentFromRequest(request);
- /*
- * 這里直接調用mapping的parameter配置
- */
- String actionMethod = mapping.getParameter();
- /*
- * 校驗配置的方法是否正確、有效
- */
- isValidMethod(actionMethod);
- return dispatchMethod(mapping, form, doc, request, response, actionMethod);
- } catch (BaseAppException ex) {
- expDTO = handlerException(request, response, ex);
- } catch (Exception ex) {
- ExceptionUtil.logException(this.getClass(), ex);
- renderText(response,"[Error :對不起,系統出現錯誤了,請向管理員報告以下異常信息." + ex.getMessage() + "]");
- request.setAttribute(Globals.ERRORMSG, "對不起,系統出現錯誤了,請向管理員報告以下異常信息." + ex.getMessage());
- expDTO = handlerException(request,response, ex);
- } finally {
- expDisplayDetails.set(null);
- }
- return null == expDTO ? null : (expDTO.getActionForwardName() == null ? null : mapping.findForward(expDTO.getActionForwardName()));
- }
- /**
- * 直接輸出純字符串
- */
- public void renderText(HttpServletResponse response, String text) {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- response.setContentType("text/plain;charset=UTF-8");
- out.write(text);
- } catch (IOException e) {
- log.error(e);
- } finally {
- if (out != null) {
- out.flush();
- out.close();
- out = null;
- }
- }
- }
- /**
- * 直接輸出純HTML
- */
- public void renderHtml(HttpServletResponse response, String text) {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- response.setContentType("text/html;charset=UTF-8");
- out.write(text);
- } catch (IOException e) {
- log.error(e);
- } finally {
- if (out != null) {
- out.flush();
- out.close();
- out = null;
- }
- }
- }
- /**
- * 直接輸出純XML
- */
- public void renderXML(HttpServletResponse response, String text) {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- response.setContentType("text/xml;charset=UTF-8");
- out.write(text);
- } catch (IOException e) {
- log.error(e);
- } finally {
- if (out != null) {
- out.flush();
- out.close();
- out = null;
- }
- }
- }
- /**
- * 異常處理
- * @param request
- * @param out
- * @param ex
- * @return ExceptionDisplayDTO異常描述對象
- */
- private ExceptionDisplayDTO handlerException(HttpServletRequest request,HttpServletResponse response, Exception ex) {
- ExceptionDisplayDTO expDTO = (ExceptionDisplayDTO) expDisplayDetails.get();
- if (null == expDTO) {
- expDTO = new ExceptionDisplayDTO(null,this.getClass().getName());
- }
- IExceptionHandler expHandler = ExceptionHandlerFactory.getInstance().create();
- ExceptionDTO exDto = expHandler.handleException(expDTO.getContext(), ex);
- request.setAttribute("ExceptionDTO", exDto);
- renderText(response,"[Error:" + (exDto == null ? "ExceptionDTO is null,請檢查expinfo.xml配置文件." : exDto.getMessageCode())
- + "]");
- return expDTO;
- }
- private void isValidMethod(String actionMethod) throws MappingConfigException {
- if (actionMethod == null || "execute".equals(actionMethod) || "perform".equals(actionMethod)) {
- log.error("[BaseDispatchAction->error] parameter = " + actionMethod);
- expDisplayDetails.set(new ExceptionDisplayDTO(null, "MappingConfigException"));
- throw new MappingConfigException("對不起,配置的方法名不能為 " + actionMethod);
- }
- }
- /**
- * 解析xml流
- * @param request
- * @return Document對象
- */
- protected static Document createDocumentFromRequest(HttpServletRequest request) throws Exception {
- try {
- request.setCharacterEncoding("UTF-8");
- Document document = null;
- SAXReader reader = new SAXReader();
- document = reader.read(request.getInputStream());
- return document;
- } catch (Exception ex) {
- log.warn("TIPS:沒有提交獲取XML格式數據流! ");
- return null;
- }
- }
- /**
- * Dispatch to the specified method.
- *
- * @since Struts 1.1
- */
- protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, Document doc,HttpServletRequest request,
HttpServletResponse response, String name) throws Exception { - Method method = null;
- try {
- method = getMethod(name);
- } catch (NoSuchMethodException e) {
- String message = messages.getMessage("dispatch.method", mapping.getPath(), name);
- log.error(message, e);
- expDisplayDetails.set(new ExceptionDisplayDTO(null, "MappingConfigException"));
- throw new MappingConfigException(message, e);
- }
- ActionForward forward = null;
- try {
- Object args[] = { mapping, form, doc, request, response };
- log.debug("[execute-begin] -> " + mapping.getPath() + "->[" + clazz.getName() + "->" + name + "]");
- forward = (ActionForward) method.invoke(this, args);
- log.debug(" [execute-end] -> " + (null == forward ? "use ajax send to html/htm" : forward.getPath()));
- } catch (ClassCastException e) {
- String message = messages.getMessage("dispatch.return", mapping.getPath(), name);
- log.error(message, e);
- throw new BaseAppException(message, e);
- } catch (IllegalAccessException e) {
- String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
- log.error(message, e);
- throw new BaseAppException(message, e);
- } catch (InvocationTargetException e) {
- Throwable t = e.getTargetException();
- String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
- throw new BaseAppException(message, t);
- }
- return (forward);
- }
- /**
- * Introspect the current class to identify a method of the specified name
- * that accepts the same parameter types as the <code>execute</code>
- * method does.
- *
- * @param name
- * Name of the method to be introspected
- *
- * @exception NoSuchMethodException
- * if no such method can be found
- */
- protected Method getMethod(String name) throws NoSuchMethodException {
- synchronized (methods) {
- Method method = (Method) methods.get(name);
- if (method == null) {
- method = clazz.getMethod(name, types);
- methods.put(name, method);
- }
- return (method);
- }
- }
- /**
- * 返回spring bean對象
- * @param name Spring Bean的名稱
- * @exception BaseAppException
- */
- protected Object getSpringBean(String name) throws BaseAppException {
- if (ctx == null) {
- ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServlet().getServletContext());
- }
- Object bean = null;
- try {
- bean = ctx.getBean(name);
- } catch (BeansException ex) {
- throw new NoSuchBeanConfigException("對不起,您沒有配置名為:" + name + "的bean。請檢查配置文件!", ex.getRootCause());
- }
- if (null == bean) {
- throw new NoSuchBeanConfigException("對不起,您沒有配置名為:" + name + "的bean。請檢查配置文件!");
- }
- return bean;
- }
- }
開發人員只需要繼承它就可以了,我們寫個簡單的示例action,如下:
- /**
- * 帶Ajax提交xml數據的action類模版
- *
- * @author 陳志平 chenzp
- *
- * @說明: web 應用基礎平臺
- * @date Aug 1, 2006 10:52:13 AM
- * @版權所有: All Right Reserved 2006-2008
- */
- public class UserAction extends BaseDispatchDocumentAction {
- /**
- * 這里 actionForm 和 doc 參數必有一個為空,請聰明的你分析一下
- * @param mapping --轉發的映射對象
- [color=blue]* @param actionForm --仍然支持表單提交,此時doc == null
- * @param doc document對象,解析xml后的文檔對象[/color]
- * @param request --請求
- * @param response --響應
- */
- public ActionForward list(ActionMapping mapping, ActionForm actionForm, [color=red]Document doc[/color],HttpServletRequest request, HttpServletResponse response) throws BaseAppException {
- /**
- * 轉發的名稱 userAction.search: 系統上下文 用于異常處理
- */
- expDisplayDetails.set(new ExceptionDisplayDTO(null, "userAction.search"));
- /**
- * 處理業務邏輯部分:
- *
- * 獲取各種類型的參數 RequestUtil.getStrParameter(request,"ParameterName");
- *
- * 調用父類的 getSpringBean("serviceID")方法獲取spring的配置bean
- *
- */
- UserManager userManager = (LogManager) getSpringBean("userManager");
- //返回xml對象到前臺
- renderXML(response, userManager.findUsersByDoc(doc));
- return null;
- }
至此,我們成功實現了ajax--struts--spring的無縫結合,下次介紹spring的開發應用。歡迎大家拍磚!
3、提供了Spring配置Bean的直接調用,雖然她沒有注入那么優雅,但是實現了ajax、struts、spring的結合。
BaseDispatchDocumentAction 的源碼如下:
- package com.ufida.haisheng.struts;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.math.BigDecimal;
- import java.sql.Timestamp;
- import java.util.Date;
- import java.util.HashMap;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import org.apache.commons.beanutils.ConvertUtils;
- import org.apache.commons.beanutils.converters.BigDecimalConverter;
- import org.apache.commons.beanutils.converters.ClassConverter;
- import org.apache.commons.beanutils.converters.IntegerConverter;
- import org.apache.commons.beanutils.converters.LongConverter;
- import org.apache.log4j.Logger;
- import org.apache.struts.action.Action;
- import org.apache.struts.action.ActionForm;
- import org.apache.struts.action.ActionForward;
- import org.apache.struts.action.ActionMapping;
- import org.apache.struts.util.MessageResources;
- import org.dom4j.Document;
- import org.dom4j.io.SAXReader;
- import org.hibernate.HibernateException;
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.dao.DataAccessException;
- import org.springframework.web.context.support.WebApplicationContextUtils;
- import com.ufida.haisheng.constants.Globals;
- import com.ufida.haisheng.converter.DateConverter;
- import com.ufida.haisheng.converter.TimestampConverter;
- import com.ufida.haisheng.exp.ExceptionDTO;
- import com.ufida.haisheng.exp.ExceptionDisplayDTO;
- import com.ufida.haisheng.exp.exceptionhandler.ExceptionHandlerFactory;
- import com.ufida.haisheng.exp.exceptionhandler.ExceptionUtil;
- import com.ufida.haisheng.exp.exceptionhandler.IExceptionHandler;
- import com.ufida.haisheng.exp.exceptions.BaseAppException;
- import com.ufida.haisheng.exp.exceptions.MappingConfigException;
- import com.ufida.haisheng.exp.exceptions.NoSuchBeanConfigException;
- /**
- * 系統的Ajax轉發基類。增加模版處理異常信息。
- *
- * @author 陳志平 chenzp
- * @desc BaseDispatchDocumentAction.java
- *
- * @說明: web 應用基礎平臺
- * @date 2005-03-02 11:18:01 AM
- * @版權所有: All Right Reserved 2006-2008
- */
- public abstract class BaseDispatchDocumentAction extends Action {
- protected Class clazz = this.getClass();
- protected static Logger log = Logger.getLogger(BaseDispatchDocumentAction.class);
- /**
- * 異常信息
- */
- protected static ThreadLocal<ExceptionDisplayDTO>
expDisplayDetails = new ThreadLocal<ExceptionDisplayDTO>(); - private static final Long defaultLong = null;
- private static ApplicationContext ctx = null;
- /**
- * 注冊轉換的工具類 使得From中的string --
- * Model中的對應的類型(Date,BigDecimal,Timestamp,Double...)
- */
- static {
- ConvertUtils.register(new ClassConverter(), Double.class);
- ConvertUtils.register(new DateConverter(), Date.class);
- ConvertUtils.register(new DateConverter(), String.class);
- ConvertUtils.register(new LongConverter(defaultLong), Long.class);
- ConvertUtils.register(new IntegerConverter(defaultLong), Integer.class);
- ConvertUtils.register(new TimestampConverter(), Timestamp.class);
- ConvertUtils.register(new BigDecimalConverter(defaultLong), BigDecimal.class);
- }
- /**
- * The message resources for this package.
- */
- protected static MessageResources messages = MessageResources.getMessageResources("org.apache.struts.actions.LocalStrings");
- /**
- * The set of Method objects we have introspected for this class, keyed by
- * method name. This collection is populated as different methods are
- * called, so that introspection needs to occur only once per method name.
- */
- protected HashMap<String, Method> methods = new HashMap<String, Method>();
- /**
- * The set of argument type classes for the reflected method call. These are
- * the same for all calls, so calculate them only once.
- */
- protected Class[] types = { ActionMapping.class, ActionForm.class, Document.class, HttpServletRequest.class,
- HttpServletResponse.class };
- /**
- * Process the specified HTTP request, and create the corresponding HTTP
- * response (or forward to another web component that will create it).
- * Return an <code>ActionForward</code> instance describing where and how
- * control should be forwarded, or <code>null</code> if the response has
- * already been completed.
- *
- * @param mapping
- * The ActionMapping used to select this instance
- * @param form
- * The optional ActionForm bean for this request (if any)
- * @param request
- * The HTTP request we are processing
- * @param response
- * The HTTP response we are creating
- *
- * @exception Exception
- * if an exception occurs
- */
- public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
- HttpServletResponse response) throws Exception {
- response.setContentType("text/html; charset=UTF-8");
- ExceptionDisplayDTO expDTO = null;
- try {
- Document doc = createDocumentFromRequest(request);
- /*
- * 這里直接調用mapping的parameter配置
- */
- String actionMethod = mapping.getParameter();
- /*
- * 校驗配置的方法是否正確、有效
- */
- isValidMethod(actionMethod);
- return dispatchMethod(mapping, form, doc, request, response, actionMethod);
- } catch (BaseAppException ex) {
- expDTO = handlerException(request, response, ex);
- } catch (Exception ex) {
- ExceptionUtil.logException(this.getClass(), ex);
- renderText(response,"[Error :對不起,系統出現錯誤了,請向管理員報告以下異常信息." + ex.getMessage() + "]");
- request.setAttribute(Globals.ERRORMSG, "對不起,系統出現錯誤了,請向管理員報告以下異常信息." + ex.getMessage());
- expDTO = handlerException(request,response, ex);
- } finally {
- expDisplayDetails.set(null);
- }
- return null == expDTO ? null : (expDTO.getActionForwardName() == null ? null : mapping.findForward(expDTO.getActionForwardName()));
- }
- /**
- * 直接輸出純字符串
- */
- public void renderText(HttpServletResponse response, String text) {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- response.setContentType("text/plain;charset=UTF-8");
- out.write(text);
- } catch (IOException e) {
- log.error(e);
- } finally {
- if (out != null) {
- out.flush();
- out.close();
- out = null;
- }
- }
- }
- /**
- * 直接輸出純HTML
- */
- public void renderHtml(HttpServletResponse response, String text) {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- response.setContentType("text/html;charset=UTF-8");
- out.write(text);
- } catch (IOException e) {
- log.error(e);
- } finally {
- if (out != null) {
- out.flush();
- out.close();
- out = null;
- }
- }
- }
- /**
- * 直接輸出純XML
- */
- public void renderXML(HttpServletResponse response, String text) {
- PrintWriter out = null;
- try {
- out = response.getWriter();
- response.setContentType("text/xml;charset=UTF-8");
- out.write(text);
- } catch (IOException e) {
- log.error(e);
- } finally {
- if (out != null) {
- out.flush();
- out.close();
- out = null;
- }
- }
- }
- /**
- * 異常處理
- * @param request
- * @param out
- * @param ex
- * @return ExceptionDisplayDTO異常描述對象
- */
- private ExceptionDisplayDTO handlerException(HttpServletRequest request,HttpServletResponse response, Exception ex) {
- ExceptionDisplayDTO expDTO = (ExceptionDisplayDTO) expDisplayDetails.get();
- if (null == expDTO) {
- expDTO = new ExceptionDisplayDTO(null,this.getClass().getName());
- }
- IExceptionHandler expHandler = ExceptionHandlerFactory.getInstance().create();
- ExceptionDTO exDto = expHandler.handleException(expDTO.getContext(), ex);
- request.setAttribute("ExceptionDTO", exDto);
- renderText(response,"[Error:" + (exDto == null ? "ExceptionDTO is null,請檢查expinfo.xml配置文件." : exDto.getMessageCode())
- + "]");
- return expDTO;
- }
- private void isValidMethod(String actionMethod) throws MappingConfigException {
- if (actionMethod == null || "execute".equals(actionMethod) || "perform".equals(actionMethod)) {
- log.error("[BaseDispatchAction->error] parameter = " + actionMethod);
- expDisplayDetails.set(new ExceptionDisplayDTO(null, "MappingConfigException"));
- throw new MappingConfigException("對不起,配置的方法名不能為 " + actionMethod);
- }
- }
- /**
- * 解析xml流
- * @param request
- * @return Document對象
- */
- protected static Document createDocumentFromRequest(HttpServletRequest request) throws Exception {
- try {
- request.setCharacterEncoding("UTF-8");
- Document document = null;
- SAXReader reader = new SAXReader();
- document = reader.read(request.getInputStream());
- return document;
- } catch (Exception ex) {
- log.warn("TIPS:沒有提交獲取XML格式數據流! ");
- return null;
- }
- }
- /**
- * Dispatch to the specified method.
- *
- * @since Struts 1.1
- */
- protected ActionForward dispatchMethod(ActionMapping mapping, ActionForm form, Document doc,HttpServletRequest request,
HttpServletResponse response, String name) throws Exception { - Method method = null;
- try {
- method = getMethod(name);
- } catch (NoSuchMethodException e) {
- String message = messages.getMessage("dispatch.method", mapping.getPath(), name);
- log.error(message, e);
- expDisplayDetails.set(new ExceptionDisplayDTO(null, "MappingConfigException"));
- throw new MappingConfigException(message, e);
- }
- ActionForward forward = null;
- try {
- Object args[] = { mapping, form, doc, request, response };
- log.debug("[execute-begin] -> " + mapping.getPath() + "->[" + clazz.getName() + "->" + name + "]");
- forward = (ActionForward) method.invoke(this, args);
- log.debug(" [execute-end] -> " + (null == forward ? "use ajax send to html/htm" : forward.getPath()));
- } catch (ClassCastException e) {
- String message = messages.getMessage("dispatch.return", mapping.getPath(), name);
- log.error(message, e);
- throw new BaseAppException(message, e);
- } catch (IllegalAccessException e) {
- String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
- log.error(message, e);
- throw new BaseAppException(message, e);
- } catch (InvocationTargetException e) {
- Throwable t = e.getTargetException();
- String message = messages.getMessage("dispatch.error", mapping.getPath(), name);
- throw new BaseAppException(message, t);
- }
- return (forward);
- }
- /**
- * Introspect the current class to identify a method of the specified name
- * that accepts the same parameter types as the <code>execute</code>
- * method does.
- *
- * @param name
- * Name of the method to be introspected
- *
- * @exception NoSuchMethodException
- * if no such method can be found
- */
- protected Method getMethod(String name) throws NoSuchMethodException {
- synchronized (methods) {
- Method method = (Method) methods.get(name);
- if (method == null) {
- method = clazz.getMethod(name, types);
- methods.put(name, method);
- }
- return (method);
- }
- }
- /**
- * 返回spring bean對象
- * @param name Spring Bean的名稱
- * @exception BaseAppException
- */
- protected Object getSpringBean(String name) throws BaseAppException {
- if (ctx == null) {
- ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServlet().getServletContext());
- }
- Object bean = null;
- try {
- bean = ctx.getBean(name);
- } catch (BeansException ex) {
- throw new NoSuchBeanConfigException("對不起,您沒有配置名為:" + name + "的bean。請檢查配置文件!", ex.getRootCause());
- }
- if (null == bean) {
- throw new NoSuchBeanConfigException("對不起,您沒有配置名為:" + name + "的bean。請檢查配置文件!");
- }
- return bean;
- }
- }
請記住本文永久地址:
http://www.javaresource.org/struts/struts-75614.html