我有一个自定义(pre)zuul过滤器,因为我想记录一个API请求的requestBody(API在服务中可以注册到Eureka)但是当我在ZUUL中使用下面的代码时
HttpServletRequest request.getReader();
或
RequestContext.getCurrentContext().getRequest().getInputStream();
我可以记录requestBody但是 -
问题: 具有API的服务无法获取requestBody,因为无法再次在同一请求上调用getReader。我知道我需要有一些扩展HttpServletRequestWrapper和覆盖getReader()方法的东西,但我不知道如何处理ZUUL上下文,如何在请求后将请求和requestBody一起转发给ZUUL服务。
任何建议都会有所帮助。
答案 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;
}
}