Zuulをpost
フィルターのプロキシーとして使用しながら、応答本文を読み取るにはどうすればよいですか?
私はこのようなコードを呼び出そうとしています:
@Component
public class PostFilter extends ZuulFilter {
private static final Logger log = LoggerFactory.getLogger(PostFilter.class);
@Override
public String filterType() {
return "post";
}
@Override
public int filterOrder() {
return 2000;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.getResponseBody(); // null
// cant't do this, cause input stream is used later in other filters and I got InputStream Closed exception
// GZIPInputStream gzipInputStream = new GZIPInputStream(stream);
return null;
}
}
私はこれをなんとか乗り越えました。ソリューションは4つのステップで構成されています。
ctx.getResponseDataStream()
をByteArrayOutputStreamに読み込みますcontext.setResponseBody(inputStream)
提案をありがとう、これは私が使用したコードで機能します。
try (final InputStream responseDataStream = ctx.getResponseDataStream()) {
final String responseData = CharStreams.toString(new InputStreamReader(responseDataStream, "UTF-8"));
ctx.setResponseBody(responseData);
} catch (IOException e) {
logger.warn("Error reading body",e);
}
この example を見るとわかるように、応答の本文を抽出するには、2つの方法があります。
1- ctx.getResponseBody();
2- ctx.getResponseDataStream();
Nullでないものを確認し、それを使用する必要があります。
誰かが圧縮された回答に苦労している場合、私が使用した解決策は次のとおりです:
// Read the compressed response
RequestContext ctx = RequestContext.getCurrentContext();
InputStream compressedResponseDataStream = ctx.getResponseDataStream();
try {
// Uncompress and transform the response
InputStream responseDataStream = new GZIPInputStream(compressedResponseDataStream);
String responseAsString = StreamUtils.copyToString(responseDataStream, Charset.forName("UTF-8"));
// Do want you want with your String response
...
// Replace the response with the modified object
ctx.setResponseBody(responseAsString);
} catch (IOException e) {
logger.warn("Error reading body", e);
}
FilterNumberに注意してください
1000を超える値を使用すると、応答の本文が既に読み込まれており、
私は数字の10を使用し、うまくいきました
答えはどれもうまくいきませんでした。 1)フィルターの次数は1000より低くする必要があります(応答フィルターを送信)
2)コード:
private String getResponseData(RequestContext ctx) throws IOException {
String responseData = null;
final InputStream responseDataStream = ctx.getResponseDataStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteArrayOutputStream copy = new ByteArrayOutputStream();
int read = 0;
byte[] buff = new byte[1024];
while ((read = responseDataStream.read(buff)) != -1) {
bos.write(buff, 0, read);
copy.write(buff, 0, read);
}
InputStream isFromFirstData = new ByteArrayInputStream(bos.toByteArray());
boolean responseGZipped = ctx.getResponseGZipped();
try {
InputStream zin = null;
if (responseGZipped) {
zin = new GZIPInputStream(isFromFirstData);
} else {
zin = responseDataStream;
}
responseData = CharStreams.toString(new InputStreamReader(zin, "UTF-8"));
ctx.setResponseDataStream(new ByteArrayInputStream(copy.toByteArray()));
} catch (IOException e) {
logger.warn("Error reading body {}", e.getMessage());
}
return responseData;
}