如何做彩票销售网站,wordpress没有安装主题选项卡,wordpress获取分类链接地址,黑马程序员培训机构官网前言
之前注解篇时我说#xff0c;通常情况下一个自定义注解一般对应一个切面#xff0c;虽然项目里的切面和注解个数相同#xff0c;但是好像有一个名字看起来并不对应#xff0c;无所谓#xff0c;先看了再说。
ExceptionLogAspect切面
我在里面做了具体注释#x…前言
之前注解篇时我说通常情况下一个自定义注解一般对应一个切面虽然项目里的切面和注解个数相同但是好像有一个名字看起来并不对应无所谓先看了再说。
ExceptionLogAspect切面
我在里面做了具体注释所以看起来比较长但我觉得作者的代码思路还是很清晰的就是里面一下就涉及了三个自写工具类的使用会让我暂时少了一些具体逻辑的理解。
如果不想看代码里的注释可以先看看我的理解。
我们先来看这个类的类图吧 这个类被两个注解修饰,Component和 Aspect一起使用可以方便地实现Spring AOP的功能同时确保切面类被Spring容器管理。
Component这个注解是Spring的一个核心注解用于指示一个类是Spring容器管理的组件。当一个类被标记为Component时Spring会自动检测并注册它使得它可以在应用程序的其他部分中被注入和使用。
Aspect这个注解是Spring AOP面向切面编程的一部分用于指示一个类是一个切面。切面是一个关注点Cross-Cutting Concerns模块化的类它包含了一系列的通知Advice这些通知在特定的连接点Join Points上执行。
这个类有四个方法 handlelog(JoinPoint,Exception) 根据传入的参数返回一个填充好数据的 ExceptionLog的对象ExceptionLog的属性部分我也放在图里面了。
logAfterThrowing(JoinPoint,Exception):用于指定在目标方法抛出异常后执行的通知。它被一个注解 AfterThrowing(value “logPointcut()”, throwing “e”) 修饰value属性指定了切点throwing属性指定了异常对象它可以在通知方法中作为参数使用。
logPointcut()它被 Pointcut(“execution(* com.rawchen.controller….(…))”)修饰表示切入点的声明里面的参数表示拦截的范围。
最后实现的功能
一旦com.rawchen.controller包下的某个类的某个方法抛出异常ExceptionLogAspect切面中的logAfterThrowing通知方法就会被触发。该方法上面一行的注解会找到切入点对象和异常信息传到方法里然后开始执行逻辑。
AfterThrowing(value logPointcut(), throwing e)
public void logAfterThrowing(JoinPoint joinPoint, Exception e) {ExceptionLog log handleLog(joinPoint, e);exceptionLogService.saveExceptionLog(log);
}ExceptionLog log handleLog(joinPoint, e) 调用handleLog方法来创建一个新的ExceptionLog对象并填充其属性包括异常发生的URI、方法、IP地址、用户代理、描述信息、错误堆栈跟踪以及请求参数。
exceptionLogService.saveExceptionLog(log) 调用ExceptionLogService的saveExceptionLog方法来保存异常日志。这个方法将异常日志信息保存到数据库或其他存储介质中。 ExceptionLogService是一个服务层接口它定义了保存异常日志的方法这个接口在ExceptionLogAspect类中通过Autowired注解注入了实现类。
完整代码注释
package com.rawchen.aspect;import com.rawchen.annotation.OperationLogger;
import com.rawchen.annotation.VisitLogger;
import com.rawchen.entity.ExceptionLog;
import com.rawchen.service.ExceptionLogService;
import com.rawchen.util.AopUtils;
import com.rawchen.util.IpAddressUtils;
import com.rawchen.util.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.rawchen.util.JacksonUtils;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Map;/*** Description: AOP记录异常日志* Date: 2020-12-03*/
Component
Aspect
public class ExceptionLogAspect {//Autowired这是一个Spring的注解用于自动注入ExceptionLogService的实例。//Spring会自动查找合适的组件并将其注入到当前类中。AutowiredExceptionLogService exceptionLogService;/*** 配置切入点* logPointcut()它的作用是作为切点的标识符。* 在这个方法上标注了Pointcut注解因此它会被Spring AOP识别为切点定义。*///Pointcut(execution(* com.rawchen.controller..*.*(..)))这是一个切点注解用于定义哪些方法会被拦截。//在这个例子中execution(* com.rawchen.controller..*.*(..))//表示拦截com.rawchen.controller包及其子包下的所有方法。Pointcut(execution(* com.rawchen.controller..*.*(..)))public void logPointcut() {}/*** 该方法它接收JoinPoint和Exception对象作为参数这个方法可用于创建一个异常日志对象并将为其填充为合适的值后存储。*///AfterThrowing(value logPointcut(), throwing e)这是一个通知注解//用于指定在目标方法抛出异常后执行的通知。value属性指定了切点throwing属性指定了异常对象//它可以在通知方法中作为参数使用。AfterThrowing(value logPointcut(), throwing e)public void logAfterThrowing(JoinPoint joinPoint, Exception e) {ExceptionLog log handleLog(joinPoint, e);exceptionLogService.saveExceptionLog(log);}/*** 设置ExceptionLog对象属性* * return 填充好数据的ExceptionLog对象*/private ExceptionLog handleLog(JoinPoint joinPoint, Exception e) {//获取了当前的ServletRequestAttributes对象这个对象包含了当前HTTP请求的详细信息。ServletRequestAttributes attributes (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();//获取当前的HttpServletRequest对象这个对象代表了当前的HTTP请求。HttpServletRequest request attributes.getRequest();//通过request对象的方法获取一些具体信息//获取请求的URI统一资源标识符String uri request.getRequestURI();//获取请求方法String method request.getMethod();//通过作者自己写的工具类来获取ip地址String ip IpAddressUtils.getIpAddress(request);//获取请求的User-Agent头这个头通常包含了客户端浏览器的信息。String userAgent request.getHeader(User-Agent);//todo 使用swagger后可以直接使用注解上的内容作为 ExceptionLog 的 description//通过类里私有方法获取注解上的描述内容存储在字符串中String description getDescriptionFromAnnotations(joinPoint);//使用作者自己写的StringUtils工具类的方法来获取异常的堆栈跟踪信息。String error StringUtils.getStackTrace(e);//创建一个新的ExceptionLog对象并使用前面获取的信息来填充它的属性。ExceptionLog log new ExceptionLog(uri, method, description, error, ip, userAgent);//调用AopUtils工具类的方法来获取请求的参数。MapString, Object requestParams AopUtils.getRequestParams(joinPoint);//将请求参数转换为JSON字符串并截取前2000个字符//然后将其设置为ExceptionLog对象的param属性,只截取2000个字符是为了限制日志的长度避免日志过长。log.setParam(StringUtils.substring(JacksonUtils.writeValueAsString(requestParams), 0, 2000));return log;}/*** 如果抛出方法被自定义注解修饰那就得到OperationLogger注解里或者VisitLog描述操作的那段字符串*/private String getDescriptionFromAnnotations(JoinPoint joinPoint) {String description ;//这行代码从JoinPoint对象中获取方法签名并将其转换为Method对象这样就可以访问方法上的注解了。Method method ((MethodSignature) joinPoint.getSignature()).getMethod();OperationLogger operationLogger method.getAnnotation(OperationLogger.class);if (operationLogger ! null) {description operationLogger.value();return description;}VisitLogger visitLogger method.getAnnotation(VisitLogger.class);if (visitLogger ! null) {description visitLogger.behavior();return description;}return description;}
}OperationLogAspect
还是先看类图 注解已经解释过一遍了而且这三个方法与前面的ExceptionLogAspect切面相差不大同时一样在图里附上OperationLog类便于理解。
logPointcut() 被 Pointcut(“annotation(operationLogger)”) 注解修饰表示切入点的声明它将会匹配所有带有OperationLogger注解的方法。
logAround(ProceedingJoinPoint joinPoint, OperationLogger operationLogger)被 Around(“logPointcut(operationLogger)”) 注解修饰表示该切入点的方法被环绕通知环绕通知是一种动态拦截方法执行的通知它允许你完全控制方法的执行流程。 环绕通知的logAround方法可以执行以下操作 执行被环绕的方法Object result joinPoint.proceed(); 这行代码会执行原始的方法调用并将返回值存储在result变量中。 在方法执行前后添加额外的逻辑在这个例子中它记录了方法执行的时间并创建了一个操作日志对象。 返回方法的执行结果return result; 这行代码将原始方法的执行结果返回给调用者。 handleLog(ProceedingJoinPoint joinPoint, OperationLogger operationLogger, int times)通过调用工具类进行信息解析返回一个填充好数据属性的OperationLog对象供服务层接口进行日志保存。
最后实现的功能
一旦被OperationLogger注解修饰的方法被调用然后切入点进行匹配传参到logAround方法进行一个环绕通知来记录这个方法的执行时间最后通过handleLog方法与其他信息一同被记录到日志当中。也是服务层接口通过注解注入实体类服务层接口方法负责日志保存。 Around(logPointcut(operationLogger))public Object logAround(ProceedingJoinPoint joinPoint, OperationLogger operationLogger) throws Throwable {// 设置当前时间currentTime.set(System.currentTimeMillis());// 执行被环绕的方法Object result joinPoint.proceed();// 计算方法执行时间int times (int) (System.currentTimeMillis() - currentTime.get());// 清除当前时间currentTime.remove();// 创建操作日志对象OperationLog operationLog handleLog(joinPoint, operationLogger, times);// 保存操作日志operationLogService.saveOperationLog(operationLog);// 返回方法的执行结果return result;}完整代码注释
Component
Aspect
public class OperationLogAspect {// 注入操作日志服务AutowiredOperationLogService operationLogService;// 线程局部变量用于记录当前时间ThreadLocalLong currentTime new ThreadLocal();/*** 配置切入点用于匹配带有OperationLogger注解的方法*/Pointcut(annotation(operationLogger))public void logPointcut(OperationLogger operationLogger) {}/*** 配置环绕通知用于记录操作日志** param joinPoint 方法执行的连接点* param operationLogger 方法上的OperationLogger注解* return 方法的执行结果* throws Throwable 方法执行中可能抛出的异常*/Around(logPointcut(operationLogger))public Object logAround(ProceedingJoinPoint joinPoint, OperationLogger operationLogger) throws Throwable {// 设置当前时间currentTime.set(System.currentTimeMillis());// 执行被环绕的方法Object result joinPoint.proceed();// 计算方法执行时间int times (int) (System.currentTimeMillis() - currentTime.get());// 清除当前时间currentTime.remove();// 创建操作日志对象OperationLog operationLog handleLog(joinPoint, operationLogger, times);// 保存操作日志operationLogService.saveOperationLog(operationLog);// 返回方法的执行结果return result;}/*** 获取HttpServletRequest请求对象并设置OperationLog对象属性** param operationLogger 方法上的OperationLogger注解* param times 方法执行时间* return 操作日志对象*/private OperationLog handleLog(ProceedingJoinPoint joinPoint, OperationLogger operationLogger, int times) {// 获取当前请求的ServletRequestAttributesServletRequestAttributes attributes (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();// 从ServletRequestAttributes中获取HttpServletRequest对象HttpServletRequest request attributes.getRequest();// 获取当前用户名通过JWT工具类解析String username JwtUtils.getTokenBody(request.getHeader(Authorization)).getSubject();// 获取请求的URIString uri request.getRequestURI();// 获取请求的HTTP方法String method request.getMethod();// 获取OperationLogger注解的描述信息String description operationLogger.value();// 获取请求的IP地址String ip IpAddressUtils.getIpAddress(request);// 获取请求的User-Agent头String userAgent request.getHeader(User-Agent);// 创建新的操作日志对象OperationLog log new OperationLog(username, uri, method, description, ip, times, userAgent);// 通过工具类获取请求参数并将其转换为JSON字符串然后截取前2000个字符作为日志参数,避免日志过长MapString, Object requestParams AopUtils.getRequestParams(joinPoint);log.setParam(StringUtils.substring(JacksonUtils.writeValueAsString(requestParams), 0, 2000));// 返回操作日志对象return log;}
}
VisitLogAspect切面
类图 这里面的logAround环绕通知方法logPointcut方法以及handleLog的方法与上面两个切面类也是大同小异现在主要看一下类图里前面三个方法。 checkIdentification(HttpServletRequest request) 校验访客标识码通过获取请求里面的校验码有校验码就与数据库里的进行比对比对成功后保存在Redis中比对不成功就签发一个新的标识码加入请求里根本没有校验码也是签发一个新的。
saveUUID(HttpServletRequest request) 签发校验码根据时间戳、ip、userAgent生成UUID并进行数据库与Redis的保存操作。
至于这个judgeBehavior(String behavior, String content, MapString, Object requestParams, Object result)方法它里面只是简单的字符串与注解里的参数进行匹配再根据请求信息完成日志数据所以说我放一张VisitLogger的注解使用次数反而更加好理解。
最后实现功能
访问日志记录当一个方法被VisitLogger注解修饰时该方法执行前后会被VisitLogAspect切面拦截并在方法执行前后执行日志记录逻辑。访客标识码验证在方法执行前切面会检查请求头中是否包含identification字段这是访客的唯一标识码。如果未包含切面会生成一个新的访客标识码并保存到数据库和Redis中。行为判断和日志内容设置根据VisitLogger注解的行为和内容描述切面会判断并设置访问日志的备注和内容字段。访问日志保存在方法执行后切面会创建一个VisitLog对象并填充其属性包括访客标识码、请求URI、HTTP方法、行为描述、内容描述、IP地址、执行时间、User-Agent头等。然后它会将这个访问日志对象保存到服务层进行持久化。Redis使用切面使用Redis服务来存储和验证访客标识码。它将访客标识码保存到Redis中的一个集合中并在验证访客标识码时检查这个集合中是否包含该标识码。数据库访问切面会访问数据库来验证访客标识码是否已存在于数据库中以及是否需要生成新的访客标识码。
UUID的作用
UUIDUniversally Unique Identifier通用唯一识别码是一种用于生成唯一标识符的机制。
在这个项目里UUID被用于生成访客的唯一标识码。当请求头中没有identification字段时切面会生成一个新的UUID并将其保存到数据库和Redis中。之后在每次请求中切面都会检查请求头中的identification字段以验证访客标识码是否有效。
这种机制可以防止重复访问和刷访问量等恶意行为。
完整代码注释
Component
Aspect
public class VisitLogAspect {// 注入访问日志服务AutowiredVisitLogService visitLogService;// 注入访客服务AutowiredVisitorService visitorService;// 注入Redis服务AutowiredRedisService redisService;// 线程局部变量用于记录当前时间ThreadLocalLong currentTime new ThreadLocal();/*** 配置切入点用于匹配带有VisitLogger注解的方法*/Pointcut(annotation(visitLogger))public void logPointcut(VisitLogger visitLogger) {}/*** 配置环绕通知用于记录访问日志** param joinPoint 方法执行的连接点* param visitLogger 方法上的VisitLogger注解* return 方法的执行结果* throws Throwable 方法执行中可能抛出的异常*/Around(logPointcut(visitLogger))public Object logAround(ProceedingJoinPoint joinPoint, VisitLogger visitLogger) throws Throwable {// 设置当前时间currentTime.set(System.currentTimeMillis());// 执行被环绕的方法Object result joinPoint.proceed();// 计算方法执行时间int times (int) (System.currentTimeMillis() - currentTime.get());// 清除当前时间currentTime.remove();// 获取请求对象HttpServletRequest request ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();// 校验访客标识码String identification checkIdentification(request);// 记录访问日志VisitLog visitLog handleLog(joinPoint, visitLogger, request, result, times, identification);// 保存访问日志visitLogService.saveVisitLog(visitLog);// 返回方法的执行结果return result;}/*** 校验访客标识码** param request* return*/private String checkIdentification(HttpServletRequest request) {// 获取请求头中的访客标识码String identification request.getHeader(identification);// 如果请求头中没有访客标识码则签发一个新的访客标识码if (identification null) {// 签发新的访客标识码并保存到数据库和Redisidentification saveUUID(request);} else {// 校验Redis中是否存在访客标识码boolean redisHas redisService.hasValueInSet(RedisKeyConfig.IDENTIFICATION_SET, identification);// 如果Redis中不存在访客标识码则检查数据库中是否存在if (!redisHas) {// 检查数据库中是否存在访客标识码boolean mysqlHas visitorService.hasUUID(identification);// 如果数据库中存在则保存至Redisif (mysqlHas) {redisService.saveValueToSet(RedisKeyConfig.IDENTIFICATION_SET, identification);} else {// 如果数据库中不存在则签发一个新的访客标识码identification saveUUID(request);}}}return identification;}/*** 签发UUID并保存至数据库和Redis** param request* return*/private String saveUUID(HttpServletRequest request) {//获取响应对象HttpServletResponse response ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();//获取当前时间戳精确到小时防刷访客数据Calendar calendar Calendar.getInstance();calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);String timestamp Long.toString(calendar.getTimeInMillis() / 1000);//获取访问者基本信息String ip IpAddressUtils.getIpAddress(request);String userAgent request.getHeader(User-Agent);//根据时间戳、ip、userAgent生成UUIDString nameUUID timestamp ip userAgent;String uuid UUID.nameUUIDFromBytes(nameUUID.getBytes()).toString();//添加访客标识码UUID至响应头response.addHeader(identification, uuid);//暴露自定义header供页面资源使用response.addHeader(Access-Control-Expose-Headers, identification);//校验Redis中是否存在uuidboolean redisHas redisService.hasValueInSet(RedisKeyConfig.IDENTIFICATION_SET, uuid);if (!redisHas) {//保存至RedisredisService.saveValueToSet(RedisKeyConfig.IDENTIFICATION_SET, uuid);//保存至数据库Visitor visitor new Visitor(uuid, ip, userAgent);visitorService.saveVisitor(visitor);}return uuid;}/*** 设置VisitLogger对象属性** param joinPoint* param visitLogger* param result* param times* return 填充好的日志对象*/private VisitLog handleLog(ProceedingJoinPoint joinPoint, VisitLogger visitLogger, HttpServletRequest request, Object result,int times, String identification) {// 获取请求的URIString uri request.getRequestURI();// 获取请求的HTTP方法String method request.getMethod();// 获取VisitLogger注解的行为描述String behavior visitLogger.behavior();// 获取VisitLogger注解的内容描述String content visitLogger.content();// 获取请求的IP地址String ip IpAddressUtils.getIpAddress(request);// 获取请求的User-Agent头String userAgent request.getHeader(User-Agent);// 获取请求参数MapString, Object requestParams AopUtils.getRequestParams(joinPoint);// 根据访问行为设置对应的访问内容或备注MapString, String map judgeBehavior(behavior, content, requestParams, result);// 创建新的访问日志对象VisitLog log new VisitLog(identification, uri, method, behavior, map.get(content), map.get(remark), ip, times, userAgent);// 设置日志的参数log.setParam(StringUtils.substring(JacksonUtils.writeValueAsString(requestParams), 0, 2000));// 返回访问日志对象return log;}/*** 根据访问行为设置对应的访问内容或备注** param behavior* param content* param requestParams* param result* return*/private MapString, String judgeBehavior(String behavior, String content, MapString, Object requestParams, Object result) {MapString, String map new HashMap();String remark ;if (behavior.equals(访问页面) (content.equals(首页) || content.equals(动态))) {int pageNum (int) requestParams.get(pageNum);remark 第 pageNum 页;} else if (behavior.equals(查看博客)) {Result res (Result) result;if (res.getCode() 200) {BlogDetail blog (BlogDetail) res.getData();String title blog.getTitle();content title;remark 文章标题 title;}} else if (behavior.equals(搜索博客)) {Result res (Result) result;if (res.getCode() 200) {String query (String) requestParams.get(query);content query;remark 搜索内容 query;}} else if (behavior.equals(查看分类)) {String categoryName (String) requestParams.get(categoryName);int pageNum (int) requestParams.get(pageNum);content categoryName;remark 分类名称 categoryName 第 pageNum 页;} else if (behavior.equals(查看标签)) {String tagName (String) requestParams.get(tagName);int pageNum (int) requestParams.get(pageNum);content tagName;remark 标签名称 tagName 第 pageNum 页;} else if (behavior.equals(点击友链)) {String nickname (String) requestParams.get(nickname);content nickname;remark 友链名称 nickname;}map.put(remark, remark);map.put(content, content);return map;}
}
后续
一扯到这个切面里面的工具类服务层接口redis配置类全部一下子冒出来了还好这个项目比较小总算是看完了现在我很难想象以后工作时真要看项目代码时那得是件多煎熬的事啊下一篇看看项目里的工具类代码咋写的。 文章转载自: http://www.morning.pnjsl.cn.gov.cn.pnjsl.cn http://www.morning.zqybs.cn.gov.cn.zqybs.cn http://www.morning.plhhd.cn.gov.cn.plhhd.cn http://www.morning.rwjh.cn.gov.cn.rwjh.cn http://www.morning.gmmxh.cn.gov.cn.gmmxh.cn http://www.morning.mlhfr.cn.gov.cn.mlhfr.cn http://www.morning.fkmyq.cn.gov.cn.fkmyq.cn http://www.morning.xbptx.cn.gov.cn.xbptx.cn http://www.morning.rqqlp.cn.gov.cn.rqqlp.cn http://www.morning.nynlf.cn.gov.cn.nynlf.cn http://www.morning.qykxj.cn.gov.cn.qykxj.cn http://www.morning.nkhdt.cn.gov.cn.nkhdt.cn http://www.morning.hrtfz.cn.gov.cn.hrtfz.cn http://www.morning.mlntx.cn.gov.cn.mlntx.cn http://www.morning.krxzl.cn.gov.cn.krxzl.cn http://www.morning.rgmd.cn.gov.cn.rgmd.cn http://www.morning.bqqzg.cn.gov.cn.bqqzg.cn http://www.morning.xdxpq.cn.gov.cn.xdxpq.cn http://www.morning.rkfwr.cn.gov.cn.rkfwr.cn http://www.morning.flmxl.cn.gov.cn.flmxl.cn http://www.morning.clzly.cn.gov.cn.clzly.cn http://www.morning.gccrn.cn.gov.cn.gccrn.cn http://www.morning.nsncq.cn.gov.cn.nsncq.cn http://www.morning.hpcpp.cn.gov.cn.hpcpp.cn http://www.morning.xjmyq.com.gov.cn.xjmyq.com http://www.morning.kehejia.com.gov.cn.kehejia.com http://www.morning.qlpq.cn.gov.cn.qlpq.cn http://www.morning.lwtfr.cn.gov.cn.lwtfr.cn http://www.morning.xqxlb.cn.gov.cn.xqxlb.cn http://www.morning.tzcr.cn.gov.cn.tzcr.cn http://www.morning.ysrtj.cn.gov.cn.ysrtj.cn http://www.morning.rdxp.cn.gov.cn.rdxp.cn http://www.morning.flpjy.cn.gov.cn.flpjy.cn http://www.morning.wdqhg.cn.gov.cn.wdqhg.cn http://www.morning.ymwny.cn.gov.cn.ymwny.cn http://www.morning.stbfy.cn.gov.cn.stbfy.cn http://www.morning.wkmpx.cn.gov.cn.wkmpx.cn http://www.morning.hdtcj.cn.gov.cn.hdtcj.cn http://www.morning.fkyqm.cn.gov.cn.fkyqm.cn http://www.morning.wpwyx.cn.gov.cn.wpwyx.cn http://www.morning.nfzw.cn.gov.cn.nfzw.cn http://www.morning.kbyp.cn.gov.cn.kbyp.cn http://www.morning.pzjrm.cn.gov.cn.pzjrm.cn http://www.morning.bsxws.cn.gov.cn.bsxws.cn http://www.morning.mmosan.com.gov.cn.mmosan.com http://www.morning.byrlg.cn.gov.cn.byrlg.cn http://www.morning.shsh1688.com.gov.cn.shsh1688.com http://www.morning.rlcqx.cn.gov.cn.rlcqx.cn http://www.morning.rymd.cn.gov.cn.rymd.cn http://www.morning.nlygm.cn.gov.cn.nlygm.cn http://www.morning.kxbry.cn.gov.cn.kxbry.cn http://www.morning.errnull.com.gov.cn.errnull.com http://www.morning.pqcrz.cn.gov.cn.pqcrz.cn http://www.morning.trsdm.cn.gov.cn.trsdm.cn http://www.morning.fhwfk.cn.gov.cn.fhwfk.cn http://www.morning.jcpq.cn.gov.cn.jcpq.cn http://www.morning.sskkf.cn.gov.cn.sskkf.cn http://www.morning.rqrh.cn.gov.cn.rqrh.cn http://www.morning.sqyjh.cn.gov.cn.sqyjh.cn http://www.morning.zqdzg.cn.gov.cn.zqdzg.cn http://www.morning.bloao.com.gov.cn.bloao.com http://www.morning.beijingzy.com.cn.gov.cn.beijingzy.com.cn http://www.morning.dwgcx.cn.gov.cn.dwgcx.cn http://www.morning.xesrd.com.gov.cn.xesrd.com http://www.morning.gtxrw.cn.gov.cn.gtxrw.cn http://www.morning.xknsn.cn.gov.cn.xknsn.cn http://www.morning.pxwjp.cn.gov.cn.pxwjp.cn http://www.morning.pjwml.cn.gov.cn.pjwml.cn http://www.morning.lctrz.cn.gov.cn.lctrz.cn http://www.morning.lywys.cn.gov.cn.lywys.cn http://www.morning.ttdxn.cn.gov.cn.ttdxn.cn http://www.morning.gzzncl.cn.gov.cn.gzzncl.cn http://www.morning.bfrsr.cn.gov.cn.bfrsr.cn http://www.morning.zpjhh.cn.gov.cn.zpjhh.cn http://www.morning.rgpy.cn.gov.cn.rgpy.cn http://www.morning.ydrn.cn.gov.cn.ydrn.cn http://www.morning.tgxrm.cn.gov.cn.tgxrm.cn http://www.morning.grtwn.cn.gov.cn.grtwn.cn http://www.morning.fjzlh.cn.gov.cn.fjzlh.cn http://www.morning.xlwpz.cn.gov.cn.xlwpz.cn