4-1 通用模块功能介绍

设计思想:

  • 通用的代码,配置不应该散落在各个业务模块中,不利于维护与更新
  • 一个大的系统,响应对象需要统一外层格式
  • 各种业务设计与实现,可能会抛出各种各样的异常,异常信息的收集也应该做到统一

第 4 章 微服务通用模块开发 - 图1

4-2 开发统一的响应处理

@RestControllerAdvice 注解

Advic 在 Spring 中的含义就是对 XX 功能增强,RestControllerAdvice 就是对 Controller 做增强。

我们需要对 Controller 返回的内容做一些额外的工作,便可以使用该注解。

通常实现的功能是对响应进行拦截,实现统一的返回处理。

@ResponseBodyAdvice 接口

ResponseBodyAdvice 接口的作用是在响应体返回之前做一些自定义的处理工作。通常,我们会实现 ResponseBodyAdvice 接口,并包装统一的响应返回。

实现该接口需要实现两个方法:

  • supports 方法
  • beforeBodyWrite 方法

supports 方法的返回类型是 boolean,用于指定哪些 Controller 方法需要处理。譬如我定义了一个 IgnoreResponseAdvice 注解:

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. @Target({ElementType.TYPE,ElementType.METHOD})
  6. @Retention(RetentionPolicy.RUNTIME)
  7. public @interface IgnoreResponseAdvice {
  8. }

我定义当前标注了 IgnoreResponseAdvice 注解的类或方法,统一响应不会生效:

/**
 * 响应是否应该拦截
 *
 * @param methodParameter
 * @param aClass
 * @return
 */
@Override
@SuppressWarnings("all")
public boolean supports(MethodParameter methodParameter, Class aClass) {

    // 如果一个类或方法被 @IgnoreResponseAdvice 注解标识则不被拦截处理
    if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class) ||
            methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) {
        return false;
    }
    return true;
}

而 beforeBodyWrite 方法的作用为在响应被写入之前做一些操作。这个方法的参数有很多,我们只需要关注第一个:Object o,这个就是原始的 Controller 返回的内容。如果想要实现统一的响应处理,我们就需要对它进行包装。

如果我们对 Controller 的返回结果的处理过程比较复杂,那么根据处理的分类,可以指定多个 ResponseBodyAdvice,并使用 @Order 指定处理顺序。

4-3 开发统一的异常处理

@ExceptionHandler

拦截 Spring 的异常处理需要使用到 ExceptionHandler 注解。Spring 3.0 引入的这个注解可以让我们在一个 handler 方法或者类中统一处理 Controller 抛出的异常。

4-4 统一配置的开发

WebMvcConfigurer 接口

Spring 的 WebMvcConfigurer 接口提供了许多方法让我们来定制 Spring MVC 的配置。下面是对一些常用方法的解释:

public interface WebMvcConfigurer {

    /**
     * 匹配路由请求规则
     */
    default void configurePathMatch(PathMatchConfigurer configurer) {
    }

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

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

    /**
    * 配置消息转换器
    */
    default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

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

    /**
     * 添加自定义方法参数处理器
     */
    default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    }
}