swagger自定义页面显示

首先明确思路:

swagger扫描的是controller包或者说是@Controller或者@RestController的类,本人的遇到的问题是controller是封装好的,service层是重写controller层下的方法,

比如controller里面的方法是需要传递参数的,{name}需要替换为service雷明如果想实现展示service下的方法,做法如下

1.pom导入依赖包

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl -->
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>
<!-- 自定义的前端swagger页面 -->
<dependency>
    <groupId>myswagger.swagger-ui-layer-master</groupId>
    <artifactId>swagger-ui-layer</artifactId>
    <version>1.0</version>
</dependency>

2.开启swagger

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.*;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;



/**
 * Swagger2配置类
 * 在与spring boot集成时,放在与Application.java同级的目录下。
 * 通过@Configuration注解,让Spring来加载该类配置。
 * 再通过@EnableSwagger2注解来启用Swagger2。
 * Author: zyg
 * Date: 2020-03-26 10:49
 * http://localhost:8080/swagger-ui.html
 */
@Configuration
@EnableSwagger2
//@Profile({"dev", "test"})// @Profile({"dev", "test"})注解是在开发环境和测试环境的时候加载该类,线上生产环境为安全不建议创建swagger的bean
public class Swagger2Config{
    // 定义分隔符
    private static final String splitor = ";";

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2).groupName("spring-test-interface")
                //加载配置信息
                .apiInfo(apiInfo())
                //设置全局参数
                .globalOperationParameters(globalParamBuilder())
                //设置全局响应参数
                .globalResponseMessage(RequestMethod.GET,responseBuilder())
                .globalResponseMessage(RequestMethod.POST,responseBuilder())
                .globalResponseMessage(RequestMethod.PUT,responseBuilder())
                .globalResponseMessage(RequestMethod.DELETE,responseBuilder())
                .select()
                /**
                 * 加载swagger 扫描包
                 */
//                .apis(RequestHandlerSelectors.any())//加载所有的controller
                .apis(basePackage("com.mes7801.server.controller"+splitor+"com.evjrsf.server.controller"))
//                .apis(basePackage("com.mes7801.server.controller"))//加载单个controller
                .paths(PathSelectors.any())
                .build()
                //设置安全认证
                .securitySchemes(security());

    }

    /**
     * 获取swagger创建初始化信息
     * @return
     */
    private ApiInfo apiInfo() {
        Contact contact = new Contact("慧都科技", "", "sales@evget.com");
        return new ApiInfoBuilder().title("MES7801 测试文档").description("dev by 慧都科技").contact(contact)
                .version("1.1.0").build();
    }

    /**
     * 安全认证参数
     * @return
     */
    private List<ApiKey> security() {
        List<ApiKey> list=new ArrayList<>();
        list.add(new ApiKey("token", "token", "header"));
        return list;
    }

    /**
     * 构建全局参数列表
     * @return
     */
    private List<Parameter> globalParamBuilder(){
        List<Parameter> pars = new ArrayList<>();
        pars.add(parameterBuilder("token","令牌","string","header",false).build());
        return pars;
    }

    /**
     * 创建参数
     * @return
     */
    private ParameterBuilder parameterBuilder(String name,String desc,String type ,String parameterType,boolean required) {
        ParameterBuilder tokenPar = new ParameterBuilder();
        tokenPar.name(name).description(desc).modelRef(new ModelRef(type)).parameterType(parameterType).required(required).build();
        return tokenPar;
    }

    /**
     * 创建全局响应值
     * @return
     */
    private List<ResponseMessage> responseBuilder() {
        List<ResponseMessage> responseMessageList = new ArrayList<>();
        responseMessageList.add(new ResponseMessageBuilder().code(200).message("响应成功").build());
        responseMessageList.add(new ResponseMessageBuilder().code(500).message("服务器内部错误").build());
        return responseMessageList;
    }

    public static Predicate<RequestHandler> basePackage(final String basePackage) {
        return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
    }

    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage)     {
        return input -> {
            // 循环判断匹配
            for (String strPackage : basePackage.split(splitor)) {
                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
                    return true;
                }
            }
            return false;
        };
    }

    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
        return Optional.fromNullable(input.declaringClass());
    }
}

3.建立监听器和拦截器(将返回的日期格式数据由时间戳重新转换为日期格式)

//授权检测的创建继承HandlerInterceptorAdapter

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Description:授权检测的创建继承HandlerInterceptorAdapter 方法
 * Author: zyg
 * Date: 2020-03-27 13:45
 */
@Component
@CrossOrigin(origins = "*", maxAge = 3600)
//实现跨域注解
//origin="*"代表所有域名都可访问
//maxAge飞行前响应的缓存持续时间的最大年龄,简单来说就是Cookie的有效期 单位为秒
//若maxAge是负数,则代表为临时Cookie,不会被持久化,Cookie信息保存在浏览器内存中,浏览器关闭Cookie就消失
public class LoginInterceptor extends HandlerInterceptorAdapter {
    /**
     * preHandle在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制等处理;
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //未开启权限检测 跳过
//        String url = request.getRequestURI();//这里打端点,页面访问swagger页面看看请求的什么路径
//        System.out.println("访问接口地址为"+url);
        return true;
    }

    /**
     * postHandle在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),
     * 有机会修改ModelAndView;
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object
            o, ModelAndView modelAndView) throws Exception {
    }

    /**
     * afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面),
     * 可以根据ex是否为null判断是否发生了异常,进行日志记录;
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse
            httpServletResponse, Object o, Exception e) throws Exception {
    }
}
//拦截器用来放行swagger和自定义的docs页面
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.mes7801.server.config.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * Description:放开swagger访问
 * Author: zyg
 * Date: 2020-03-27 13:32
 */
@Configuration
public class WebMvcConfigurerAdapter extends WebMvcConfigurationSupport {

    @Autowired
    private LoginInterceptor loginInterceptor;

    /**
     * WebMvcConfigurationSupport将返回值json中的日期格式转换为时间戳,这里转换成日期格式
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //1.需要定义一个convert转换消息的对象;
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        //2.添加fastJson的配置信息,比如:是否要格式化返回的json数据;
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteDateUseDateFormat);
        //3处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        //4.在convert中添加配置信息.
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        //5.将convert添加到converters当中.
        converters.add(fastJsonHttpMessageConverter);
    }

    /**
     * addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
     * addPathPatterns:用于设置拦截器的过滤路径规则
     * excludePathPatterns:用于设置不需要拦截的过滤规则
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截接口请求处理,
        /**
         *此处拦截路径(/**)
         * 注意两个**。一个*号只拦截一级路径下,两个*号拦截所有
         * 添加拦截的路径
         * /为根路径
         * /*为一级路径HandlerInterceptor
         * /** 为所有路径包括多级
         */
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/docs.html/**")
                .excludePathPatterns("/v2/**")
                .excludePathPatterns("/swagger-ui.html")
                .excludePathPatterns("/swagger-resources/**")
                .excludePathPatterns("/error")
                .excludePathPatterns("/webjars/**");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //定向swagger 位置
        String RESOURCE_LOCATION = "classpath:/META-INF/resources/";
        registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
        registry.addResourceHandler("swagger-ui.html").addResourceLocations(RESOURCE_LOCATION);
        registry.addResourceHandler("swagger-resources.html").addResourceLocations(RESOURCE_LOCATION);
        registry.addResourceHandler("docs.html").addResourceLocations(RESOURCE_LOCATION);
        registry.addResourceHandler("/webjars/**").addResourceLocations(RESOURCE_LOCATION+"webjars/");
    }

    /**
     * 拦截后的跨域解决
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        /*
         * .addMapping("/cors/**")
         */
        registry.addMapping("/cors/**")
                .allowedHeaders("*")
                .allowCredentials(true)
                .allowedMethods("GET","POST", "PUT", "OPTIONS")
                .allowedOrigins("*");
    }


    /**
     * 处理拦截前处理检测 授权跨域问题
     *
     */
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig());
        return new CorsFilter(source);
    }

    /**
     * @return
     */
    private CorsConfiguration corsConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // 请求常用的三种配置,*代表允许所有,当时你也可以自定义属性(比如header只能带什么,只能是post方式等等)
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setMaxAge(3600L);
        return corsConfiguration;
    }

}

4.swagger接口复制过来添加你需要修改补充的内容

import com.google.common.base.Optional;
import com.google.common.base.Strings;
import com.mes7801.service.utils.ClassUint;
import io.swagger.models.Path;
import io.swagger.models.Swagger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponents;
import springfox.documentation.service.Documentation;
import springfox.documentation.spring.web.DocumentationCache;
import springfox.documentation.spring.web.json.Json;
import springfox.documentation.spring.web.json.JsonSerializer;
import springfox.documentation.swagger.common.HostNameProvider;
import springfox.documentation.swagger2.mappers.ServiceModelToSwagger2Mapper;
import springfox.documentation.swagger2.web.Swagger2Controller;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Description:获取swagger的接口文档并添加需要加入的接口
 * Author: zyg
 * Date: 2020-03-30 15:07
 */
@RestController
@RequestMapping("/api")
@Scope("request")
public class GetSwaggerApiDocController {

    public static final String DEFAULT_URL = "/v2/api-docs";
    private static final Logger LOGGER = LoggerFactory.getLogger(Swagger2Controller.class);
    private static final String HAL_MEDIA_TYPE = "application/hal+json";
    private final String hostNameOverride;
    private final DocumentationCache documentationCache;
    private final ServiceModelToSwagger2Mapper mapper;
    private final JsonSerializer jsonSerializer;

    @Autowired
    public GetSwaggerApiDocController(Environment environment, DocumentationCache documentationCache, ServiceModelToSwagger2Mapper mapper, JsonSerializer jsonSerializer) {
        this.hostNameOverride = environment.getProperty("springfox.documentation.swagger.v2.host", "DEFAULT");
        this.documentationCache = documentationCache;
        this.mapper = mapper;
        this.jsonSerializer = jsonSerializer;
    }

    /**
     * 获取swagger返回的 json
     * //@RequestParam(value = "condition") String condition,
     */
    @RequestMapping(value = "/swagger2", method = RequestMethod.GET)
    public ResponseEntity<Json> getDocumentation(@RequestParam(value = "group", required = false) String swaggerGroup, HttpServletRequest servletRequest) {
        String groupName = (String) Optional.fromNullable(swaggerGroup).or("spring-test-interface");
        Documentation documentation = this.documentationCache.documentationByGroup(groupName);
        if (documentation == null) {
            LOGGER.warn("Unable to find specification for group {}", groupName);
            return new ResponseEntity(HttpStatus.NOT_FOUND);
        } else {
            //获取swagger返回的json
            Swagger swagger = this.mapper.mapDocumentation(documentation);
            UriComponents uriComponents = HostNameProvider.componentsFrom(servletRequest, swagger.getBasePath());
            swagger.basePath(Strings.isNullOrEmpty(uriComponents.getPath()) ? "/" : uriComponents.getPath());
            if (Strings.isNullOrEmpty(swagger.getHost())) {
                swagger.host(this.hostName(uriComponents));
            }

            /************************这里加入你想加入的代码****************************/
            /************************因为这里还没有生成转换后的swagger的json****************************/
            swagger.setPaths(pathTmp);

            return new ResponseEntity(this.jsonSerializer.toJson(swagger), HttpStatus.OK);
        }
    }

    private String hostName(UriComponents uriComponents) {
        if ("DEFAULT".equals(this.hostNameOverride)) {
            String host = uriComponents.getHost();
            int port = uriComponents.getPort();
            return port > -1 ? String.format("%s:%d", host, port) : host;
        } else {
            return this.hostNameOverride;
        }
    }

5. 自定义页面的引入

5.1.可以在项目的基础上新增一个servlet ,指向对应的html文件
html文件里再去解析json,并渲染UI

5.2.新建一个项目,用webjars将前端资源打成jar包,再供其他项目使用
项目结构如图

swagger-ui-layer项目结构如图

这里自己就可以改造docs.js 把访问路径改为 GetSwaggerApiDocController的访问路径swagger2,现在返回的swagger文档是自己改造过的,docs.html也可以自己改造

 

感谢 https://blog.csdn.net/tuposky/article/details/77965139

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值