资讯专栏INFORMATION COLUMN

[Spring cloud 一步步实现广告系统] 4. 通用代码模块设计

since1986 / 2725人阅读

摘要:对的配置和行为进行定制修改匹配路由请求规则注册自定义的和添加静态资源处理器添加自定义视图控制器添加自定义方法参数处理器配置消息转换器清空所有转换器做一个好人。博客园掘金简书头条知乎

一个大的系统,在代码的复用肯定是必不可少的,它能解决:

统一的响应处理(可以对外提供统一的响应对象包装)

统一的异常处理(可以将业务异常统一收集处理)

通用代码定义、配置定义(通用的配置信息放在统一的代码管理中,便于维护和更新)

创建项目 mscx-ad-common
POM文件


    
        mscx-ad
        com.sxzhongf
        1.0-SNAPSHOT
        ../pom.xml
    
    4.0.0
    jar

    com.sxzhongf
    mscx-ad-common
    1.0-SNAPSHOT
    Common-Service
    公共逻辑 and 帮助类

    
        
            org.springframework.boot
            spring-boot-starter-web
        
          
        
            com.alibaba
            fastjson
            1.2.58
        
          
        
            commons-codec
            commons-codec
        
        
            org.apache.commons
            commons-lang3
        
    
        
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    
项目结构

vo (统一响应对象package)

advice (bean 增强package )

Spring支持五种类型的增强或通知(Advice)

Before(方法执行前) org.apringframework.aop.MethodBeforeAdvice

AfterReturning(方法返回后) org.springframework.aop.AfterReturningAdvice

After-throwing(异常抛出后) org.springframework.aop.ThrowsAdviceArround环绕,即方法前后 org.aopaliance.intercept.MethodInterceptor
引介,不常用 org.springframework.aop.IntroductionInterceptor

具体可参考:细说advice,advisor

annotation

config

exception

utils

export

通用响应编码

创建通用返回对象

/**
* @Data是下属注解的组合注解
* 
* @see Getter
* @see Setter
* @see RequiredArgsConstructor
* @see ToString
* @see EqualsAndHashCode
* @see lombok.Value 
*/
@Data
@NoArgsConstructor //无参构造函数
@AllArgsConstructor //全参构造函数
public class CommonResponse implements Serializable {
   private Integer code = 0;
   private String message = "success";
   /**
    * 具体的数据对象信息
    */
   private T data;

   public CommonResponse(Integer code, String message) {
       this.code = code;
       this.message = message;
   }

   public CommonResponse(T data) {
       this.data = data;
   }
}

在advice包中实现对响应的统一拦截com.sxzhongf.ad.common.advice.CommonResponseDataAdvice,参考 ResponseBodyAdvice, RestControllerAdvice 可查看源码org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice

   @RestControllerAdvice
   public class CommonResponseDataAdvice implements ResponseBodyAdvice {
   
       /**
        * 判断是否需要对响应进行处理
        *
        * @return false -> 不处理,true -> 处理
        */
       @Override
       public boolean supports(MethodParameter methodParameter, Class> converterType) {
   //
   //        //获取当前处理请求的controller的方法
   //        String methodName = methodParameter.getMethod().getName().toLowerCase();
   //        // 不拦截/不需要处理返回值 的方法
   //        String method = "login"; //如登录
   //        //不拦截
   //        return !method.equals(methodName);
   
           // 如果类上标记了@IgnoreResponseAdvice,则不拦截
           if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class)) {
               return false;
           }
   
           // 如果方法上标记了@IgnoreResponseAdvice,则不拦截
           if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) {
               return false;
           }
   
           //对响应进行处理,执行beforeBodyWrite方法
           return true;
       }
   
       /**
        * 目的 拦截CommonResponse
        *
        * @param body 原始的Controller需要返回的数据
        */
       @Override
       public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                     MediaType selectedContentType,
                                     Class> selectedConverterType,
                                     ServerHttpRequest request,
                                     ServerHttpResponse response) {
   
           CommonResponse commonResponse = new CommonResponse<>();
   
           if (null == body) {
               return commonResponse;
           } else if (body instanceof CommonResponse) {
               commonResponse = (CommonResponse) body;
           } else {
               commonResponse.setData(body);
           }
           return commonResponse;
       }
   }

我们在annotation包下面添加一个注解com.sxzhongf.ad.common.annotation.IgnoreResponseAdvice,用它来标柱是否需要支持上面的统一返回拦截。

   /**
    * IgnoreResponseAdvice for 标示需要忽略拦截动作
    *
    * @author Isaac.Zhang
    */
   //ElementType.TYPE 表示该注解可用于class
   //ElementType.METHOD 表示可用于方法
   @Target({ElementType.TYPE, ElementType.METHOD})
   @Retention(RetentionPolicy.RUNTIME)
   public @interface IgnoreResponseAdvice {
   }
通用异常处理
异常处理也是统一的,那么同样就要使用到RestControllerAdvice,同时,需要使用的Spring 的ExceptionHandler进行异常处理

创建统一异常拦截类

/**
 * GlobalExceptionAdvice for 全局统一异常拦截
 *
 * @author Isaac.Zhang
 * @see RestControllerAdvice
 * @see ExceptionHandler
 */
@RestControllerAdvice
public class GlobalExceptionAdvice {

    /**
     * 对 {@link AdException} 进行统一处理
     * {@link ExceptionHandler}  对指定的异常进行拦截
     * 可优化:
     * 定义多种类异常,实现对应的异常处理,
     * 例如:
     * 
    *
  • * 推广单元操作异常,抛出 AdUnitException *
  • *
  • * Binlog 解析异常,抛出 BinlogException *
  • *
* 拦截Spring Exception 使用 {@link ExceptionHandler}注解 */ @ExceptionHandler(value = AdException.class) public CommonResponse handlerAdException(HttpServletRequest request, AdException ex) { CommonResponse response = new CommonResponse<>(-1, "business error"); response.setData(ex.getMessage()); return response; } }

2.创建通用异常类

/**
 * AdException for 统一异常处理类
 *
 * @author Isaac.Zhang
 */
public class AdException extends Exception {
    public AdException(String message) {
        super(message);
    }
}
通用配置信息

通过HTTP消息转换器HttpMessageConverter,实现对象转换,Java Object -> HTTP 数据流

新增WebConfiguration,我们通过实现org.springframework.web.servlet.config.annotation.WebMvcConfigurer来定制和修改Spring MVC的配置信息。

/**
 * WebConfiguration for 对Spring的配置和行为进行定制修改
 *
 * @author Isaac.Zhang
 * @see WebMvcConfigurer
 */
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
    /**
     * 匹配路由请求规则
     */
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {

    }
    /**
     * 注册自定义的Formatter 和 Convert
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {

    }
    /**
     * 添加静态资源处理器
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

    }
    /**
     * 添加自定义视图控制器
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {

    }
    /**
     * 添加自定义方法参数处理器
     */
    @Override
    public void addArgumentResolvers(List resolvers) {

    }
    /**
     * 配置消息转换器
     */
    @Override
    public void configureMessageConverters(List> converters) {
        //清空所有转换器
        converters.clear();
          // Java Obj -> Json Obj (http header: application/json)
        converters.add(new MappingJackson2HttpMessageConverter());
    }
}
做一个好人。

博客园 | segmentfault | spring4all | csdn | 掘金 | OSChina | 简书 | 头条 | 知乎 | 51CTO

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75604.html

相关文章

  • [Spring cloud 步步实现广告系统] 7. 中期总结回顾

    摘要:在前面的过程中,我们创建了个服务发现我们使用作为服务发现组件,学习了的使用。加依赖加注解改配置使用项目三部曲,我们可以快速添加一个新组件,并正常使用这个我没有在项目中实现,但是大家可以和一样,三部曲搞定。 在前面的过程中,我们创建了4个project: 服务发现 我们使用Eureka 作为服务发现组件,学习了Eureka Server,Eureka Client的使用。 Eureka...

    cnsworder 评论0 收藏0
  • [Spring cloud 步步实现广告系统] 12. 广告索引介绍

    摘要:索引设计介绍在我们广告系统中,为了我们能更快的拿到我们想要的广告数据,我们需要对广告数据添加类似于数据库一样的索引结构,分两大类正向索引和倒排索引。如何在广告系统中使用倒排索引核心用途是对各个维度限制的整理。 索引设计介绍 在我们广告系统中,为了我们能更快的拿到我们想要的广告数据,我们需要对广告数据添加类似于数据库index一样的索引结构,分两大类:正向索引和倒排索引。 正向索引 通过...

    endless_road 评论0 收藏0
  • [Spring cloud 步步实现广告系统] 14. 全量索引代码实现

    摘要:各个表数据的存储文件名定义索引对象导出的字段信息依然用为例。通用处理索引类索引之间存在层级划分,也就是相互之间拥有依赖关系的划分加载全量索引其实是增量索引添加的一种特殊实现若初实现广告推广计划的第二层级索引实现。 上一节我们实现了索引基本操作的类以及索引缓存工具类,本小节我们开始实现加载全量索引数据,在加载全量索引数据之前,我们需要先将数据库中的表数据导出到一份文件中。Lets cod...

    MycLambert 评论0 收藏0
  • [Spring cloud 步步实现广告系统] 6. Service实现&Zuul配置&a

    摘要:所以,没必要过分纠结这种信息,咬文嚼字有时候反而会适得其反。若初通用错误信息异常类请求参数异常用户已存在用户不存在在下面创建一个工具类用来对用户进行加密来获取信息。工具类若初加密参考创建用户的实现,依次实现其他表操作。 DAO层设计实现 这里我们使用Spring DATA JPA来实现数据库操作,当然大家也可以使用Mybatis,都是一样的,我们依然以用户表操作为例: /** * A...

    孙淑建 评论0 收藏0
  • [Spring cloud 步步实现广告系统] 8. 检索系统配置&依赖

    摘要:工作流程项目依赖监控面板引入服务调用的组件依赖引入服务消费者的依赖数据库链接依赖工具类集合类操作日志监听解析开源工具类库中的配置相关依赖图片压缩 工作流程 showImg(https://i.loli.net/2019/07/29/5d3ee1829df4d57461.png); 项目依赖 org.springframewo...

    dailybird 评论0 收藏0

发表评论

0条评论

since1986

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<