我目前正在使用Spring Netflix Zuul库为一个新的微服务系统构建一个API网关。
到目前为止,我的网关包含PRE和POST过滤器,它们拦截请求并执行所需的逻辑,等等。
我看到的一件事是,对特定微服务的REST调用需要调用包含JSON有效负载数据的API端点( GET或POST),这非常复杂。
对于最终用户,向包含此JSON的微服务发送请求将不是用户友好的。
我的想法是,API网关充当中介者,用户可以向API网关提交更“简化/用户友好”的JSON,API网关将使用目标微服务可以理解的正确的“复杂”JSON结构来转换JSON有效负载,以便有效地处理请求。
我对Netflix Zuul的理解是,这可以通过创建一个RouteFilter,然后在这里包含以下逻辑来完成。
有人能解释一下这种转变是否(或如何)可以使用Netflix Zuul完成吗?
任何建议都是值得感谢的。
谢谢。
发布于 2018-01-31 18:21:42
毫无疑问,你可以用Zuul做到这一点,我现在也在尝试做同样的事情。我建议你看看这个回购:
和github上的official doc。
过滤器必须扩展ZuulFilter并实现以下方法:
/**
*return a string defining when your filter must execute during zuul's
*lyfecyle ('pre'/'post' routing
**/
@Override
public String filterType(){
return 'pre'; // run this filter before sending the final request
}
/**
* return an int describing the order that the filter should run on,
* (relative to the other filters and the current 'pre' or 'post' context)
**/
@Override
public int filterOrder {
return 1; //this filter runs first in a pre-request context
}
/**
* return a boolean indicating if the filter should run or not
**/
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
if(ctx.getRequest().getRequestURI().equals("/theRouteIWantToFilter"))
{
return true;
}
else {
return false;
}
}
/**
* After all the config stuffs you can set what your filter actually does
* here. This is where your json logic goes.
*/
@Override
public Object run() {
try {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
InputStream stream = ctx.getResponseDataStream();
String body = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
// transform your json and send it to the api.
ctx.setResponseBody(" Modified body : " + body);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}我不确定我的答案是100%准确的,因为我正在努力,但这是一个开始。
发布于 2018-05-07 00:55:11
我已经在预过滤中进行了有效负载转换,但这在路由过滤器中也应该有效。在将请求转发到目标微服务之前,使用com.netflix.zuul.http.HttpServletRequestWrapper捕获并修改原始请求负载。
示例代码:
package com.sample.zuul.filters.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 com.netflix.zuul.http.ServletInputStreamWrapper;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class JsonConverterFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0; // Set it to whatever the order of your filter is
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = new HttpServletRequestWrapper(context.getRequest());
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) {
//Add your exception handling code here
}
JSONObject modifiedRequest = modifyJSONRequest(requestJson);
final byte[] newRequestDataBytes = modifiedRequest.toJSONString().getBytes();
request = getUpdatedHttpServletRequest(request, newRequestDataBytes);
context.setRequest(request);
return null;
}
private JSONObject modifyJSONRequest(JSONObject requestJSON) {
JSONObject jsonObjectDecryptedPayload = null;
try {
jsonObjectDecryptedPayload = (JSONObject) new JSONParser()
.parse("Your new complex json");
} catch (ParseException e) {
e.printStackTrace();
}
return jsonObjectDecryptedPayload;
}
private HttpServletRequest getUpdatedHttpServletRequest(HttpServletRequest request, final byte[] newRequestDataBytes) {
request = new javax.servlet.http.HttpServletRequestWrapper(request) {
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(
new InputStreamReader(new ByteArrayInputStream(newRequestDataBytes)));
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamWrapper(newRequestDataBytes);
}
/*
* Forcing any calls to HttpServletRequest.getContentLength to return the accurate length of bytes
* from a modified request
*/
@Override
public int getContentLength() {
return newRequestDataBytes.length;
}
};
return request;
}
}https://stackoverflow.com/questions/48230092
复制相似问题