参考项目:nxcloud-sample-simple

项目搭建

参考示例项目和示例 POM 建立要开发的项目。

Gateway 配置

其他内容和开发任何一个 SpringBoot Web 项目大同小异,仅描述需要统一配置的内容。

指定注解驱动要扫描的包路径

要注意,扫描的包路径要包含领域驱动的其他模块的内容。

  1. @SpringBootApplication(scanBasePackages = {"nxcloud.sample.simple"})

配置 Json 消息转换器

package nxcloud.sample.simple.gateway.config;

import my.clean.foundation.core.json.mapper.BaseObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 * @author qatang
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private BaseObjectMapper baseObjectMapper;

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new MappingJackson2HttpMessageConverter(baseObjectMapper));
    }

}

配置 Swagger 接口文档

package nxcloud.sample.simple.gateway.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Value("${swagger.enable:false}")
    boolean enableSwagger;

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(enableSwagger)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("nxcloud.sample.simple"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("NXCloud Sample Simple APIs")
                .description("swagger-bootstrap-ui")
                .version("1.0")
                .build();
    }

}

配置自定义异常码转换

将当前项目自定义的异常转换成对外输出的异常码,即将异常转换成 CodeWrapperRuntimeException

package nxcloud.sample.simple.gateway.config;

import nxcloud.foundation.base.exception.CodeWrapperExceptionConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CodeWrapperConfig {

    @Bean
    protected CodeWrapperExceptionConverter codeWrapperExceptionConverter() {
        return throwable -> null;
    }

}

配置请求拦截

拿到请求体记录日志等,可选。

package nxcloud.sample.simple.gateway.http.advice;

import lombok.extern.slf4j.Slf4j;
import nxcloud.foundation.feign.gateway.advice.BaseFeignRequestBodyAdvice;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.IOException;
import java.lang.reflect.Type;

/**
 * @author qatang
 */
@Slf4j
@RestControllerAdvice
public class GatewayRequestBodyAdvice extends BaseFeignRequestBodyAdvice {

    @Override
    protected void executeBodyRead(String body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        // log.info("============ request body : {}", body);
    }

}

配置响应拦截

将业务处理完的响应对象转化成统一的结构体。

package nxcloud.sample.simple.gateway.http.advice;

import lombok.extern.slf4j.Slf4j;
import my.clean.foundation.core.json.mapper.BaseObjectMapper;
import nxcloud.foundation.feign.gateway.advice.BaseFeignResponseBodyAdvice;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author qatang
 */
@Slf4j
@RestControllerAdvice
public class GatewayResponseBodyAdvice extends BaseFeignResponseBodyAdvice {

    public GatewayResponseBodyAdvice(BaseObjectMapper baseObjectMapper) {
        super(baseObjectMapper);
    }

}

配置异常拦截

将业务异常转化成统一的响应结果码。

package nxcloud.sample.simple.gateway.http.advice;

import lombok.extern.slf4j.Slf4j;
import nxcloud.foundation.feign.gateway.advice.BaseFeignExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author qatang
 */
@Slf4j
@RestControllerAdvice
public class GatewayExceptionHandler extends BaseFeignExceptionHandler {

}

开发业务接口

标记接口方法注解

在 Controller 方法中添加 @ControllerExecutor 注解后,返回结果会被统一封装成 ResponseWrapper 格式。

ResponseWrapper 响应格式

package nxcloud.foundation.feign.gateway.wrapper;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author qatang
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ResponseWrapper<D> {
    /**
     * 响应状态码
     */
    private int code;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应时间
     */
    private long timestamp;

    /**
     * 响应数据
     */
    private D data;
}