栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

网关中配置过滤器

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

网关中配置过滤器

学习目标: 1.网关中配置过滤器实例
2.网关中配置过滤器原理
3.资料学习

学习内容: 1.实例中各部分方法的实际意义
2.原理来源于那些基础知识
3.java8新知识学习

学习产出: 1 网关中配置过滤器实例

1.1网关中配置过滤器java代码实现

import com.alibaba.fastjson.JSON;
import com.heima.admin.utils.AppJwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Component
@Slf4j
@Order(0)  // 越小越优先执行
//GlobalFilter处理链接web请求
public class AuthorizeFilter implements GlobalFilter {

    List urlList = Arrays.asList(
            "/v2/api-docs",
            "/login/in"
    );

    
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //1 判断用户是否登录
        //2 是登陆则放行
//        if (url.contains("/login/in")) {
//            return chain.filter(exchange);
//        }
        String url = request.getURI().getPath();
        for (String urls : urlList){
            //测试此字符串是否以指定的后缀结尾
            if (url.endsWith(urls)) {
                //调用网关过滤器
                return chain.filter(exchange);//放行
            }
        }

        //3 从 head 获取token
        String token = request.getHeaders().getFirst("token");
        //3.1 无 token 返回提示信息和401 拦截
        if (StringUtils.isBlank(token)) {
            //如果不存在,向客户端返回错误提示信息
            Map resultMap = new HashMap<>();
            resultMap.put("host", request.getRemoteAddress().getHostName());
            resultMap.put("code", HttpStatus.UNAUTHORIZED.value());
            resultMap.put("errorMessage", "需要登录");

            return writeMessage(exchange, resultMap);
        }

        try {
            //3.2 有 token 校验token合法性, 无效则返回提示信息和401
            //获取payload body信息
            Claims claims = AppJwtUtil.getClaimsBody(token);
            //-1 0 -》有效     1 2  -》 无效
            //是否过期
            int verifyToken = AppJwtUtil.verifyToken(claims);
            if (verifyToken > 0) {  // 无效  拦截
                Map resultMap = new HashMap<>();
                resultMap.put("host", request.getRemoteAddress().getHostName());
                resultMap.put("code", HttpStatus.UNAUTHORIZED.value());
                resultMap.put("errorMessage", "登录已过期,请重新登录");

                return writeMessage(exchange, resultMap);
            }


            //4 有效:解析jwt令牌,获取的用户id  body信息就是token json形式信息
            Integer id = claims.get("id", Integer.class);

            //5 把用户的id 转发到各个微服务中
            //mutate变异,创建出ServerHttpRequest建设者-->建设者操纵请求头(加入userId)-->建设完成【这个和pojos类里面的建设者模式一样】
            ServerHttpRequest serverHttpRequest = request.mutate().headers(httpHeaders -> {
                httpHeaders.add("userId", String.valueOf(id));
            }).build();
            //服务交换给各个wei服务
            exchange.mutate().request(serverHttpRequest);

        } catch (Exception e) {
           // e.printStackTrace();
            // 记录日志
            log.error("jwt verifyToken is fail,url:{}", url);
            Map resultMap = new HashMap<>();
            resultMap.put("host", request.getRemoteAddress().getHostName());
            resultMap.put("code", HttpStatus.UNAUTHORIZED.value());
            resultMap.put("errorMessage", "登录失败,请重新登录");

            return writeMessage(exchange, resultMap);
        }

        //6 放行
        return chain.filter(exchange);
    }

    
    private Mono writeMessage(ServerWebExchange exchange, Map resultMap) {
        //获取响应对象
        ServerHttpResponse response = exchange.getResponse();
        //设置状态码
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //response.setStatusCode(HttpStatus.OK);
        //设置返回类型 json
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        //设置返回数据
        DataBuffer buffer = response.bufferFactory().wrap(JSON.toJSONBytes(resultMap));
        //响应数据回浏览器
        return response.writeWith(Flux.just(buffer));
    }
}

1.2网关中配置过滤器yml文件

server:
  port: 6001
spring:
  application:
    name: 模块名字

  cloud:
    nacos:
      discovery:
        server-addr: 192.168.200.129:8848
    gateway:
      globalcors:
        cors-configurations:
          '[
    public static String getToken(Long id) {
        Map claimMaps = new HashMap<>();
        claimMaps.put("id", id);
        long currentTime = System.currentTimeMillis();

        return Jwts.builder().setId(UUID.randomUUID().toString())
                .setIssuedAt(new Date(currentTime))  //签发时间
                .setSubject("system")  //说明
                .setIssuer("heima") //签发者信息
                .setAudience("app")  //接收用户
                .compressWith(CompressionCodecs.GZIP)  //数据压缩方式
                .signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000))  //过期时间戳
                .addClaims(claimMaps) //cla信息 自定义信息
                .compact();
    }

    
    private static Jws getJws(String token) {
        return Jwts.parser().setSigningKey(generalKey()).parseClaimsJws(token);
    }

    
    public static Claims getClaimsBody(String token) {
        try {
            return getJws(token).getBody();
        } catch (ExpiredJwtException e) {
            return null;
        }
    }

    
    public static JwsHeader getHeaderBody(String token) {
        return getJws(token).getHeader();
    }

    
    public static int verifyToken(Claims claims) {
        if (claims == null) {
            return 1;
        }
        try {
            claims.getExpiration().before(new Date());
            // 需要自动刷新TOKEN
            if ((claims.getExpiration().getTime() - System.currentTimeMillis()) > REFRESH_TIME * 1000) {
                return -1;
            } else {
                return 0;
            }
        } catch (ExpiredJwtException ex) {
            return 1;
        } catch (Exception e) {
            return 2;
        }
    }

    
    public static SecretKey generalKey() {
        byte[] encodedKey = base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    public static void main(String[] args) {
       
        System.out.println(AppJwtUtil.getToken(1102L));
        Jws jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");
        Claims claims = jws.getBody();
        System.out.println(claims.get("id"));

    }

}

2 网关中配置过滤器原理

2.1 GlobalFilter


package org.springframework.cloud.gateway.filter;

import reactor.core.publisher.Mono;

import org.springframework.web.server.ServerWebExchange;



//GlobalFilter处理链接web请求的方法
public interface GlobalFilter {

	
	Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);

}

2.2 GatewayFilterChain网关过滤器链


2.3 网关过滤器∧ λ /'læmdə/ lambda 兰姆达 表达式

2.4 设计模式之建设者模式
https://blog.csdn.net/u010342008/article/details/45565531
2.5 Spring Cloud Gateway网关原理
https://www.cnblogs.com/lucky-yqy/p/13965296.html
2.6 lambda各种用法
由匿名内部类而来,中间存在不完全简写体,最简体。

import org.junit.Test;
import java.util.Comparator;
import java.util.function.Consumer;

public class LambdaDemo {

    
    
    @Test
    public void test1() {
        //匿名内部类
        Runnable r1 = new Runnable() {
            public void run() {
                
                System.out.println("我爱北京天安门你");
            }
        };
        r1.run();

        //lambda表达式
        Runnable r2 = () -> System.out.println("我爱北京天安门你");
        r2.run();

    }

    
    @Test
    public void Test2() {
        Comparator com1 = new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {

                return Integer.compare(o1, o2);
            }
        };
        System.out.println(com1.compare(15, 16));

        //lambda表达式
        Comparator com2 = (o1, o2) -> Integer.compare(o1, o2);
        System.out.println(com2.compare(17, 16));

        //方法引用
        Comparator com3 = Integer::compare;
        System.out.println(com3.compare(18, 16));
    }

    
    @Test
    public void Test3() {
        Consumer con = new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("谎言和誓言的区别是什么?");

        //lambda
        //Consumer con2 =(s )-> {System.out.println(s);};
        //Consumer con2 =s -> {System.out.println(s);};
        Consumer con2 = s -> System.out.println(s);
        con2.accept("谎言和誓言的区别是什么?");
    }

    
    @Test
    public void Test4() {
        Comparator com = new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                System.out.println(o1);
                System.out.println(o2);
                return Integer.compare(o1, o2);
            }
        };
        System.out.println(com.compare(13, 4));

        //
        Comparator com2 = (o1, o2) -> {
            System.out.println(o1);
            System.out.println(o2);
            return Integer.compare(o1, o2);
        };
        System.out.println(com2.compare(23, 7));
    }

    
    @Test
    public void Test5(){
        Comparator com =new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        };
        System.out.println(com.compare(13,4));

        //类型不同不可省略类型
        Comparator com2=(o1,o2) ->  o1.compareTo(o2);
        System.out.println(com2.compare(13,4));
    }
}

2.7 Optional操作

import org.junit.Test;

import java.math.BigDecimal;
import java.util.Optional;

public class OptionalDemo {

    @Test
    public void test1() {
        PaymentChange paymentChange = new PaymentChange();
        BigDecimal bigAbmout = Optional.ofNullable(paymentChange.getPaymentChangeMoney()).orElseGet(() -> BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    @Test
    public void test2() {
        PaymentChange paymentChange = new PaymentChange();
        BigDecimal bigAbmout = Optional.ofNullable(paymentChange.getPaymentChangeMoney()).orElse(BigDecimal.ZERO);
    }
}

import java.math.BigDecimal;

public class PaymentChange {
    public BigDecimal  getPaymentChangeMoney() {
        return new BigDecimal("222222222222222222222222222222222");
    }
}

2.8 stream流式操作

import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

public class StreamDemo {

    //传统for循环
    //迭代器
    //增强for循环
    //流式
    @Test
    public void test1() {

        //类型转换1
        List studentList = new ArrayList<>();
        List studentNos = new ArrayList();
        for (Student student : studentList) {
            studentNos.add(student.getStudentNo());
        }

        //Stream
        List studentNos2 = studentList.stream().map(Student::getStudentNo).collect(Collectors.toList());
    }

    @Test
    public void test2() {

        //类型转换2
        List studentList = new ArrayList<>();
        for (Student student : studentList) {
            if ("0001".equals(student.getStudentNo())) {
                System.out.println(student.getName());
            }
        }

        //Stream
        Map collect = studentList.stream()
                .collect(Collectors.toMap(Student::getStudentNo, Student::getName));
        System.out.println(collect.get("0001"));
    }

    @Test
    public void test3() {

        //过滤
        List studentList = new ArrayList<>();
        List manList = new ArrayList();
        for (Student student : studentList) {
            if (student.getSex().equals(1)) {
                manList.add(student);
            }
        }

        //Stream+Lambda
        List manList2 = studentList.stream()
                .filter(s -> s.getSex()
                        .equals(1)).collect(Collectors.toList());
    }

    @Test
    public void test4() {

        //排序
        List studentList = new ArrayList<>();
        List manList = new ArrayList();

        for (Student student : studentList) {
            if (student.getAge() > studentList.get(0).getAge()) {
                manList.add(student);
            }
        }

        //Stream+Lambda
        studentList.stream().
                sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());
    }

    @Test
    public void test5() {

        //去重
        List studentList = new ArrayList<>();
        List collect2 = studentList.stream().distinct().collect(Collectors.toList());

        //也可以根据某一属性去重
        studentList.stream()
                .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet(Comparator.comparingLong(Student::getAge))), ArrayList::new));
    }

    @Test
    public void test6() {

        //快速找到集合中想要匹配的数据
        List studentList = new ArrayList<>();
        //是否存在学号为0001的人
        boolean match = studentList.stream().anyMatch(detail -> "0001".equals(detail.getStudentNo()));


    }

    @Test
    public void test7() {
        List studentList = new ArrayList<>();
        //跳过前面n个元素
        List skipList = studentList.stream().skip(2).collect(Collectors.toList());
        //取前n个元素
        List limitList = studentList.stream().limit(2).collect(Collectors.toList());

    }

    
    @Test
    public void test8() {
        List list = new ArrayList<>();

        list.stream().collect(Collectors.toList());
        //把流中元素收集到List

        list.stream().collect(Collectors.toSet());
        //把流中元素收集到Set

        list.stream().collect(Collectors.toCollection(ArrayList::new));
        //把流中元素收集到创建的集合

        list.stream().collect(Collectors.counting());
        //计算流中元素的个数

        list.stream().collect(Collectors.summingInt(Student::getAge));
        //对流中元素的整数属性求和

        list.stream().collect(Collectors.averagingInt(Student::getAge));
        //计算流中元素Integer属性的平均值

        list.stream().collect(Collectors.summarizingInt(Student::getAge));
        //收集流中Integer属性的统计值。如:平均值

        list.stream().collect(Collectors.groupingBy(Student::getAge));
        //根据某属性值对流分组,属性为K,结果为V
        //最大值maxBy和最小值 minBy
    }
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    String name;
    String studentNo;
    String sex;
    Integer age;

}

3 java8新知识学习

3.1 Java Lambda 表达式
https://www.runoob.com/java/java8-lambda-expressions.html
3.2 Java optional 操作
https://www.runoob.com/java/java8-optional-class.html
https://www.cnblogs.com/zhangboyu/p/7580262.html
3.3 Java streams操作
https://www.runoob.com/java/java8-streams.html

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/349285.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号