
org.eweb4j.mvc.action.ActionExecution Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eweb4j-all Show documentation
Show all versions of eweb4j-all Show documentation
easy web framework for java, full-stack
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 = "";
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