Webflux还不支持ResponseBodyAdvice吗?

时间:2018-02-09 11:49:53

标签: spring spring-webflux

由于ResponseBodyAdvice接口位于web.servlet包中 我怎么能在webflux中实现这样的功能?

2 个答案:

答案 0 :(得分:1)

我也有这个问题,我发现可以通过HandlerResultHandler完成。

例如,我扩展ResponseBodyResultHandler来包装我的所有回复

首先,您应该写ResponseWrapper.java

public class ResponseWrapper extends ResponseBodyResultHandler {
    private static MethodParameter param;

    static {
        try {
            //get new params
            param = new MethodParameter(ResponseWrapper.class
                    .getDeclaredMethod("methodForParams"), -1);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public ResponseWrapper(List<HttpMessageWriter<?>> writers, RequestedContentTypeResolver resolver) {
        super(writers, resolver);
    }

    private static Mono<Response> methodForParams() {
        return null;
    }

    @Override
    public boolean supports(HandlerResult result) {
        boolean isMono = result.getReturnType().resolve() == Mono.class;
        boolean isAlreadyResponse = result.getReturnType().resolveGeneric(0) == Response.class;
        return isMono && !isAlreadyResponse;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
        Preconditions.checkNotNull(result.getReturnValue(), "response is null!");
        // modify the result as you want
        Mono<Response> body = ((Mono<Object>) result.getReturnValue()).map(Response::success)
                .defaultIfEmpty(Response.success());
        return writeBody(body, param, exchange);
    }
}    

然后,在SpringBootApplication中添加Bean

@SpringBootApplication
public class SmartApplication {

    @Autowired
    ServerCodecConfigurer        serverCodecConfigurer;
    @Autowired
    RequestedContentTypeResolver requestedContentTypeResolver;

    @Bean
    ResponseWrapper responseWrapper() {
        return new ResponseWrapper(serverCodecConfigurer
                .getWriters(), requestedContentTypeResolver);
    }
    //Spring start
    public static void main(String[] args) {
        SpringApplication.run(SmartApplication.class, args);
    }
}

我的回答班,仅供参考

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Response<T> {
    boolean success;
    T       data;
    Object  error;
    String  warning;

    public Response() {
    }


    public static Response success() {
        return success(null);
    }

    public static <T> Response success(T data) {
        return new Response<T>().setSuccess(true).setData(data);
    }

    public static Response error(Throwable e) {
        LogManager.getLogger(StackLocatorUtil.getCallerClass(2)).info(e);
        return new Response().setSuccess(false).setError(e);
    }

    public static Response error(Object e) {
        return new Response().setSuccess(false).setError(e);
    }

    public static Response error(String e) {
        return new Response().setSuccess(false).setError(e);
    }

    /* get success */
    public boolean isSuccess() {
        return success;
    }

    /* set success */
    public Response setSuccess(boolean success) {
        this.success = success;
        return this;
    }

    /* get data */
    public Object getData() {
        return data;
    }

    /* set data */
    public Response setData(T data) {
        this.data = data;
        return this;
    }

    /* get error */
    public Object getError() {
        return error;
    }

    /* set error */
    public Response setError(Object error) {
        this.error = error;
        return this;
    }
}

答案 1 :(得分:0)

我在Spring 5.0之前使用ResponseBodyAdvise。我认为从spring5.0开始,ResponseBodyResultHandler支持webflux。