package com.geccocrawler.gecco.spider.render.html; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.reflections.ReflectionUtils; import com.geccocrawler.gecco.annotation.HtmlField; import com.geccocrawler.gecco.request.HttpRequest; import com.geccocrawler.gecco.response.HttpResponse; import com.geccocrawler.gecco.spider.SpiderBean; import com.geccocrawler.gecco.spider.render.FieldRender; import com.geccocrawler.gecco.spider.render.FieldRenderException; import com.geccocrawler.gecco.utils.ReflectUtils; import net.sf.cglib.beans.BeanMap; @SuppressWarnings({ "rawtypes", "unchecked" }) public class HtmlFieldRender implements FieldRender { @Override public void render(HttpRequest request, HttpResponse response, BeanMap beanMap, SpiderBean bean) { Map<String, Object> fieldMap = new HashMap<String, Object>(); Set<Field> htmlFields = ReflectionUtils.getAllFields(bean.getClass(), ReflectionUtils.withAnnotation(HtmlField.class)); for (Field htmlField : htmlFields) { Object value = injectHtmlField(request, response, htmlField, bean.getClass()); if(value != null) { fieldMap.put(htmlField.getName(), value); } } beanMap.putAll(fieldMap); } private Object injectHtmlField(HttpRequest request, HttpResponse response, Field field, Class<? extends SpiderBean> clazz) { HtmlField htmlField = field.getAnnotation(HtmlField.class); String content = response.getContent(); HtmlParser parser = new HtmlParser(request.getUrl(), content); // parser.setLogClass(clazz); String cssPath = htmlField.cssPath(); Class<?> type = field.getType();// 属性的类 boolean isArray = type.isArray();// 是否是数组类型 boolean isList = ReflectUtils.haveSuperType(type, List.class);// 是List类型 if (isList) { Type genericType = field.getGenericType();// 获得包含泛型的类型 Class genericClass = ReflectUtils.getGenericClass(genericType, 0);// 泛型类 if (ReflectUtils.haveSuperType(genericClass, SpiderBean.class)) { // List<spiderBean> return parser.$beanList(cssPath, request, genericClass); } else { // List<Object> try { return parser.$basicList(cssPath, field); } catch (Exception ex) { //throw new FieldRenderException(field, content, ex); FieldRenderException.log(field, content, ex); } } } else if (isArray) { Class genericClass = type.getComponentType(); if (ReflectUtils.haveSuperType(genericClass, SpiderBean.class)) { List<SpiderBean> list = parser.$beanList(cssPath, request, genericClass); SpiderBean[] a = (SpiderBean[]) Array.newInstance(genericClass, list.size()); return list.toArray(a); } else { // List<Object> try { return parser.$basicList(cssPath, field).toArray(); } catch (Exception ex) { //throw new FieldRenderException(field, content, ex); FieldRenderException.log(field, content, ex); } } } else { if (ReflectUtils.haveSuperType(type, SpiderBean.class)) { // SpiderBean return parser.$bean(cssPath, request, (Class<? extends SpiderBean>) type); } else { // Object try { return parser.$basic(cssPath, field); } catch (Exception ex) { //throw new FieldRenderException(field, content, ex); FieldRenderException.log(field, content, ex); } } } return null; } }