From 862d47d76ffa207de0193f0ad0831fb776125c75 Mon Sep 17 00:00:00 2001 From: Jesse-Ma <24167796@qq.com> Date: Thu, 1 Dec 2022 16:33:26 +0800 Subject: [PATCH] gateway --- pom.xml | 2 +- .../flagnote/gateway/config/GwCorsFilter.java | 38 ++++++ .../gateway/filter/ValidateNoteKeyFilter.java | 10 +- .../com/flagnote/gateway/utils/JsonUtils.java | 112 ++++++++++++++++++ .../com/flagnote/gateway/utils/NoteMeta.java | 30 +++++ src/main/resources/application.yml | 26 ++-- 6 files changed, 200 insertions(+), 18 deletions(-) create mode 100644 src/main/java/com/flagnote/gateway/config/GwCorsFilter.java create mode 100644 src/main/java/com/flagnote/gateway/utils/JsonUtils.java create mode 100644 src/main/java/com/flagnote/gateway/utils/NoteMeta.java diff --git a/pom.xml b/pom.xml index 53e54fe..f360b36 100644 --- a/pom.xml +++ b/pom.xml @@ -78,4 +78,4 @@ - + \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/config/GwCorsFilter.java b/src/main/java/com/flagnote/gateway/config/GwCorsFilter.java new file mode 100644 index 0000000..c744e44 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/config/GwCorsFilter.java @@ -0,0 +1,38 @@ +package com.flagnote.gateway.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.reactive.CorsWebFilter; +import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; +import org.springframework.web.util.pattern.PathPatternParser; + +//@Configuration +public class GwCorsFilter { + +// @Bean + public CorsWebFilter corsFilter() { + CorsConfiguration config = new CorsConfiguration(); + config.addAllowedMethod("*"); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + + config.setAllowCredentials(true); // 允许cookies跨域 + config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin + config.addAllowedHeader("*");// #允许访问的头信息,*表示全部 + config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了 + config.addAllowedMethod("OPTIONS");// 允许提交请求的方法类型,*表示全部允许 + config.addAllowedMethod("HEAD"); + config.addAllowedMethod("GET"); + config.addAllowedMethod("PUT"); + config.addAllowedMethod("POST"); + config.addAllowedMethod("DELETE"); + config.addAllowedMethod("PATCH"); + + UrlBasedCorsConfigurationSource source = + new UrlBasedCorsConfigurationSource(new PathPatternParser()); + source.registerCorsConfiguration("/**", config); + + return new CorsWebFilter(source); + } +} \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/filter/ValidateNoteKeyFilter.java b/src/main/java/com/flagnote/gateway/filter/ValidateNoteKeyFilter.java index f47762b..65abcfc 100644 --- a/src/main/java/com/flagnote/gateway/filter/ValidateNoteKeyFilter.java +++ b/src/main/java/com/flagnote/gateway/filter/ValidateNoteKeyFilter.java @@ -1,17 +1,22 @@ package com.flagnote.gateway.filter; +import java.nio.charset.StandardCharsets; import java.util.Map; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.support.ServerWebExchangeUtils; import org.springframework.core.Ordered; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import com.flagnote.gateway.utils.BizKeyUtils; +import com.flagnote.gateway.utils.JsonUtils; +import com.flagnote.gateway.utils.NoteMeta; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; /** @@ -27,8 +32,9 @@ public class ValidateNoteKeyFilter implements GatewayFilter, Ordered { String noteKey = uriVariables.get("key"); if (!BizKeyUtils.validateKey(noteKey)) { - exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST); - return exchange.getResponse().setComplete(); + NoteMeta meta = new NoteMeta(); + DataBuffer dataBuffer = exchange.getResponse().bufferFactory().wrap(JsonUtils.toJson(meta).getBytes(StandardCharsets.UTF_8)); + return exchange.getResponse().writeWith(Flux.just(dataBuffer)); } return chain.filter(exchange); diff --git a/src/main/java/com/flagnote/gateway/utils/JsonUtils.java b/src/main/java/com/flagnote/gateway/utils/JsonUtils.java new file mode 100644 index 0000000..d2530b3 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/utils/JsonUtils.java @@ -0,0 +1,112 @@ +package com.flagnote.gateway.utils; + +import java.io.IOException; +import java.text.SimpleDateFormat; + +import org.springframework.util.StringUtils; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class JsonUtils { + + private static ObjectMapper om = new ObjectMapper(); + + static { + + // 对象的所有字段全部列入,还是其他的选项,可以忽略null等 + om.setSerializationInclusion(Include.ALWAYS); + // 设置Date类型的序列化及反序列化格式 + om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); + + // 忽略空Bean转json的错误 + om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); + // 忽略未知属性,防止json字符串中存在,java对象中不存在对应属性的情况出现错误 + om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + // 注册一个时间序列化及反序列化的处理模块,用于解决jdk8中localDateTime等的序列化问题 + om.registerModule(new JavaTimeModule()); + } + + /** + * 对象 => json字符串 + * + * @param obj 源对象 + */ + public static String toJson(T obj) { + + String json = null; + if (obj != null) { + try { + json = om.writeValueAsString(obj); + } catch (JsonProcessingException e) { + log.warn(e.getMessage(), e); + throw new IllegalArgumentException(e.getMessage()); + } + } + return json; + } + + /** + * json字符串 => 对象 + * + * @param json 源json串 + * @param clazz 对象类 + * @param 泛型 + */ + public static T parse(String json, Class clazz) { + + return parse(json, clazz, null); + } + + /** + * json字符串 => 对象 + * + * @param json 源json串 + * @param type 对象类型 + * @param 泛型 + */ + public static T parse(String json, TypeReference type) { + + return parse(json, null, type); + } + + + /** + * json => 对象处理方法 + *
+ * 参数clazz和type必须一个为null,另一个不为null + *
+ * 此方法不对外暴露,访问权限为private + * + * @param json 源json串 + * @param clazz 对象类 + * @param type 对象类型 + * @param 泛型 + */ + private static T parse(String json, Class clazz, TypeReference type) { + + T obj = null; + if (StringUtils.hasLength(json)) { + try { + if (clazz != null) { + obj = om.readValue(json, clazz); + } else { + obj = om.readValue(json, type); + } + } catch (IOException e) { + log.warn(e.getMessage(), e); + throw new IllegalArgumentException(e.getMessage()); + } + } + return obj; + } +} \ No newline at end of file diff --git a/src/main/java/com/flagnote/gateway/utils/NoteMeta.java b/src/main/java/com/flagnote/gateway/utils/NoteMeta.java new file mode 100644 index 0000000..0d08a47 --- /dev/null +++ b/src/main/java/com/flagnote/gateway/utils/NoteMeta.java @@ -0,0 +1,30 @@ +package com.flagnote.gateway.utils; + +import java.io.Serializable; + +import lombok.Data; + +@Data +public class NoteMeta implements Serializable {/** + * + */ + private static final long serialVersionUID = -8234044213813670440L; + +/** + * + */ + + private String key; + + private Integer state; + + private String cipher; + + private Integer lock; + + private String md5; + + private Long serverTime; + + private Long ttl; +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 54e975a..704d28d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -10,8 +10,8 @@ spring: # 最大支持请求大小 max-request-size: 100MB redis: - host: cq.openif.com - port: 6379 + host: service.flagnote.com + port: 36379 timeout: 1000 poolMaxTotal: 10 poolMaxIdle: 10 @@ -39,11 +39,11 @@ spring: # 指定此客户端的ip default-ip-address: localhost gateway: - globalcors: - corsConfigurations: - '[/**]': - allowedOrigins: "*" - allowedMethods: "*" +# globalcors: +# corsConfigurations: +# '[/**]': +# allowedOrigins: "*" +# allowedMethods: "*" routes: - id: keyMeta uri: lb://keyMetaService @@ -60,7 +60,7 @@ spring: # 每秒产生多少个令牌 redis-rate-limiter.replenishRate: 1 # 1秒内最大的令牌,即在1s内可以允许的突发流程,设置为0,表示阻止所有的请求 - redis-rate-limiter.burstCapacity: 1 + redis-rate-limiter.burstCapacity: 10 # 每次请求申请几个令牌 redis-rate-limiter.requestedTokens: 1 # IP 地址限流 @@ -75,9 +75,9 @@ spring: # 每秒产生多少个令牌 redis-rate-limiter.replenishRate: 1 # 1秒内最大的令牌,即在1s内可以允许的突发流程,设置为0,表示阻止所有的请求 - redis-rate-limiter.burstCapacity: 3 + redis-rate-limiter.burstCapacity: 10 # 每次请求申请几个令牌 - redis-rate-limiter.requestedTokens: 3 + redis-rate-limiter.requestedTokens: 2 # IP 地址限流 key-resolver: "#{@remoteSessionKeyResolver}" @@ -106,11 +106,7 @@ spring: - Path=/note/{key:[abcdefhikmnopqstuvwxyz23456789]{16}} - Method=POST filters: - - name: ValidateNoteKey - - name: CacheRequestBody - args: - bodyClass: java.lang.String - - name: ValidateNoteCipher + - ValidateNoteKey - id: deleteNote uri: lb://keyMetaService order: -1