当前位置: 移动技术网 > IT编程>开发语言>Java > [Spring cloud 一步步实现广告系统] 4. 通用代码模块设计

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

2019年07月27日  | 移动技术网IT编程  | 我要评论

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

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

utools1564230299519.png

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

utools1564230319631.png

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

创建项目mscx-ad-common

pom文件

<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
         xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactid>mscx-ad</artifactid>
        <groupid>com.sxzhongf</groupid>
        <version>1.0-snapshot</version>
        <relativepath>../pom.xml</relativepath>
    </parent>
    <modelversion>4.0.0</modelversion>
    <packaging>jar</packaging>

    <groupid>com.sxzhongf</groupid>
    <artifactid>mscx-ad-common</artifactid>
    <version>1.0-snapshot</version>
    <name>common-service</name>
    <description>公共逻辑 and 帮助类</description>

    <dependencies>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>
        <!-- fastjson是阿里巴巴的开源json解析库,它可以解析json格式的字符串,支持将java bean序列化为json字符串,也可以从json字符串反序列化到javabean -->
        <dependency>
            <groupid>com.alibaba</groupid>
            <artifactid>fastjson</artifactid>
            <version>1.2.58</version>
        </dependency>
        <!--  -->
        <dependency>
            <groupid>commons-codec</groupid>
            <artifactid>commons-codec</artifactid>
        </dependency>
        <dependency>
            <groupid>org.apache.commons</groupid>
            <artifactid>commons-lang3</artifactid>
        </dependency>
    </dependencies>
        <!--maven编译插件-->
    <build>
        <plugins>
            <plugin>
                <groupid>org.springframework.boot</groupid>
                <artifactid>spring-boot-maven-plugin</artifactid>
            </plugin>
        </plugins>
    </build>
</project>

项目结构

  • 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
      具体可参考:
  • annotation
  • config
  • exception
  • utils
  • export

    通用响应编码
  1. 创建通用返回对象
/**
* @data是下属注解的组合注解
* 
* @see getter
* @see setter
* @see requiredargsconstructor
* @see tostring
* @see equalsandhashcode
* @see lombok.value 
*/
@data
@noargsconstructor //无参构造函数
@allargsconstructor //全参构造函数
public class commonresponse<t> 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;
   }
}
  1. 在advice包中实现对响应的统一拦截com.sxzhongf.ad.common.advice.commonresponsedataadvice,参考 responsebodyadvice, restcontrolleradvice 可查看源码org.springframework.web.servlet.mvc.method.annotation.responsebodyadvice
   @restcontrolleradvice
   public class commonresponsedataadvice implements responsebodyadvice<object> {
   
       /**
        * 判断是否需要对响应进行处理
        *
        * @return false -> 不处理,true -> 处理
        */
       @override
       public boolean supports(methodparameter methodparameter, class<? extends httpmessageconverter<?>> 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<? extends httpmessageconverter<?>> selectedconvertertype,
                                     serverhttprequest request,
                                     serverhttpresponse response) {
   
           commonresponse<object> commonresponse = new commonresponse<>();
   
           if (null == body) {
               return commonresponse;
           } else if (body instanceof commonresponse) {
               commonresponse = (commonresponse<object>) body;
           } else {
               commonresponse.setdata(body);
           }
           return commonresponse;
       }
   }

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

   /**
    * ignoreresponseadvice for 标示需要忽略拦截动作
    *
    * @author <a href="mailto:magicianisaac@gmail.com">isaac.zhang</a>
    */
   //elementtype.type 表示该注解可用于class
   //elementtype.method 表示可用于方法
   @target({elementtype.type, elementtype.method})
   @retention(retentionpolicy.runtime)
   public @interface ignoreresponseadvice {
   }
通用异常处理

异常处理也是统一的,那么同样就要使用到restcontrolleradvice,同时,需要使用的spring 的exceptionhandler进行异常处理

  1. 创建统一异常拦截类
/**
 * globalexceptionadvice for 全局统一异常拦截
 *
 * @author <a href="mailto:magicianisaac@gmail.com">isaac.zhang</a>
 * @see restcontrolleradvice
 * @see exceptionhandler
 */
@restcontrolleradvice
public class globalexceptionadvice {

    /**
     * 对 {@link adexception} 进行统一处理
     * {@link exceptionhandler}  对指定的异常进行拦截
     * 可优化:
     * 定义多种类异常,实现对应的异常处理,
     * 例如:
     * <ul>
     * <li>
     * 推广单元操作异常,抛出 adunitexception
     * </li>
     * <li>
     * binlog 解析异常,抛出 binlogexception
     * </li>
     * </ul>
     * 拦截spring exception 使用 {@link exceptionhandler}注解
     */
    @exceptionhandler(value = adexception.class)
    public commonresponse<string> handleradexception(httpservletrequest request, adexception ex) {
        commonresponse<string> response = new commonresponse<>(-1, "business error");
        response.setdata(ex.getmessage());
        return response;
    }
}
  1. 创建通用异常类
/**
 * adexception for 统一异常处理类
 *
 * @author <a href="mailto:magicianisaac@gmail.com">isaac.zhang</a>
 */
public class adexception extends exception {
    public adexception(string message) {
        super(message);
    }
}
通用配置信息

通过http消息转换器httpmessageconverter,实现对象转换,java object -> http 数据流

  1. 新增webconfiguration,我们通过实现org.springframework.web.servlet.config.annotation.webmvcconfigurer来定制和修改spring mvc的配置信息。
/**
 * webconfiguration for 对spring的配置和行为进行定制修改
 *
 * @author <a href="mailto:magicianisaac@gmail.com">isaac.zhang</a>
 * @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<handlermethodargumentresolver> resolvers) {

    }
    /**
     * 配置消息转换器
     */
    @override
    public void configuremessageconverters(list<httpmessageconverter<?>> converters) {
        //清空所有转换器
        converters.clear();
        // java obj -> json obj (http header: application/json)
        converters.add(new mappingjackson2httpmessageconverter());
    }
}

做一个好人。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网