Zuul 修改 请求头、响应头 (死磕)

疯狂创客圈 Java 高并发【 亿级流量聊天室实战】实战系列 【博客园总入口

架构师成长+面试必备之 高并发基础书籍 【Netty Zookeeper Redis 高并发实战


前言

Crazy-SpringCloud 微服务脚手架 &视频介绍

Crazy-SpringCloud 微服务脚手架,是为 Java 微服务开发 入门者 准备的 学习和开发脚手架。并配有一系列的使用教程和视频,大致如下:

高并发 环境搭建 图文教程和演示视频,陆续上线:

中间件 链接地址
Linux Redis 安装(带视频) Linux Redis 安装(带视频)
Linux Zookeeper 安装(带视频) Linux Zookeeper 安装, 带视频
Windows Redis 安装(带视频) Windows Redis 安装(带视频)
RabbitMQ 离线安装(带视频) RabbitMQ 离线安装(带视频)
ElasticSearch 安装, 带视频 ElasticSearch 安装, 带视频
Nacos 安装(带视频) Nacos 安装(带视频)

Crazy-SpringCloud 微服务脚手架 图文教程和演示视频,陆续上线:

组件 链接地址
Eureka Eureka 入门,带视频
SpringCloud Config springcloud Config 入门,带视频
spring security spring security 原理+实战
Spring Session SpringSession 独立使用
分布式 session 基础 RedisSession (自定义)
重点: springcloud 开发脚手架 springcloud 开发脚手架
SpingSecurity + SpringSession 死磕 (写作中) SpingSecurity + SpringSession 死磕

小视频以及所需工具的百度网盘链接,请参见 疯狂创客圈 高并发社群 博客

Zuul 修改请求头、响应头的场景

由于 SpingSecurity + SpringSession 整合场景,涉及到修改Zuul请求头的问题。

故梳理一个比较全面的Zuul 修改请求头、响应头的文章

1 SpingSecurity + SpringSession 整合场景二

本场景为统一网关 + 微服务场景:网关 SpingSecurity 实现 token认证,转成sessionID后,路由到单体微服务, 单体微服务 的 SpringSession 实现Session 共享。SessionID 保持在 token中。

在这里插入图片描述

2 功能介绍:

Zuul网关 SpingSecurity 实现 token认证,从token中提取sessionID,放入header头部,再传给后台微服务

在这里插入图片描述

3 参考文献:Zuul 使用filter 修改请求头和响应头

一: 修改请求参数,参见 博文

RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
     Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();

        if (requestQueryParams==null) {
            requestQueryParams=new HashMap<>();
        }

        //将要新增的参数添加进去,被调用的微服务可以直接 去取,就想普通的一样,框架会直接注入进去
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("1");
        requestQueryParams.put("test", arrayList);

        ctx.setRequestQueryParams(requestQueryParams);

二: 修改请求头,参见 博文

RequestContext ctx = RequestContext.getCurrentContext();  
ctx.addZuulRequestHeader("original_requestURL",request.getRequestURL().toString());

三:修改响应头,参见 博文

RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletResponse response = ctx.getResponse();
		String info = response.getHeader("info");
		String info_size = response.getHeader("info_size");
		/**
		 * 设置响应头,使请求变为文件下载
		 */
		ctx.addZuulResponseHeader("Content-Type", "application/octet-stream");
        ctx.addZuulResponseHeader("Content-Disposition", "attachment;fileName=" + info);
        ctx.addZuulResponseHeader("Content-Length", ""+info_size);

4 ZuulFilter 修改请求头

1 对 含有token头的request 进行拦截

2 springsecurity 负责将 sessionid 放在 request 的attribute中

3 filter 负责修改请求头,将session 加到向微服务的请求head中

package com.crazymaker.springcloud.cloud.center.zuul.config;

import com.crazymaker.springcloud.common.constants.SessionConstants;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
@Slf4j
public class ModifyRequestHeaderFilter extends ZuulFilter {

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String uri = request.getRequestURI();
        /**
         * 根据条件去判断是否需要路由,是否需要执行该过滤器
         */
        String token = request.getHeader(SessionConstants.AUTHORIZATION);
        log.info("token=" + token);
        if (!StringUtils.isEmpty(token) ) {
            return true;
        }
        return false;
    }

    /**
     * 修改请求头
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        String sessionSeed = (String) request.getAttribute(SessionConstants.SESSION_SEED);
        log.info("sessionSeed=" + sessionSeed);

        ctx.addZuulRequestHeader(SessionConstants.SESSION_SEED,sessionSeed);

//        response.addHeader(SessionConstants.SESSION_SEED, sessionId);
        return null;

    }

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 1;
    }

}

5 token到 sessionid

由 springsecurity 负责token的验证,然后从token提取 sessionid,并且 放在 request 的attribute中。

具体,请关注 Java 高并发研习社群博客园 总入口


最后,介绍一下疯狂创客圈:疯狂创客圈,一个Java 高并发研习社群博客园 总入口

疯狂创客圈,倾力推出:面试必备 + 面试必备 + 面试必备 的基础原理+实战 书籍 《Netty Zookeeper Redis 高并发实战

img


疯狂创客圈 Java 死磕系列

  • Java (Netty) 聊天程序【 亿级流量】实战 开源项目实战

疯狂创客圈 Java 死磕系列

  • Java (Netty) 聊天程序【 亿级流量】实战 开源项目实战

原文地址:https://www.cnblogs.com/crazymakercircle/p/12037587.html