自定义Zuul过滤器 - 日志请求正文

时间:2016-03-23 12:51:32

标签: spring-cloud netflix-zuul

我有一个自定义(pre)zuul过滤器,因为我想记录一个API请求的requestBody(API在服务中可以注册到Eureka)但是当我在ZUUL中使用下面的代码时

HttpServletRequest request.getReader();RequestContext.getCurrentContext().getRequest().getInputStream();

我可以记录requestBody但是 -

问题: 具有API的服务无法获取requestBody,因为无法再次在同一请求上调用getReader。我知道我需要有一些扩展HttpServletRequestWrapper和覆盖getReader()方法的东西,但我不知道如何处理ZUUL上下文,如何在请求后将请求和requestBody一起转发给ZUUL服务。

任何建议都会有所帮助。

1 个答案:

答案 0 :(得分:0)

您可以直接将传入请求包装在 HttpServletRequestWrapper 实例中。这是示例代码。希望这会有所帮助。

package com.example.edge.filter.pre;

import com.google.common.io.CharStreams;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

@Component
public class RequestPayloadLoggingFilter extends ZuulFilter {

    private static Logger log = LoggerFactory.getLogger(RequestPayloadLoggingFilter.class);

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 2;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = new HttpServletRequestWrapper(ctx.getRequest());

        log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));

        String requestData = null;
        JSONParser jsonParser = new JSONParser();
        JSONObject requestJson = null;

        try {
            if (request.getContentLength() > 0 ) {
                requestData = CharStreams.toString(request.getReader());
            }

            if (requestData == null) {
                return null;
            }
            requestJson = (JSONObject) jsonParser.parse(requestData);
        } catch (Exception e) {
            log.error("Error parsing JSON request", e);
            return null;
        }
        log.info(String.format("%s request payload %s", request.getMethod(), requestJson.toJSONString()));
        return null;
    }
}