Why does springfox-swagger2 UI tell me "Unable to infer base url."
Why does springfox-swagger2 UI tell me Unable to infer base url. As far as I know, I am using a typical Swagger spring-boot configuration. As you can see in the screenshot, the swagger-fox url
stackoverflow.com
스프링 시큐리티를 사용하는 환경에서 스웨거를 붙여서 쓰려고 하니 스웨거의 경로로 접근이 안 되는 문제가 발생했다.
여러 삽질을 모두 다 해보았지만 해결이 되지 않았었는데, 나름 야매(?) 적인 방식인지는 모르겠지만 해결 방법을 찾아 포스팅한다.
나의 경우는 RestControllerAdvisor 를 활용하여 공통 Response DTO 를 만들어서 클라이언트 단에 반환하고 있었다.
즉, Advisor 를 사용하고 있다면 beforeBodyWrite 에게 Response 를 넘길지 말지를 판단하는 supports 메소드 단에서 Swagger 엔드 포인트에 대하여 무시 처리를 해주어야 한다.
즉, Swagger를 관리하는 Swagger2Controller와 ApiResourceController 가 Custom Response(beforeBodyWrite 메소드)를 통과하지 못하도록 막아야 한다.
package egovframework.lms.boot.advisor;
import egovframework.lms.boot.dto.CommonResponseDto;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.io.IOException;
@RestControllerAdvice
public class RestResponseAdvisor<T> implements ResponseBodyAdvice<T> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
String className = returnType.getContainingClass().getSimpleName();
// Swagger2Controller 와 ApiResourceController 에 대한 요청일 경우 return false 로 처리한다.
if(className.equals("ExceptionHandler") || className.equals("Swagger2Controller") || className.equals("ApiResourceController"))
return false;
return true;
}
@Override
public T beforeBodyWrite(T body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
// 공통 Response 생성
ServletServerHttpResponse httpResponse = (ServletServerHttpResponse) response;
Integer statusCode = httpResponse.getServletResponse().getStatus();
CommonResponseDto responseDto = CommonResponseDto.builder()
.success(true)
.statusCode(statusCode)
.msg("")
.data(body)
.build();
return (T) responseDto;
}
}
아 또, custom context path 를 사용하고 있다면 (나의 경우는 /api/v1) Swagger Config 에서 Path Mapping을 /로 지정해주어야 엔드포인트가 정상 호출된다.
만일, Path Mapping 을 Custom Context Path 에 따라 /api/v1 로 지정한다면 호출 시 /api/v1/api/v1 과 같이 Context Path 가 두 번 붙는 경우가 발생한다.
package egovframework.lms.boot.config;
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.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(
RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
// Before
// .pathMapping("/api/v1")
// After
.pathMapping("/")
.apiInfo(
new ApiInfoBuilder()
.title("Spring Security take over Swagger Authentication authorization")
.description("Spring Security and Swagger")
.version("1.0.0")
.contact(
new Contact(
"Fox under the tree",
"https://www.ramostear.com",
"ramostear@163.com"
)
).build()
);
}
}
정상 동작한다.
'Programming > Spring' 카테고리의 다른 글
[Spring Boot] Maven 프로젝트 Heroku 에 배포하기 (0) | 2022.07.01 |
---|---|
스프링 Multipart Form Data JSON 형태로 받기 (0) | 2022.05.10 |