美文网首页Spring Boot
Spring Cloud Gateway重写请求

Spring Cloud Gateway重写请求

作者: EasyNetCN | 来源:发表于2024-06-13 10:00 被阅读0次

    在Spring Cloud中,有时候需要对前端直接调用的微服务,进行请求内容重组,这时候可以通过自定义org.springframework.cloud.gateway.filter.GlobalFilter,org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction,来满足需求。
    下面的例子,是前端通过Gateway调用后端的文件服务,获取上传OSS的一些必要信息。通过重组,可以简化和规范使用。

    自定义RewriteFunction

    
    import java.io.IOException;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    import org.apache.commons.lang3.StringUtils;
    import org.reactivestreams.Publisher;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeanUtils;
    import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
    import org.springframework.core.env.Environment;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    import reactor.core.publisher.Mono;
    
    @Component
    public class FileServiceRequestRewriteFunction implements RewriteFunction<byte[], byte[]> {
        private static final Logger logger = LoggerFactory.getLogger(FileServiceRequestRewriteFunction.class);
    
        private Environment environment;
        private ObjectMapper objectMapper;
        private FileServiceProperties fileServiceProperties;
    
        public FileServiceRequestRewriteFunction(Environment environment, ObjectMapper objectMapper,
                FileServiceProperties fileServiceProperties) {
            this.environment = environment;
            this.objectMapper = objectMapper;
            this.fileServiceProperties = fileServiceProperties;
        }
    
        @Override
        public Publisher<byte[]> apply(ServerWebExchange t, byte[] u) {
            UploadTokenRequest uploadTokenRequest = new UploadTokenRequest();
    
            try {
                uploadTokenRequest = objectMapper.readValue(u, UploadTokenRequest.class);
            } catch (IOException e) {
                logger.error("转换异常", e);
    
                return Mono.just(u);
            }
    
            var ossUploadFile = new OssUploadFile();
    
            BeanUtils.copyProperties(uploadTokenRequest, ossUploadFile);
    
            ossUploadFile.bucket = fileServiceProperties.getTypeBuckets().getOrDefault(uploadTokenRequest.getType(),
                    fileServiceProperties.getDefaultBucket());
    
            ossUploadFile.prefix = getPrefix(uploadTokenRequest.getType(), uploadTokenRequest.getPrefix());
    
            try {
                return Mono.just(objectMapper.writeValueAsBytes(ossUploadFile));
            } catch (JsonProcessingException e) {
                logger.error("转换异常", e);
    
                return Mono.just(u);
            }
        }
    
        private String getActiveProfile() {
            var profiles = environment.getActiveProfiles();
    
            return profiles.length > 0 ? profiles[0] : "";
        }
    
        private String getPrefix(String type, String prefix) {
            var activeProfile = getActiveProfile();
            var sb = new StringBuilder();
    
            if (StringUtils.isNotBlank(activeProfile) && !activeProfile.equalsIgnoreCase("prod")) {
                sb.append(activeProfile.toLowerCase());
            }
    
            if (StringUtils.isNotBlank(type)) {
                if (!sb.isEmpty()) {
                    sb.append("/");
                }
    
                sb.append(type.toLowerCase());
            }
    
            if (StringUtils.isNotBlank(prefix)) {
                if (!sb.isEmpty()) {
                    sb.append("/");
                }
    
                sb.append(prefix);
            } else {
                if (!sb.isEmpty()) {
                    sb.append("/");
                }
    
                sb.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")));
            }
    
            return sb.toString();
        }
    
        static class UploadTokenRequest {
            private String type;
            private String bucket;
            private String prefix;
            private String fileKey;
            private String sourceFile;
            private Long sourceFileSize;
            private String sourceFileType;
            private Integer useSourceFilename;
            private Long expiredInSec;
    
            public String getType() {
                return type;
            }
    
            public void setType(String type) {
                this.type = type;
            }
    
            public String getBucket() {
                return bucket;
            }
    
            public void setBucket(String bucket) {
                this.bucket = bucket;
            }
    
            public String getPrefix() {
                return prefix;
            }
    
            public void setPrefix(String prefix) {
                this.prefix = prefix;
            }
    
            public String getFileKey() {
                return fileKey;
            }
    
            public void setFileKey(String fileKey) {
                this.fileKey = fileKey;
            }
    
            public String getSourceFile() {
                return sourceFile;
            }
    
            public void setSourceFile(String sourceFile) {
                this.sourceFile = sourceFile;
            }
    
            public Long getSourceFileSize() {
                return sourceFileSize;
            }
    
            public void setSourceFileSize(Long sourceFileSize) {
                this.sourceFileSize = sourceFileSize;
            }
    
            public String getSourceFileType() {
                return sourceFileType;
            }
    
            public void setSourceFileType(String sourceFileType) {
                this.sourceFileType = sourceFileType;
            }
    
            public Integer getUseSourceFilename() {
                return useSourceFilename;
            }
    
            public void setUseSourceFilename(Integer useSourceFilename) {
                this.useSourceFilename = useSourceFilename;
            }
    
            public Long getExpiredInSec() {
                return expiredInSec;
            }
    
            public void setExpiredInSec(Long expiredInSec) {
                this.expiredInSec = expiredInSec;
            }
        }
    
        static class OssUploadFile {
            private String bucket;
            private String prefix;
            private String fileKey;
            private String sourceFile;
            private Long sourceFileSize;
            private String sourceFileType;
            private Integer useSourceFilename;
            private Long expiredInSec;
    
            public String getBucket() {
                return bucket;
            }
    
            public void setBucket(String bucket) {
                this.bucket = bucket;
            }
    
            public String getPrefix() {
                return prefix;
            }
    
            public void setPrefix(String prefix) {
                this.prefix = prefix;
            }
    
            public String getFileKey() {
                return fileKey;
            }
    
            public void setFileKey(String fileKey) {
                this.fileKey = fileKey;
            }
    
            public String getSourceFile() {
                return sourceFile;
            }
    
            public void setSourceFile(String sourceFile) {
                this.sourceFile = sourceFile;
            }
    
            public Long getSourceFileSize() {
                return sourceFileSize;
            }
    
            public void setSourceFileSize(Long sourceFileSize) {
                this.sourceFileSize = sourceFileSize;
            }
    
            public String getSourceFileType() {
                return sourceFileType;
            }
    
            public void setSourceFileType(String sourceFileType) {
                this.sourceFileType = sourceFileType;
            }
    
            public Integer getUseSourceFilename() {
                return useSourceFilename;
            }
    
            public void setUseSourceFilename(Integer useSourceFilename) {
                this.useSourceFilename = useSourceFilename;
            }
    
            public Long getExpiredInSec() {
                return expiredInSec;
            }
    
            public void setExpiredInSec(Long expiredInSec) {
                this.expiredInSec = expiredInSec;
            }
        }
    }
    

    自定义GlobalFilter

    
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory;
    import org.springframework.cloud.gateway.route.Route;
    import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    
    import reactor.core.publisher.Mono;
    
    /**
     * 文件服务全局过滤器
     */
    @Component
    public class FileServiceGatewayGlobalFilter implements GlobalFilter {
        private ModifyRequestBodyGatewayFilterFactory modifyRequestBodyGatewayFilterFactory;
        private FileServiceProperties fileServiceProperties;
        private FileServiceRequestRewriteFunction fileServiceRequestRewriteFunction;
    
        public FileServiceGatewayGlobalFilter(ModifyRequestBodyGatewayFilterFactory modifyRequestBodyGatewayFilterFactory,
                FileServiceProperties fileServiceProperties,
                FileServiceRequestRewriteFunction fileServiceRequestRewriteFunction) {
            this.modifyRequestBodyGatewayFilterFactory = modifyRequestBodyGatewayFilterFactory;
            this.fileServiceProperties = fileServiceProperties;
            this.fileServiceRequestRewriteFunction = fileServiceRequestRewriteFunction;
        }
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
    
            if (route != null && route.getUri() != null && route.getUri().getHost().equalsIgnoreCase("file-service")) {
    
                var requestPath = exchange.getRequest().getURI().getPath();
    
                if (requestPath.equalsIgnoreCase(fileServiceProperties.getUploadTokenPath())) {
                    return modifyRequestBodyGatewayFilterFactory.apply(new ModifyRequestBodyGatewayFilterFactory()
                            .newConfig().setRewriteFunction(byte[].class, byte[].class, fileServiceRequestRewriteFunction))
                            .filter(exchange, chain);
    
                }
            }
    
            return chain.filter(exchange);
        }
    
        static class UploadTokenRequest {
            private String type;
            private String bucket;
            private String prefix;
            private String fileKey;
            private String sourceFile;
            private Long sourceFileSize;
            private String sourceFileType;
            private Integer useSourceFilename;
            private Long expiredInSec;
    
            public String getType() {
                return type;
            }
    
            public void setType(String type) {
                this.type = type;
            }
    
            public String getBucket() {
                return bucket;
            }
    
            public void setBucket(String bucket) {
                this.bucket = bucket;
            }
    
            public String getPrefix() {
                return prefix;
            }
    
            public void setPrefix(String prefix) {
                this.prefix = prefix;
            }
    
            public String getFileKey() {
                return fileKey;
            }
    
            public void setFileKey(String fileKey) {
                this.fileKey = fileKey;
            }
    
            public String getSourceFile() {
                return sourceFile;
            }
    
            public void setSourceFile(String sourceFile) {
                this.sourceFile = sourceFile;
            }
    
            public Long getSourceFileSize() {
                return sourceFileSize;
            }
    
            public void setSourceFileSize(Long sourceFileSize) {
                this.sourceFileSize = sourceFileSize;
            }
    
            public String getSourceFileType() {
                return sourceFileType;
            }
    
            public void setSourceFileType(String sourceFileType) {
                this.sourceFileType = sourceFileType;
            }
    
            public Integer getUseSourceFilename() {
                return useSourceFilename;
            }
    
            public void setUseSourceFilename(Integer useSourceFilename) {
                this.useSourceFilename = useSourceFilename;
            }
    
            public Long getExpiredInSec() {
                return expiredInSec;
            }
    
            public void setExpiredInSec(Long expiredInSec) {
                this.expiredInSec = expiredInSec;
            }
        }
    
        static class OssUploadFile {
            private String bucket;
            private String prefix;
            private String fileKey;
            private String sourceFile;
            private Long sourceFileSize;
            private String sourceFileType;
            private Integer useSourceFilename;
            private Long expiredInSec;
    
            public String getBucket() {
                return bucket;
            }
    
            public void setBucket(String bucket) {
                this.bucket = bucket;
            }
    
            public String getPrefix() {
                return prefix;
            }
    
            public void setPrefix(String prefix) {
                this.prefix = prefix;
            }
    
            public String getFileKey() {
                return fileKey;
            }
    
            public void setFileKey(String fileKey) {
                this.fileKey = fileKey;
            }
    
            public String getSourceFile() {
                return sourceFile;
            }
    
            public void setSourceFile(String sourceFile) {
                this.sourceFile = sourceFile;
            }
    
            public Long getSourceFileSize() {
                return sourceFileSize;
            }
    
            public void setSourceFileSize(Long sourceFileSize) {
                this.sourceFileSize = sourceFileSize;
            }
    
            public String getSourceFileType() {
                return sourceFileType;
            }
    
            public void setSourceFileType(String sourceFileType) {
                this.sourceFileType = sourceFileType;
            }
    
            public Integer getUseSourceFilename() {
                return useSourceFilename;
            }
    
            public void setUseSourceFilename(Integer useSourceFilename) {
                this.useSourceFilename = useSourceFilename;
            }
    
            public Long getExpiredInSec() {
                return expiredInSec;
            }
    
            public void setExpiredInSec(Long expiredInSec) {
                this.expiredInSec = expiredInSec;
            }
        }
    }
    

    文件服务配置

    
    import java.util.Map;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties(prefix = "file-service", ignoreUnknownFields = true)
    public class FileServiceProperties {
        private String uploadTokenPath;
    
        private String defaultBucket;
    
        private Map<String, String> typeBuckets;
    
        public String getUploadTokenPath() {
            return uploadTokenPath;
        }
    
        public void setUploadTokenPath(String uploadTokenPath) {
            this.uploadTokenPath = uploadTokenPath;
        }
    
        public String getDefaultBucket() {
            return defaultBucket;
        }
    
        public void setDefaultBucket(String defaultBucket) {
            this.defaultBucket = defaultBucket;
        }
    
        public Map<String, String> getTypeBuckets() {
            return typeBuckets;
        }
    
        public void setTypeBuckets(Map<String, String> typeBuckets) {
            this.typeBuckets = typeBuckets;
        }
    }
    

    相关文章

      网友评论

        本文标题:Spring Cloud Gateway重写请求

        本文链接:https://www.haomeiwen.com/subject/wpanqjtx.html