springcloud 中 zuul 如何修改请求参数

一. 为什么要用到这个

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

二.基础知识

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

 


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

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

 

三.具体做法

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

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

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

 

 


 
 
  1. import javax.servlet.http.HttpServletRequestWrapper;
  2. // 在json参数中添加 userId
  3. try {
  4. InputStream in = ctx.getRequest().getInputStream();
  5. String body = StreamUtils.copyToString(in, Charset.forName( "UTF-8"));
  6. System.out.println( "body:" + body);
  7. JSONObject json = JSONObject.fromObject(body);
  8. json.put( "userId", userId);
  9.   String newBody = json.toString();
  10. System.out.println( "newBody:" + newBody);
  11. final byte[] reqBodyBytes = newBody.getBytes();
  12. ctx.setRequest( new HttpServletRequestWrapper(request){
  13. @Override
  14.   public ServletInputStream getInputStream() throws IOException {
  15. return new ServletInputStreamWrapper(reqBodyBytes);
  16. }
  17. @Override
  18. public int getContentLength() {
  19. return reqBodyBytes.length;
  20. }
  21. @Override
  22. public long getContentLengthLong() {
  23. return reqBodyBytes.length;
  24. }
  25. });
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }

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

在后续的微服务的 controller 中,可以用 形似


 
 
  1. @RequestBody Map <String,Object> body
  2. =======
  3. body.get("userId");

这样的方式,去获取在 zuulFilter 传入的 userId

 

四.一些尝试

 在重写  HttpServletRequestWrapper 的时候,我尝试过 重写 getParameterNames() 和 getParameterMap() 方法,希望重写 url 参数,但是并没有生效。具体原因不太清楚,如果有大神知道怎么办,欢迎指教。

=================================

以上尝试 已经找到可行方法:


 
 
  1. request.getParameterMap(); // 关键步骤,一定要get一下,下面这行代码才能取到值
  2. Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
  3. if (requestQueryParams == null) {
  4. requestQueryParams = new HashMap<>();
  5. }
  6. // 添加userId
  7. ArrayList<String> arrayList2 = new ArrayList<>();
  8. arrayList.add(userId + "");
  9. requestQueryParams.put( "userId", arrayList2);
  10. ctx.setRequestQueryParams(requestQueryParams);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值