当前位置: 首页 > 知识库问答 >
问题:

Spring Netflix Zuul:API网关-转换JSON请求

叶书
2023-03-14

我目前正在使用SpringNetflixZuul库为一个新的微服务系统构建API网关。

到目前为止,我的网关包含PREPOST过滤器,用于拦截请求并执行所需的逻辑等。

我看到的一件事是,对特定微服务的REST调用需要调用包含非常复杂的JSON有效负载数据的APIendpoint(GET或POST)。

对于最终用户来说,向包含此JSON的微服务发送请求对用户不友好。

我有一个想法,即API网关充当中介,用户可以在其中向API网关提交更“简化/用户友好”的JSON,这将使用正确的“复杂”JSON结构转换JSON有效负载目标微服务可以理解,以便有效地处理请求。

我对Netflix Zuul的理解是,这可以通过创建一个RouteFilter来实现,然后在这里包含这个逻辑。

有人能解释一下这种转变是否(或如何)可以使用NetflixZuul来完成吗?

任何建议都将不胜感激。

谢谢

共有2个答案

仉洲
2023-03-14

我已经在pre filter中完成了有效负载转换,但在route filter中也应该可以。使用com。netflix。祖尔。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;
    }
}
宰父深
2023-03-14

毫无疑问,你可以用Zuul做这件事,我目前正在尝试做几乎相同的事情。我建议你看看这个回购:

示例-zuul-过滤器

还有github上的官方文件。

过滤器必须扩展ZumFilter并实现以下方法:

/** 
 *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%准确,因为我正在努力,但这是一个开始。

 类似资料:
  • ---->HTTP-Inbound-Gateway->JSON-to-Object-Transformer-> 客户: 服务器: 我不希望在通道的特定映射器上显式地指示类型,因为它们可以变化。有没有一种方法来配置我需要的组件来支持这个路径? --引用-- (1)http://docs.spring.io/spring-integration/reference/html/messaging-tra

  • 我试图隐藏一个卷曲来吞咽请求,这里是卷曲请求。 以下是JSON部分:

  • 问题内容: 我有一个场景。 必需的输入和输出是JSON。 我需要一些转换代码或最好是xslt类型的语言才能将json从一种格式转换为另一种格式。该变压器也需要快速运行,因为转换将即时进行。 编辑 我没有收到INPUT对象的定义,它可能会在运行时更改。但是如果需要,我可以将类用于OUTPUT对象。我尝试以 json- > xml-> xslt-> xml-> json的方式进行此操作 ,但 此刻 每

  • 我想转换我的嵌套json消息,并使用Jolt规范只获取必需的文件- 我的输入JSON: 低于我的规格输出,这不是预期的- 我尝试了很多选择,但国籍不是我预期的输出。请在这里帮助颠簸转换

  • 我想转换这个JSON: 对此JSON: 我目前正在使用该规范,但它不适合我: 有人能给出一个规范吗?有没有关于jolt JSON的明确文档 ................................................................................................................................

  • 我只是想知道SAP NGW适配器是否能够将odata edm.datetime转换为JSON/JavaScript datetime。 例如...从SAP检索formation时,odata文档中提供了以下格式-“name_of_attribute”:“/date(1377561600000)/”我们在JSON中期望的内容:“name_of_attribute”:“2012-04-23T18:25