springboot使用ResponseBodyAdvice导致swagger无法显示的问题

springboot使用@RestController注解和ResponseBodyAdvice统一返回一个返回体

/**
 * @author lisuo
 * @version 1.0
 * @Description 自定义注解ResponseResult,之前使用RestController,导致拦截了swagger
 * @email 495019733@qq.com
 * @date 2021/11/30 0:59
 */
@ControllerAdvice(annotations = RestController.class)
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {


    /**
     * 判断是否要执行 beforeBodyWrite 方法,true为执行,false不执行,有注解标记的时候处理返回值
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    /**
     * 对返回值做包装处理
     * @param body
     * @param arg1
     * @param arg2
     * @param arg3
     * @param arg4
     * @param arg5
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter arg1, MediaType arg2,
                                  Class<? extends HttpMessageConverter<?>> arg3, ServerHttpRequest arg4, ServerHttpResponse arg5) {
        if (body instanceof Void){
            ResponseEntity.succeed("请求成功!");
        }
        if (body instanceof ResponseEntity) {
            return body;
        }
        return ResponseEntity.succeed(body);
    }

    @InitBinder
    public void binder(WebDataBinder webDataBinder){
        StringTrimmerEditor propertyEditor = new StringTrimmerEditor(false);
        webDataBinder.registerCustomEditor(String.class, propertyEditor);
    }
}

整合swagger3,然后访问swagger页面出现下面的问题

  <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>

 找遍了项目中的代码也没有发现订了其他的啥拦截器,后面一想自己定义了一个统一返回拦截,是不是这里出了问题,于是打了个断点,果然问题出在这里

 打开ApiResourceController一看果然类上面有一个@Restcontroller注解,瞬间明白了问题所在

/*
 *
 *  Copyright 2015-2019 the original author or authors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *
 */

package springfox.documentation.swagger.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import java.util.List;

@RestController
@ApiIgnore
@RequestMapping({
    "${springfox.documentation.swagger-ui.base-url:}/swagger-resources"})
public class ApiResourceController {

  @Autowired(required = false)
  private SecurityConfiguration securityConfiguration;
  @Autowired(required = false)
  private UiConfiguration uiConfiguration;

  private final SwaggerResourcesProvider swaggerResources;

  @Autowired
  public ApiResourceController(
      SwaggerResourcesProvider swaggerResources,
      @Value("${springfox.documentation.swagger-ui.base-url:}") String swaggerUiBaseUrl) {
    this.swaggerResources = swaggerResources;
    this.uiConfiguration = UiConfigurationBuilder.builder()
        .copyOf(uiConfiguration)
        .swaggerUiBaseUrl(StringUtils.trimTrailingCharacter(swaggerUiBaseUrl, '/'))
        .build();
    this.securityConfiguration = SecurityConfigurationBuilder.builder()
        .copyOf(securityConfiguration)
        .build();
  }

  @GetMapping(value = "/configuration/security", produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<SecurityConfiguration> securityConfiguration() {
    return new ResponseEntity<>(securityConfiguration, HttpStatus.OK);
  }

  @GetMapping(value = "/configuration/ui", produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<UiConfiguration> uiConfiguration() {
    return new ResponseEntity<>(uiConfiguration, HttpStatus.OK);
  }

  @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<List<SwaggerResource>> swaggerResources() {
    return new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK);
  }
}

解决方法1:

在实现ResponseBodyAdvice的类上面选择拦截的注解是自定义注解@ResponseResult

,然后在所有的controller类上面加一个自定义注解

/**
 * @author lisuo
 * @version 1.0
 * @Description
 * @email 495019733@qq.com
 * @date 2021/11/30 1:02
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD})
@Documented
public @interface ResponseResult {

}
/**
 * @author lisuo
 * @version 1.0
 * @Description 自定义注解ResponseResult,之前使用RestController,导致拦截了swagger
 * @email 495019733@qq.com
 * @date 2021/11/30 0:59
 */
@ControllerAdvice(annotations = ResponseResult.class)
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {


    /**
     * 判断是否要执行 beforeBodyWrite 方法,true为执行,false不执行,有注解标记的时候处理返回值
     * 这里整合swagger出现了问题,swagger相关的不拦截
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return !returnType.getDeclaringClass().getName().contains("springfox");
    }

    /**
     * 对返回值做包装处理
     * @param body
     * @param arg1
     * @param arg2
     * @param arg3
     * @param arg4
     * @param arg5
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter arg1, MediaType arg2,
                                  Class<? extends HttpMessageConverter<?>> arg3, ServerHttpRequest arg4, ServerHttpResponse arg5) {
        if (body instanceof Void){
            ResponseEntity.succeed("请求成功!");
        }
        if (body instanceof ResponseEntity) {
            return body;
        }
        return ResponseEntity.succeed(body);
    }

    @InitBinder
    public void binder(WebDataBinder webDataBinder){
        StringTrimmerEditor propertyEditor = new StringTrimmerEditor(false);
        webDataBinder.registerCustomEditor(String.class, propertyEditor);
    }
}

解决方法2:

在support方法里面过滤掉swagger相关的方法拦截

/**
 * @author lisuo
 * @version 1.0
 * @Description 自定义注解ResponseResult,之前使用RestController,导致拦截了swagger
 * @email 495019733@qq.com
 * @date 2021/11/30 0:59
 */
@ControllerAdvice(annotations = RestController.class)
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {


    /**
     * 判断是否要执行 beforeBodyWrite 方法,true为执行,false不执行,有注解标记的时候处理返回值
     * 这里整合swagger出现了问题,swagger相关的不拦截
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return !returnType.getDeclaringClass().getName().contains("springfox");
    }

    /**
     * 对返回值做包装处理
     * @param body
     * @param arg1
     * @param arg2
     * @param arg3
     * @param arg4
     * @param arg5
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter arg1, MediaType arg2,
                                  Class<? extends HttpMessageConverter<?>> arg3, ServerHttpRequest arg4, ServerHttpResponse arg5) {
        if (body instanceof Void){
            ResponseEntity.succeed("请求成功!");
        }
        if (body instanceof ResponseEntity) {
            return body;
        }
        return ResponseEntity.succeed(body);
    }

    @InitBinder
    public void binder(WebDataBinder webDataBinder){
        StringTrimmerEditor propertyEditor = new StringTrimmerEditor(false);
        webDataBinder.registerCustomEditor(String.class, propertyEditor);
    }
}

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值