package com.geccocrawler.gecco.spider.render.html; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.reflections.ReflectionUtils; import com.geccocrawler.gecco.annotation.Ajax; import com.geccocrawler.gecco.downloader.DownloadException; import com.geccocrawler.gecco.downloader.DownloaderContext; import com.geccocrawler.gecco.request.HttpRequest; import com.geccocrawler.gecco.response.HttpResponse; import com.geccocrawler.gecco.spider.JsonBean; import com.geccocrawler.gecco.spider.SpiderBean; import com.geccocrawler.gecco.spider.render.FieldRender; import com.geccocrawler.gecco.spider.render.FieldRenderException; import com.geccocrawler.gecco.spider.render.Render; import com.geccocrawler.gecco.spider.render.RenderContext; import com.geccocrawler.gecco.spider.render.RenderType; import com.geccocrawler.gecco.utils.ReflectUtils; import com.geccocrawler.gecco.utils.UrlMatcher; import net.sf.cglib.beans.BeanMap; /** * 渲染@Ajax属性 * * @author huchengyi * */ public class AjaxFieldRender implements FieldRender { @Override @SuppressWarnings("unchecked") public void render(HttpRequest request, HttpResponse response, BeanMap beanMap, SpiderBean bean) { Map<String, Object> fieldMap = new HashMap<String, Object>(); Set<Field> ajaxFields = ReflectionUtils.getAllFields(bean.getClass(), ReflectionUtils.withAnnotation(Ajax.class)); for (Field ajaxField : ajaxFields) { Object value = injectAjaxField(request, beanMap, ajaxField); if(value != null) { fieldMap.put(ajaxField.getName(), value); } } beanMap.putAll(fieldMap); } @SuppressWarnings({ "rawtypes", "unchecked" }) private Object injectAjaxField(HttpRequest request, BeanMap beanMap, Field field) { Class clazz = field.getType(); // ajax的属性类型必须是spiderBean Ajax ajax = field.getAnnotation(Ajax.class); String url = ajax.url(); url = UrlMatcher.replaceParams(url, request.getParameters()); url = UrlMatcher.replaceFields(url, beanMap); HttpRequest subRequest = request.subRequest(url); HttpResponse subReponse = null; try { subReponse = DownloaderContext.download(subRequest); RenderType type = RenderType.HTML; if (ReflectUtils.haveSuperType(clazz, JsonBean.class)) { type = RenderType.JSON; } Render render = RenderContext.getRender(type); return render.inject(clazz, subRequest, subReponse); } catch (DownloadException ex) { //throw new FieldRenderException(field, ex.getMessage(), ex); FieldRenderException.log(field, ex.getMessage(), ex); return null; } finally { if(subReponse != null) { subReponse.close(); } } } }