All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eweb4j.mvc.action.ActionExecution Maven / Gradle / Ivy

The newest version!
package org.eweb4j.mvc.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eweb4j.cache.ActionConfigBeanCache;
import org.eweb4j.cache.SingleBeanCache;
import org.eweb4j.config.Log;
import org.eweb4j.config.LogFactory;
import org.eweb4j.ioc.IOC;
import org.eweb4j.mvc.Context;
import org.eweb4j.mvc.CookieProxy;
import org.eweb4j.mvc.Http;
import org.eweb4j.mvc.HttpSessionProxy;
import org.eweb4j.mvc.MIMEType;
import org.eweb4j.mvc.ParamUtil;
import org.eweb4j.mvc.ServletContextProxy;
import org.eweb4j.mvc.action.annotation.Ioc;
import org.eweb4j.mvc.action.annotation.Singleton;
import org.eweb4j.mvc.action.annotation.Transactional;
import org.eweb4j.mvc.config.ActionClassCache;
import org.eweb4j.mvc.config.ConsumesUtil;
import org.eweb4j.mvc.config.JAXWSUtil;
import org.eweb4j.mvc.config.MVCConfigConstant;
import org.eweb4j.mvc.config.PathUtil;
import org.eweb4j.mvc.config.ProducesUtil;
import org.eweb4j.mvc.config.QueryParamUtil;
import org.eweb4j.mvc.config.bean.ActionConfigBean;
import org.eweb4j.mvc.config.bean.ResultConfigBean;
import org.eweb4j.mvc.interceptor.After;
import org.eweb4j.mvc.interceptor.Before;
import org.eweb4j.mvc.interceptor.InterExecution;
import org.eweb4j.mvc.upload.UploadFile;
import org.eweb4j.mvc.validator.ValidateExecution;
import org.eweb4j.mvc.validator.annotation.DateFormat;
import org.eweb4j.mvc.validator.annotation.Upload;
import org.eweb4j.mvc.view.JSPRendererImpl;
import org.eweb4j.mvc.view.RenderFactory;
import org.eweb4j.mvc.view.Renderer;
import org.eweb4j.orm.dao.DAO;
import org.eweb4j.orm.dao.DAOFactory;
import org.eweb4j.orm.dao.DAOImpl;
import org.eweb4j.orm.dao.cascade.CascadeDAO;
import org.eweb4j.orm.dao.delete.DeleteDAO;
import org.eweb4j.orm.dao.insert.InsertDAO;
import org.eweb4j.orm.dao.select.DivPageDAO;
import org.eweb4j.orm.dao.select.SearchDAO;
import org.eweb4j.orm.dao.select.SelectDAO;
import org.eweb4j.orm.dao.update.UpdateDAO;
import org.eweb4j.orm.jdbc.transaction.Trans;
import org.eweb4j.orm.jdbc.transaction.Transaction;
import org.eweb4j.util.ClassUtil;
import org.eweb4j.util.CommonUtil;
import org.eweb4j.util.ReflectUtil;
import org.eweb4j.util.xml.BeanXMLUtil;
import org.eweb4j.util.xml.XMLWriter;

/**
 * Action 执行器
 * 
 * @author weiwei
 * @since 1.b.8
 * 
 */
@SuppressWarnings("all")
public class ActionExecution {

	private static Log log = LogFactory.getMVCLogger(ActionExecution.class);

	// 要执行的Action方法
	private Method method;
	private Field[] fields;
	
	private Context context;

	private Object actionObject;
	private Object retn;

	private ReflectUtil ru;

	// 验证器
	private void handleValidator() throws Exception {
		context.setValidation(ValidateExecution.execute(context));
	}

	public ActionExecution(String uri, String httpMethod, Context context) {
		this.context = context;
		this.context.setUri(uri);
		this.context.setHttpMethod(httpMethod);
	}

	public boolean findAction() throws Exception {
		// URL参数
		Map> pathParams = null;
		if (ActionConfigBeanCache.containsKey(this.context.getUri()) 
				|| (pathParams = ActionConfigBeanCache.getByMatches(this.context.getUri(), this.context.getHttpMethod())) != null) {
			// 处理形如" /xxx/{id}/{name} "的URI
			if (pathParams != null && pathParams.containsKey("mvcBean")) {
				// 根据Url配置的UrlParam获取参数值
				this.context.setActionConfigBean((ActionConfigBean) pathParams.get("mvcBean").get(0));
				Map pathParamMap = ParamUtil.getPathParamMap(pathParams);
//				System.out.println("pp->\n\t"+pathParamMap);
				this.context.getPathParamMap().putAll(pathParamMap);
//				System.out.println("pp222->\n\t"+this.context.getPathParamMap());
				this.context.getQueryParamMap().putAll(this.context.getPathParamMap());
			} else
				this.context.setActionConfigBean(ActionConfigBeanCache.get(this.context.getUri()));

			if (this.context.getActionConfigBean() != null)
				return true;
		}

		return false;
	}

	private Object initPojo() throws Exception {
		Class clazz = ActionClassCache.get(this.context.getActionConfigBean().getClazz());
		Annotation singletonAnn = clazz.getAnnotation(Singleton.class);
		if (singletonAnn != null) {
			this.actionObject = SingleBeanCache.get(clazz.getName());
			if (this.actionObject == null) {
				this.actionObject = clazz.newInstance();
				SingleBeanCache.add(clazz.getName(), this.actionObject);
			}
		} else
			this.actionObject = clazz.newInstance();

		ru = new ReflectUtil(this.actionObject);

		return this.actionObject;
	}

	// IOC,注入对象到pojo
	private void injectIocBean() throws Exception {
		fields = ru.getFields();
		if (fields == null)
			return;

		for (Field f : fields) {
			Class type = f.getType();

			Ioc ioc = f.getAnnotation(Ioc.class);
			if (ioc == null)
				continue;
			String beanId = "";
			if (ioc.value().trim().length() == 0)
				beanId = type.getSimpleName();
			else
				beanId = CommonUtil.parsePropValue(ioc.value());

			Method setter = ru.getSetter(f.getName());
			if (setter == null)
				continue;

			setter.invoke(this.actionObject, IOC.getBean(beanId));
		}
	}

	private void exeActionLog() {
		StringBuilder sb = new StringBuilder();
		sb.append("handle http -> ")
			.append(this.context.getUri())
			.append(", ").append(this.context.getHttpMethod())
			.append(" by ")
			.append(this.context.getActionConfigBean().getClazz())
			.append(".")
			.append(this.context.getActionConfigBean().getMethod());
		log.debug(sb.toString());
	}

	private Object[] assemParams(Class[] paramTypes, Annotation[][] paramAnns)throws Exception {
		Object[] params = new Object[paramTypes.length];
		int pathParamIndex = 0;
		for (int i = 0; i < paramTypes.length; ++i) {
			Annotation[] anns = paramAnns[i];
			Class paramClass = paramTypes[i];
			String[] paramValue = null;
			// ------------------------------------------------------
			// 通过给定class 获取对应的ActionContextObj
			if (Context.class.isAssignableFrom(paramClass)) {
				params[i] = this.context;
				continue;
			}

			if (HttpServletRequest.class.isAssignableFrom(paramClass)) {
				params[i] = this.context.getRequest();
				continue;
			}

			if (HttpServletResponse.class.isAssignableFrom(paramClass)) {
				params[i] = this.context.getResponse();
				continue;
			}

			if (PrintWriter.class.isAssignableFrom(paramClass)) {
				params[i] = this.context.getWriter();
				continue;
			}

			if (ServletOutputStream.class.isAssignableFrom(paramClass)) {
				params[i] = this.context.getOut();
				continue;
			}

			if (HttpSession.class.isAssignableFrom(paramClass)) {
				params[i] = this.context.getSession();
				continue;
			}

			if (ActionProp.class.isAssignableFrom(paramClass)) {
				if (this.context.getActionProp() == null)
					this.context.setActionProp(new ActionProp(this.actionObject.getClass().getName()));

				params[i] = this.context.getActionProp();
				continue;
			}

			if (Validation.class.isAssignableFrom(paramClass)) {
				params[i] = this.context.getValidation();
				continue;
			}

			if (QueryParams.class.isAssignableFrom(paramClass)) {
				params[i] = this.context.getQueryParams();
				continue;
			}

			if (DAO.class.isAssignableFrom(paramClass)) {
				params[i] = new DAOImpl("");
				continue;
			}

			if (InsertDAO.class.isAssignableFrom(paramClass)) {
				params[i] = DAOFactory.getInsertDAO();
				continue;
			}

			if (DeleteDAO.class.isAssignableFrom(paramClass)) {
				params[i] = DAOFactory.getDeleteDAO();
				continue;
			}

			if (UpdateDAO.class.isAssignableFrom(paramClass)) {
				params[i] = DAOFactory.getUpdateDAO();
				continue;
			}

			if (SelectDAO.class.isAssignableFrom(paramClass)) {
				params[i] = DAOFactory.getSelectDAO();
				continue;
			}

			if (DivPageDAO.class.isAssignableFrom(paramClass)) {
				params[i] = DAOFactory.getDivPageDAO();
				continue;
			}

			if (SearchDAO.class.isAssignableFrom(paramClass)) {
				params[i] = DAOFactory.getSearchDAO();
				continue;
			}

			if (CascadeDAO.class.isAssignableFrom(paramClass)) {
				params[i] = DAOFactory.getCascadeDAO();
				continue;
			}

//			PathParam pathParamAnn = this.getPathParamAnn(anns);
			Annotation pathParam = JAXWSUtil.getPathParam(anns);
            if (pathParam != null) {
                paramValue = this.getPathParamValue(PathUtil.getPathParamValue(pathParam));
                params[i] = ClassUtil.getParamVal(paramClass, paramValue[0]);
                continue;
            }

//			QueryParam queryParamAnn = this.getQueryParamAnn(anns);
            Annotation queryParamAnn = JAXWSUtil.getQueryParam(anns);
            if (queryParamAnn == null && Map.class.isAssignableFrom(paramClass)) {
                params[i] = this.context.getModel();
                continue;
            }

            //若参数有@QueryParam注解
            if (queryParamAnn != null) {
            	final String fieldName = QueryParamUtil.getQueryParamValue(queryParamAnn);
				if (File.class.isAssignableFrom(paramClass)) {
					if (!this.context.getUploadMap().containsKey(fieldName))
						continue;
					List list = this.context.getUploadMap().get(fieldName);
					if (list == null || list.isEmpty())
						continue;
					
					UploadFile uploadFile = list.get(0);
					File file = uploadFile.getTmpFile();
					params[i] = file;
					
					continue;
				}
				
				if (File[].class.isAssignableFrom(paramClass)){
					if (!this.context.getUploadMap().containsKey(fieldName))
						continue;
					List list = this.context.getUploadMap().get(fieldName);
					if (list == null || list.isEmpty())
						continue;
					File[] files = new File[list.size()];
					for (int j = 0; j < files.length; j++)
						files[j] = list.get(j).getTmpFile();
					
					params[i] = files;
				}
				
				if (UploadFile.class.isAssignableFrom(paramClass)) {
					if (!this.context.getUploadMap().containsKey(fieldName))
						continue;
					List list = this.context.getUploadMap().get(fieldName);
					if (list == null || list.isEmpty())
						continue;
					
					UploadFile uploadFile = list.get(0);
					params[i] = uploadFile;
					
					continue;
				}
				
				if (UploadFile[].class.isAssignableFrom(paramClass)){
					if (!this.context.getUploadMap().containsKey(fieldName))
						continue;
					List list = this.context.getUploadMap().get(fieldName);
					if (list == null || list.isEmpty())
						continue;
					
					params[i] = list.toArray(new UploadFile[]{});
				}
				
				// 根据参数名称获取http对应的参数值
				String defaultValue = null;
//				DefaultValue defaultValueAnn = this.getDefaultValueAnn(anns);
				Annotation defaultValueAnn = JAXWSUtil.getDefaultValue(anns);
				if (defaultValueAnn != null)
					defaultValue = QueryParamUtil.getDefaultValue(defaultValueAnn);
	
				paramValue = this.getQueryParamValue(fieldName, defaultValue);
				
				// 处理Date日期类型的参数
				if (java.util.Date.class.isAssignableFrom(paramClass)) {
					params[i] = this.getDateParam(anns, paramValue[0]);
					continue;
				}
	
				// 处理POJO类型的参数
				String startName = fieldName;
				if (ClassUtil.isPojo(paramClass)) {
					params[i] = this.injectParam2Pojo(paramClass, startName);
					continue;
				}
	
				// 处理Map类型的参数
				if (Map.class.isAssignableFrom(paramClass)) {
					params[i] = this.injectParam2Map(startName);
					continue;
				}
	
				//处理数组类型的参数
				if (paramClass.isArray())
					params[i] = ClassUtil.getParamVals(paramClass, paramValue);
				else
					params[i] = ClassUtil.getParamVal(paramClass, paramValue[0]);
            } else {
				// 如果是基本数据类型,则按照排序进行注入
            	String[] pathParams = this.context.getActionConfigBean().getPathParams();
            	if (pathParams == null){
            		log.warn("QueryParam not found and PathParam not found too");
            		continue;
            	}
            	
				paramValue = this.getPathParamValue(pathParams[pathParamIndex]);
				params[i] = ClassUtil.getParamVal(paramClass, paramValue[0]);
				pathParamIndex++;
				continue;
			}
		}

		return params;
	}

	private Method getFirstMethd(Method[] methods) {
		Method m = methods[0];
		if (methods.length == 1)
			return m;

		// 如果含有两个或以上同名的方法,优先拿到被@Path注解的第一个方法
		for (Method mm : methods) {
//			Path p = mm.getAnnotation(Path.class);
			boolean hasPath = JAXWSUtil.hasPath(mm);
			if (!hasPath)
				continue;

			m = mm;
			break;
		}

		return m;
	}

	private String[] getQueryParamValue(String paramName, String defaultValue) {
		String[] paramValue = this.context.getQueryParamMap().get(paramName);

		return getParamValue(paramValue, defaultValue);
	}

	private String[] getPathParamValue(String pathParamName) {
		String[] paramValue = this.context.getPathParamMap().get(pathParamName);

		return getParamValue(paramValue, null);
	}

	private String[] getParamValue(String[] paramValue, String defaultValue) {
		if (paramValue == null || paramValue.length == 0 || paramValue[0] == null) {
			if (defaultValue != null)
				paramValue = new String[] { defaultValue };
			else
				paramValue = new String[] { "" };
		}

		return paramValue;
	}

	private Date getDateParam(Annotation[] anns, String paramValue)
			throws Exception {
		DateFormat dateAnn = null;
		for (Annotation a : anns) {
			if (a == null)
				continue;

			if (!a.annotationType().isAssignableFrom(DateFormat.class))
				continue;

			dateAnn = (DateFormat) a;
			break;
		}

		String pattern = "yyyy-MM-dd HH:mm:ss";
		if (dateAnn != null)
			pattern = dateAnn.value();

		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.parse(paramValue);
	}

	private Object injectParam2Pojo(Class paramClass, String startName)
			throws Exception {
		Object paramObj = paramClass.newInstance();
		ReflectUtil ru = new ReflectUtil(paramObj);
		this.injectActionCxt2Pojo(ru);
		// 注入mvc action 请求参数
		ParamUtil.injectParam(this.context, ru, startName);
		return paramObj;
	}

	private Object injectParam2Map(String startName) throws Exception {
		Map map = new HashMap();
		ReflectUtil ru = new ReflectUtil(map);
		this.injectActionCxt2Pojo(ru);
		// 注入mvc action 请求参数
		ParamUtil.injectParam(this.context, ru, startName);

		return map;
	}

//	private PathParam getPathParamAnn(Annotation[] anns) {
//		for (Annotation a : anns) {
//			if (a == null)
//				continue;
//
//			if (!a.annotationType().isAssignableFrom(PathParam.class))
//				continue;
//
//			return (PathParam) a;
//		}
//
//		return null;
//	}

//	private QueryParam getQueryParamAnn(Annotation[] anns) {
//		for (Annotation a : anns) {
//			if (a == null)
//				continue;
//
//			if (!a.annotationType().isAssignableFrom(QueryParam.class))
//				continue;
//
//			return (QueryParam) a;
//		}
//
//		return null;
//	}
//	
//	private DefaultValue getDefaultValueAnn(Annotation[] anns) {
//		for (Annotation a : anns) {
//			if (a == null)
//				continue;
//
//			if (!a.annotationType().isAssignableFrom(DefaultValue.class))
//				continue;
//
//			return (DefaultValue) a;
//		}
//
//		return null;
//	}

	private void handleDownload(File file) throws Exception{
		if (file.exists()){
			HttpServletResponse response = this.context.getResponse();
			String filename = URLEncoder.encode(file.getName(), "utf-8");
            response.reset();
            response.setContentType("application/x-msdownload");
            response.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
            int fileLength = (int) file.length();
            response.setContentLength(fileLength);
            /*如果文件长度大于0*/
            if (fileLength != 0) {
                /*创建输入流*/
                InputStream inStream = new FileInputStream(file);
                byte[] buf = new byte[4096];
                /*创建输出流*/
                ServletOutputStream servletOS = response.getOutputStream();
                int readLength;
                while (((readLength = inStream.read(buf)) != -1)) {
                    servletOS.write(buf, 0, readLength);
                }
                inStream.close();
                servletOS.flush();
                servletOS.close();
            }
		}
	}
	
	private void handleResult() throws Exception {

		this.exeActionLog();
		if (retn == null)
			return;
		String baseUrl = (String) this.context.getServletContext().getAttribute(MVCConfigConstant.BASE_URL_KEY);
		if (File.class.isAssignableFrom(retn.getClass())){
			File file = (File)retn;
			this.handleDownload(file);
			return ;
		}else if(File[].class.isAssignableFrom(retn.getClass())){
			File[] files = (File[])retn;
			
			String fileName = CommonUtil.getNowTime("yyyyMMddHHmmss")+ "_" + "download.zip";
			
			HttpServletResponse resp = this.context.getResponse();
			resp.reset();
			resp.setContentType("application/zip");  
            resp.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
	          
	        ServletOutputStream outputStream = resp.getOutputStream();  
	        ZipOutputStream zip = new ZipOutputStream(outputStream);  
	       
	        for (File file :files){
	        	byte[] b = new byte[1024];  
	 	        int len;  
	        	zip.putNextEntry(new ZipEntry(file.getName()));  
	        	FileInputStream fis = new FileInputStream(file);  
	 	        while ((len = fis.read(b)) != -1) {  
	 	            zip.write(b, 0, len);  
	 	        }  
	 	        
	 	        fis.close();
	        }
	          
	        zip.flush();  
	        zip.close();  
	        outputStream.flush();  
			
			return;
		}
		
		if (!String.class.isAssignableFrom(retn.getClass())) {
			String mimeType = null;
			boolean hasProduces = JAXWSUtil.hasProduces(method);
			if (hasProduces){
				String[] mimeTypes = ProducesUtil.getProducesValue(method);
				if (mimeTypes != null && mimeTypes.length > 0)
					mimeType = mimeTypes[0];
			}
			
			if (mimeType == null || mimeType.trim().length() == 0)
				mimeType = this.context.getRequest().getParameter(MVCConfigConstant.HTTP_HEADER_ACCEPT_PARAM);
			
			if (mimeType == null || mimeType.trim().length() == 0){
				String contentType = this.context.getRequest().getContentType();
				if (contentType != null){
					this.context.getResponse().setContentType(contentType);
					mimeType = contentType.split(";")[0];
				}
			}
			
			if (this.context.getWriter() == null)
				this.context.setWriter(this.context.getResponse().getWriter());
			
			if (MIMEType.JSON.equals(mimeType) || "json".equalsIgnoreCase(mimeType)) {
				this.context.getResponse().setContentType(MIMEType.JSON);
				this.context.getWriter().print(CommonUtil.toJson(retn));
			} else if (MIMEType.XML.equals(mimeType) || "xml".equalsIgnoreCase(mimeType)) {
				Class cls = retn.getClass();
				if (Collection.class.isAssignableFrom(cls)) {
					Class _cls = ClassUtil.getPojoClass(this.method);
					if (_cls != null)
						cls = _cls;
				}

				XMLWriter writer = BeanXMLUtil.getBeanXMLWriter(retn);
				writer.setCheckStatck(true);
				writer.setSubNameAuto(true);
				writer.setClass(cls);
				writer.setRootElementName(null);
				this.context.getResponse().setContentType(MIMEType.XML);
				this.context.getWriter().print(writer.toXml());
			} else {
				//默认都用json
				this.context.getResponse().setContentType(MIMEType.JSON);
				this.context.getWriter().print(CommonUtil.toJson(retn));
			}
			
//			this.context.getWriter().flush();

			return;
		}

		List produces = this.context.getActionConfigBean().getProduces();
		if (produces != null && produces.size() > 0)
			for (String produce : produces) {
                this.context.getResponse().setContentType(produce);
				break;
			}

		String re = String.valueOf(retn);

		//model driven
		for (Field f : fields) {
			Method getter = ru.getGetter(f.getName());
			if (getter == null)
				continue;

			String name = f.getName();
			if (this.context.getModel().containsKey(name))
				continue;
			
			this.context.getModel().put(name, getter.invoke(actionObject));
		}
		
		this.context.getModel().put(MVCConfigConstant.BASE_URL_KEY, this.context.getServletContext().getAttribute(MVCConfigConstant.BASE_URL_KEY));
		this.context.getModel().put(MVCConfigConstant.APPLICATION_SCOPE_KEY, new ServletContextProxy(this.context.getServletContext()).attrs());
		this.context.getModel().put(MVCConfigConstant.SESSION_SCOPE_KEY, new HttpSessionProxy(this.context.getSession()).attrs());
		this.context.getModel().put(MVCConfigConstant.COOKIE_SCOPE_KEY, new CookieProxy(this.context.getRequest().getCookies()).attrs());
		this.context.getModel().put(MVCConfigConstant.REQ_PARAM_SCOPE_KEY, this.context.getQueryParamMap());
		
		// 客户端重定向
		if (re.startsWith(RenderType.REDIRECT + ":")) {
			String url = re.substring((RenderType.REDIRECT + ":").length());
			String location = url;

			this.context.getResponse().sendRedirect(CommonUtil.replaceChinese2Utf8(location));

			return;
		} else if (re.startsWith(RenderType.ACTION + ":")) {
			String path = re.substring((RenderType.ACTION + ":").length());
			// ACTION 重定向
			handleActionRedirect(context, path, baseUrl);

			return;
		} else if (re.startsWith(RenderType.OUT + ":")) {
			String location = re.substring((RenderType.OUT + ":").length());
			this.context.getWriter().print(location);
//			this.context.getWriter().flush();

			return;
		} else if (re.startsWith(RenderType.FORWARD + ":") 
				|| re.startsWith(RenderType.JSP + ":")
				|| re.endsWith("."+RenderType.JSP)) {
			String[] str = re.split("@");
			re = str[0];
			String location = re;
			if (re.startsWith(RenderType.FORWARD + ":"))
				location = re.substring((RenderType.FORWARD + ":").length());
			else if (re.startsWith(RenderType.JSP + ":"))
				location = re.substring((RenderType.JSP + ":").length());
			
			//渲染JSP
	        JSPRendererImpl render = new JSPRendererImpl();
	        render.setContext(context);
	        if (str.length > 1)
	        	render.layout(str[1]);
	        
	        render.target(location).render(context.getWriter(), context.getModel());
			
			return;
		} else if (re.startsWith(RenderType.FREEMARKER + ":") 
				|| re.startsWith(RenderType.FREEMARKER2 + ":")
				|| re.endsWith("."+RenderType.FREEMARKER2)) {
			String[] str = re.split("@");
			re = str[0];
			String location = re;
			if (re.startsWith(RenderType.FREEMARKER + ":"))
				location = re.substring((RenderType.FREEMARKER + ":").length());
			else if (re.startsWith(RenderType.FREEMARKER2 + ":"))
				location = re.substring((RenderType.FREEMARKER2 + ":").length());
			
			//渲染Freemarker
	        Renderer render = RenderFactory.create(RenderType.FREEMARKER).target(location);
	        if (str.length > 1)
	        	render.layout(str[1]);
	        
	        render.render(context.getWriter(), context.getModel());
			
//	        this.context.getWriter().flush();
			return;
		}else if (re.startsWith(RenderType.VELOCITY + ":") 
				|| re.startsWith(RenderType.VELOCITY2 + ":")
				|| re.endsWith("."+RenderType.VELOCITY2)) {
			String[] str = re.split("@");
			re = str[0];
			String location = re;
			if (re.startsWith(RenderType.VELOCITY + ":"))
				location = re.substring((RenderType.VELOCITY + ":").length());
			else if (re.startsWith(RenderType.VELOCITY2 + ":"))
				location = re.substring((RenderType.VELOCITY2 + ":").length());
			
			//渲染Velocity
	        Renderer render = RenderFactory.create(RenderType.VELOCITY).target(location);
	        if (str.length > 1)
	        	render.layout(str[1]);
	        
	        render.render(context.getWriter(),context.getModel());
			
//	        this.context.getWriter().flush();
			return;
		} else {
			List results = this.context.getActionConfigBean().getResult();

			if (results == null || results.size() == 0) {
				this.context.getWriter().print(retn);
//				this.context.getWriter().flush();
				return;
			}

			boolean isOut = true;
			for (ResultConfigBean r : results) {
				if (!"_props_".equals(r.getName()) && !r.getName().equals(re)
						&& !"".equals(re)){
					continue;
				}
				
				isOut = false;
				String type = r.getType();
				String location = r.getLocation();
				
				if (RenderType.REDIRECT.equalsIgnoreCase(type)) {
					this.context.getResponse().sendRedirect(CommonUtil.replaceChinese2Utf8(location));
					return ;
				} else if (RenderType.FORWARD.equalsIgnoreCase(type)
						|| RenderType.JSP.equalsIgnoreCase(type)) {
					//渲染JSP
					String[] str = location.split("@");
			        JSPRendererImpl render = new JSPRendererImpl();
			        render.setContext(context);
			        if (str.length > 1)
			        	render.layout(str[1]);
			        
			        render.target(str[0]).render(context.getWriter(), context.getModel());
			        
					return ;
				} else if (RenderType.FREEMARKER.equalsIgnoreCase(type)
						|| RenderType.FREEMARKER2.equalsIgnoreCase(type)) {
					//渲染Freemarker
					String[] str = location.split("@");
			        Renderer render = RenderFactory.create(RenderType.FREEMARKER).target(str[0]);
			        if (str.length > 1)
			        	render.layout(str[1]);
			        render.render(context.getWriter(), context.getModel());
//			        this.context.getWriter().flush();
			        
					return ;
				} else if (RenderType.VELOCITY.equalsIgnoreCase(type)
						|| RenderType.VELOCITY2.equalsIgnoreCase(type)){
					//渲染Velocity
					String[] str = location.split("@");
			        Renderer render = RenderFactory.create(RenderType.VELOCITY).target(str[0]);
			        if (str.length > 1)
			        	render.layout(str[1]);
			        render.render(context.getWriter(),context.getModel());
//			        this.context.getWriter().flush();
			        
			        return ;
				} else if (RenderType.ACTION.equalsIgnoreCase(type)) {
					
					// ACTION 重定向
					handleActionRedirect(context, location, baseUrl);

					return ;
				} else if (RenderType.OUT.equalsIgnoreCase(type)
						|| location.trim().length() == 0) {
					this.context.getWriter().print(location);
//					this.context.getWriter().flush();
					
					return ;
				} 
			}
			
			if (isOut){
				this.context.getWriter().print(retn);
//				this.context.getWriter().flush();
			}
		}

	}

	public static void handleActionRedirect(Context context, String path, String baseUrl)
			throws IOException {
		String method;
		String location;
		if (!path.contains("@")) {
			method = Http.Method.GET;
			location = path;
		} else {
			int lastIndex = path.indexOf("@") + 1;
			method = path.substring(lastIndex);
			location = path.substring(0, lastIndex - 1);
		}
		StringBuilder sb = new StringBuilder("");
		String param = null;
		if (path.contains("?")) {
			int lastIndex2 = path.indexOf("?") + 1;
			param = path.substring(lastIndex2);
			String[] params = param.split("&");
			for (String para : params) {
				String[] p = para.split("=");
				sb.append(String.format("", p[0], p[1]));
			}

			method = method.substring(0, method.indexOf("?"));
		}

		if (Http.Method.GET.equalsIgnoreCase(method)) {
			String pa = param == null ? "" : "?" + CommonUtil.replaceChinese2Utf8(param);
			context.getResponse().sendRedirect(baseUrl + location + pa);
			return;
		}

		String _method = "";
		if (Http.Method.PUT.equalsIgnoreCase(method) || Http.Method.DELETE.equalsIgnoreCase(method)) {
			_method = new String(method);
			method = Http.Method.POST;
		}

		String action = baseUrl + location;
		// 构造一个Form表单模拟客户端发送新的Action请求
		String format = "
%s
"; String form = String.format(format, action, method, _method, sb.toString()); String js = ""; context.getWriter().print(form + js); } /** * 执行Action * * @param methodName * @throws Exception */ private void excuteMethod(String methodName) throws Exception{ boolean isTrans = false; if (method.getAnnotation(Transactional.class) != null) isTrans = true; else if (actionObject.getClass().getAnnotation(Transactional.class) != null) isTrans = true; Class[] paramTypes = method.getParameterTypes(); // 无参数运行方法 if (paramTypes == null || paramTypes.length == 0) { // 无参数运行方法 if (isTrans) Transaction.execute(new Trans() { @Override public void run(Object... args) throws Exception { retn = method.invoke(actionObject); } }, ""); else retn = method.invoke(actionObject); } else { Annotation[][] paramAnns = method.getParameterAnnotations(); // 拿到方法所需要的参数 final Object[] params = assemParams(paramTypes, paramAnns); // 带参数运行方法 if (isTrans) Transaction.execute(new Trans() { @Override public void run(Object... args) throws Exception { retn = method.invoke(actionObject, params); } }, ""); else retn = method.invoke(actionObject, params); } } private void injectActionCxt2Pojo(ReflectUtil ru) throws Exception { HttpServletRequest req = this.context.getRequest(); HttpServletResponse res = this.context.getResponse(); PrintWriter out = this.context.getWriter(); HttpSession session = this.context.getSession(); ActionProp actionProp = this.context.getActionProp(); QueryParams queryParams = this.context.getQueryParams(); for (String n : ru.getFieldsName()) { Method m = ru.getSetter(n); if (m == null) continue; Class clazz = m.getParameterTypes()[0]; if (Context.class.isAssignableFrom(clazz)) { m.invoke(ru.getObject(), this.context); } else if (HttpServletRequest.class.isAssignableFrom(clazz)) { m.invoke(ru.getObject(), req); } else if (HttpServletResponse.class.isAssignableFrom(clazz)) { m.invoke(ru.getObject(), res); } else if (PrintWriter.class.isAssignableFrom(clazz)) { m.invoke(ru.getObject(), out); } else if (ServletOutputStream.class.isAssignableFrom(clazz)) { m.invoke(ru.getObject(), this.context.getOut()); } else if (HttpSession.class.isAssignableFrom(clazz)) { m.invoke(ru.getObject(), session); } else if (ActionProp.class.isAssignableFrom(clazz)) { if (actionProp == null) actionProp = new ActionProp(clazz.getName()); this.context.setActionProp(actionProp); m.invoke(ru.getObject(), actionProp); } else if (QueryParams.class.isAssignableFrom(clazz)) { m.invoke(ru.getObject(), queryParams); } else if (Validation.class.isAssignableFrom(clazz)) { m.invoke(ru.getObject(), this.context.getValidation()); } else { /* 如果找不到注入的类型,则尝试从IOC容器获取 */ Object obj = IOC.getBean(n); if (obj != null) m.invoke(ru.getObject(), obj); } } } /** * 执行Action * * @throws Exception */ public void execute() throws Exception { // 实例化pojo initPojo(); // IOC注入对象到pojo中 injectIocBean(); String methodName = this.context.getActionConfigBean().getMethod(); Method[] methods = ru.getMethods(methodName); if (methods == null || methods.length == 0) return; method = this.getFirstMethd(methods); if (method == null) return; // Consumes cons = method.getAnnotation(Consumes.class); boolean hasConsumes = JAXWSUtil.hasConsumes(method); if (hasConsumes) { String[] cts = ConsumesUtil.getConsumesValue(method); for (String ct : cts){ if ("json".equals(ct) || MIMEType.JSON.equals(ct)){ String[] jss = this.context.getQueryParamMap().get("_json_data_"); if (jss != null) { for (String json : jss){ Map map; try { map = CommonUtil.parse(json, Map.class); }catch (Exception e){ e.printStackTrace(); break; } for (Iterator> it = map.entrySet().iterator(); it.hasNext(); ){ Entry e = it.next(); String key = e.getKey(); String val = String.valueOf(e.getValue()); //继续解析,如果解析成功说明是多级的json格式,最后将其平展开来 try { Map subMap = CommonUtil.parse(val, Map.class); for (Iterator> subIt = subMap.entrySet().iterator(); subIt.hasNext(); ){ Entry subE = subIt.next(); String subKey = subE.getKey(); String subVal = String.valueOf(subE.getValue()); String newKey = key+"."+subKey; try { Map subSubMap = CommonUtil.parse(subVal, Map.class); for (Iterator> subSubIt = subSubMap.entrySet().iterator(); subSubIt.hasNext(); ){ Entry subSubE = subSubIt.next(); String subSubKey = subSubE.getKey(); String subSubVal = String.valueOf(subSubE.getValue()); String newSubKey = newKey+"."+subSubKey; assemJsonData(newSubKey, subSubVal); } }catch (Exception ex2){ assemJsonData(newKey, subVal); } } }catch (Exception ex){ assemJsonData(key, val); } } } } } } } // 注入框架mvc action 上下文环境 this.injectActionCxt2Pojo(this.ru); // if (IAction.class.isAssignableFrom(this.actionObject.getClass())) { // // struts2风格 // IAction action = (IAction) actionObject; // action.init(this.context); // retn = action.execute(); // // 对Action执行返回结果的处理 // this.handleResult(); // // return ; // } // 执行验证器 this.handleValidator(); try{ // 注入mvc action 请求参数 ParamUtil.injectParam(this.context, this.ru, null); /* 方法体内的前置拦截器执行 */ Before before = method.getAnnotation(Before.class); if (before != null){ InterExecution before_interExe = new InterExecution("before", context); before_interExe.execute(before.value()); if (before_interExe.getError() != null){ before_interExe.showErr(); return ; } } // execute the action method excuteMethod(methodName); /* 方法体内的后置拦截器执行 */ After after = method.getAnnotation(After.class); if (after != null){ // 后置拦截器 InterExecution after_interExe = new InterExecution("after", context); after_interExe.execute(after.value()); if (after_interExe.getError() != null){ after_interExe.showErr(); return ; } } /* 外部配置的后置拦截器后执行 */ InterExecution after_interExe = new InterExecution("after", this.context);// 7.后置拦截器 if (after_interExe.findAndExecuteInter()) { after_interExe.showErr(); return; } // 对Action执行返回结果的处理 this.handleResult(); }catch(Exception e){ throw e; } } private void assemJsonData(String key, String val) { List vals = new ArrayList(); String[] _vals = this.context.getQueryParamMap().get(key); if (_vals != null){ vals.addAll(Arrays.asList(_vals)); } vals.add(val); this.context.getQueryParamMap().put(key, vals.toArray(new String[]{})); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy