The project is built based on Springboot. In order to interact with the front end, Swagger is integrated in the background. How to use Swagger can be explained in another article.During project optimization, in order to make the return value of the Controller interface semantically clear, instead of uniformly returning ApiResult, the structure is similar to the one shown above (please ignore the background image). The following code was introduced into the project

package com.yizhun.label.user.config; import com.yizhun.auth.model.ApiResult; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import springfox.documentation.spring.web.json.Json; import springfox.documentation.swagger.web.SwaggerResource; import springfox.documentation.swagger.web.UiConfiguration; import java.util.ArrayList; /** * @author Alex * @version 1.0 * @date 2021-01-18 9:58 PM */ @restControllerAdvice public class GlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse Response) {if (body instanceof ApiResult) return body; return new ApiResult(body); }}Copy the code

After the configuration, I accidentally found that the swagger of the project integration could not be displayed. Since there were many changes in the code at that time, I did not immediately think that the problem was caused by the advice that configured the global response. Since the failure of Swagger could not be solved all the time, I had no choice but to roll back all the codes. In line with the principle of one step at a time, I changed a little code and ran to see whether Swagger was normal. I didn’t find the problem until the above configuration was added.

Before the global response is added, all interfaces directly return their own content. After the global response is added, it is equivalent to encapsulating the returned value, resulting in the change of the return structure of swagger related interfaces, resulting in the failure of Swagger. The beforeBodyWrite method of Override is modified

@Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {/ / here need to filter out the relevant swagger back if (body instanceof ApiResult | | body instanceof Json | | body instanceof UiConfiguration || (body instanceof ArrayList && ((ArrayList) body).get(0) instanceof SwaggerResource)) return body; return new ApiResult(body); }Copy the code

Swagger involves three interfaces, respectively

  • {domain}/swagger-resources/configuration/ui
  • {domain}/swagger-resources
  • {domain}/v2/api-docs

The body type returned by the three interfaces when they reach the beforeBodyWrite method is

  • UiConfiguration
  • ArrayList
  • Json

If the body type is ArrayList and the first element of the ArrayList is SwaggerResource, the code is as follows:

@Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {/ / here need to filter out the relevant swagger back if (body instanceof ApiResult | | body instanceof Json | | body instanceof UiConfiguration || (body instanceof ArrayList && ((ArrayList) body).get(0) instanceof SwaggerResource)) return body; return new ApiResult(body); }Copy the code

Based on the above code, deal with the problem that the project configuration global response causes swagger to fail.