如何通过zuul添加或修改请求参数

 更新时间:2021年07月27日 10:14:02   作者:矿泉  
这篇文章主要介绍了如何通过zuul添加或修改请求参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

zuul添加或修改请求参数

一、为什么要用到这个

在基于 springcloud 构建的微服务系统中,通常使用网关zuul来进行一些用户验证等过滤的操作,比如 用户在 header 或者 url 参数中存放了 token ,网关层需要 用该 token 查出用户 的 userId ,并存放于 request 中,以便后续微服务可以直接使用而避免再去用 token 查询。

二、基础知识

在 zuul 中最大的用法的除了路由之外,就是过滤器了,自定义过滤器需实现接口 ZuulFilter ,在 run() 方法中,可以用

RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();

获取到 request,但是在 request 中只有 getParameter() 而没有 setParameter() 方法,所以直接修改 url 参数不可行,另外在 reqeust 中虽然可以使用 setAttribute() ,但是可能由于作用域的不同,在这里设置的 attribute 在后续的微服务中是获取不到的,因此必须考虑另外的方式。

三、具体做法

最后确定的可行的方法是,用

ctx.setRequest(new HttpServletRequestWrapper(request) {})

的方式,重新构造上下文中的 request ,代码如下:

// 例如在请求参数中添加 userId
try {
  InputStream in = ctx.getRequest().getInputStream();
  String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
  if(StringUtils.isBlank(body)){
    body = "{}";
  }
  JSONObject jsonObject = JSON.parseObject(body);
  jsonObject.put("userId", 666);
  String newBody = jsonObject.toString();
  final byte[] reqBodyBytes = newBody.getBytes();
  ctx.setRequest(new HttpServletRequestWrapper(request){    
    @Override
    public ServletInputStream getInputStream() throws IOException {
      return new ServletInputStreamWrapper(reqBodyBytes);
    }
    @Override
    public int getContentLength() {
      return reqBodyBytes.length;
    }
    @Override
    public long getContentLengthLong() {
      return reqBodyBytes.length;
    }
  });
} catch (IOException e) {
  e.printStackTrace();
}

思路就是,获取请求的输入流,并重写,即重写json参数。

在后续的微服务的 controller 中,通过下面的方式获取通过zuul添加或修改的请求参数。

InputStream in = request().getInputStream();
String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
if(StringUtils.isNotBlank(body)){
  JSONObject jsonObject = JSON.parseObject(body);
  Object userId = jsonObject.get("userId");
}

zuul修改请求url

除了修改请求参数、设置响应header,响应body外,还有一种需求就是url重新,或者是修改url,这里简述一下怎么在zuul修改url。

转发配置

demo:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    listOfServers: 192.168.99.100,192.168.99.101
zuul:
  routes:
    demo:
      path: /demo/**
      stripPrefix: true
      serviceId: demo

filter配置

@Component
public class UrlPathFilter extends ZuulFilter{
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }
    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
    }
    @Override
    public boolean shouldFilter() {
        final String serviceId = (String) RequestContext.getCurrentContext().get("proxy");
        return "demo".equals(serviceId);
    }
    @Override
    public Object run() {
        RequestContext context = RequestContext.getCurrentContext();
        Object originalRequestPath = context.get(FilterConstants.REQUEST_URI_KEY);
        //http://localhost:10000/demo/list/data
        //-->/api/prefix/list/data
        String modifiedRequestPath = "/api/prefix" + originalRequestPath;
        context.put(FilterConstants.REQUEST_URI_KEY, modifiedRequestPath);
        return null;
    }
}

这样就大功告成了!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java日常练习题,每天进步一点点(27)

    Java日常练习题,每天进步一点点(27)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • java实现远程桌面的实例代码

    java实现远程桌面的实例代码

    下面小编就为大家分享一篇java实现远程桌面的实例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Java如何获取List<String>中的String详解

    Java如何获取List<String>中的String详解

    工作了这么长时间了,一直没有记录的习惯,以至于导致我即便是查过的东西总会忘记,下面这篇文章主要给大家介绍了关于Java如何获取List<String>中String的相关资料,需要的朋友可以参考下
    2022-02-02
  • Java Scanner 类读取一维数组二维数组示例详解

    Java Scanner 类读取一维数组二维数组示例详解

    这篇文章主要为大家介绍了Java Scanner 类读取一维数组二维数组示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • SpringBoot没有主清单属性的解决方法

    SpringBoot没有主清单属性的解决方法

    在本篇文章里小编给大家整理的是关于解决SpringBoot没有主清单属性知识点,需要的朋友们学习下。
    2019-11-11
  • spring-boot通过@Scheduled配置定时任务及定时任务@Scheduled注解的方法

    spring-boot通过@Scheduled配置定时任务及定时任务@Scheduled注解的方法

    这篇文章主要介绍了spring-boot通过@Scheduled配置定时任务,文中还给大家介绍了springboot 定时任务@Scheduled注解的方法,需要的朋友可以参考下
    2017-11-11
  • java 随机生成6位短信验证码实例代码

    java 随机生成6位短信验证码实例代码

    这篇文章主要介绍了java 随机生成6位短信验证码的实例代码,文中给大家扩展介绍了java随机生成四位数字验证码的方法,需要的朋友可以参考下
    2019-12-12
  • Java泛型中<?>和<T>的区别浅析

    Java泛型中<?>和<T>的区别浅析

    <T>和<?>的区别 <T>是参数类型,常常用于泛型类或泛型方法的定义,下面这篇文章主要给大家介绍了关于Java泛型中<?>和<T>区别的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • java实战之桌球小游戏

    java实战之桌球小游戏

    这篇文章主要为大家详细介绍了java实战之桌球小游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • SpringCloud 微服务最佳开发实践

    SpringCloud 微服务最佳开发实践

    本文结合我们实际的开发中遇到的一些问题整理出了一份微服务开发的实践规范,对SpringCloud 微服务开发实践相关知识感兴趣的朋友一起看看吧
    2021-07-07

最新评论