RequestAdvice.java 3.73 KB
package com.infoloop.tianting.advice;

import cn.hutool.json.JSONObject;
import com.infoloop.tianting.model.common.ResponseResult;
import com.infoloop.tianting.utils.JsonUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonInputMessage;
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.RequestBodyAdviceAdapter;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

@SuppressWarnings("all")
@RestControllerAdvice(basePackages = "com.infoloop.tianting.controller")
public class RequestAdvice extends RequestBodyAdviceAdapter implements ResponseBodyAdvice<Object> {
    private static final Logger LOGGER = LoggerFactory.getLogger(RequestAdvice.class);

    private static final String VOID = "void";

    @Override
    public boolean supports(final MethodParameter methodParameter,
                            final Type targetType,
                            final Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public HttpInputMessage beforeBodyRead(final HttpInputMessage inputMessage,
                                           final MethodParameter parameter,
                                           final Type targetType,
                                           Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
        final var stringBuilder = new StringBuilder();
        try (final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputMessage.getBody(), StandardCharsets.UTF_8))) {
            var line = bufferedReader.readLine();
            while (line != null) {
                stringBuilder.append(line);
                line = bufferedReader.readLine();
            }
            bufferedReader.close();
            final var body = stringBuilder.toString();
            if (!new JSONObject(body).isEmpty()) {
                LOGGER.info("request body: {}", body);
            }
            return new MappingJacksonInputMessage(new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)), inputMessage.getHeaders());
        }
    }

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return !VOID.equals(getReturnName(returnType)) && !returnType.getGenericParameterType().equals(ResponseResult.class);
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof ResponseResult) {
            return body;
        }
        if (body instanceof String) {
            return JsonUtil.writeAsJson(ResponseResult.ok(body));
        }
        return ResponseResult.ok(body);
    }

    private String getReturnName(MethodParameter returnType) {
        if (returnType == null || returnType.getMethod() == null) {
            return StringUtils.EMPTY;
        }
        return returnType.getMethod().getReturnType().getName();
    }

}