gitway 添加依赖
This commit is contained in:
parent
8309b6d8ce
commit
4685991a2b
@ -49,7 +49,17 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.83</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
package com.qiuguo.iot.gateway.config;
|
||||
|
||||
import com.qiuguo.iot.gateway.config.properties.CorsProperties;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
|
||||
/**
|
||||
* 全局跨域配置.
|
||||
*
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(CorsProperties.class)
|
||||
public class GlobalCorsConfiguration {
|
||||
|
||||
/**
|
||||
* 允许跨域调用的过滤器.
|
||||
*
|
||||
* @param corsProperties 跨域配置
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(CorsFilter.class)
|
||||
public CorsFilter corsFilter(CorsProperties corsProperties) {
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
// 设置允许跨域访问的域名
|
||||
config.setAllowedOriginPatterns(corsProperties.getAllowedOriginPatterns());
|
||||
// 设置允许跨域访问的方法
|
||||
config.setAllowedMethods(corsProperties.getAllowedMethods());
|
||||
// 设置允许跨域访问的请求头
|
||||
config.setAllowedHeaders(corsProperties.getAllowedHeaders());
|
||||
config.setExposedHeaders(corsProperties.getExposedHeaders());
|
||||
// 允许跨越发送cookie
|
||||
config.setAllowCredentials(corsProperties.getAllowCredentials());
|
||||
config.setMaxAge(corsProperties.getMaxAge());
|
||||
|
||||
// 对接口配置跨域设置
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
return new CorsFilter(source);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package com.qiuguo.iot.gateway.config.properties;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* 跨域配置.
|
||||
*
|
||||
* @author yangning
|
||||
* @since 2022/11/7 14:45
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@ConfigurationProperties(prefix = "application.cors")
|
||||
public class CorsProperties {
|
||||
|
||||
/**
|
||||
* 允许跨域访问的域名.
|
||||
*/
|
||||
private List<String> allowedOriginPatterns;
|
||||
|
||||
/**
|
||||
* 允许跨域访问的方法.
|
||||
*/
|
||||
private List<String> allowedMethods;
|
||||
|
||||
/**
|
||||
* 允许跨域访问的请求头.
|
||||
*/
|
||||
private List<String> allowedHeaders;
|
||||
|
||||
/**
|
||||
* 暴露的响应头.
|
||||
*/
|
||||
private List<String> exposedHeaders;
|
||||
|
||||
/**
|
||||
* 是否允许跨域发送cookie.
|
||||
*/
|
||||
private Boolean allowCredentials = true;
|
||||
|
||||
/**
|
||||
* 跨域访问有效期.
|
||||
*/
|
||||
private Long maxAge = 1800L;
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.qiuguo.iot.gateway.config.properties;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Xss配置.
|
||||
*
|
||||
* @author yangning
|
||||
* @since 2023/4/7 18:31
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(prefix = "security.xss")
|
||||
public class XssProperties {
|
||||
|
||||
/**
|
||||
* Xss开关.
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* 排除路径.
|
||||
*/
|
||||
private List<String> excludeUrls = new ArrayList<>();
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.qiuguo.iot.gateway.filter;
|
||||
|
||||
import com.qiuguo.iot.gateway.util.WebFluxUtils;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 全局缓存获取body请求数据(解决流不能重复读取问题).
|
||||
*
|
||||
* @author yangning
|
||||
* @since 2022/12/14 16:07
|
||||
*/
|
||||
@Component
|
||||
public class GlobalCacheRequestFilter implements GlobalFilter, Ordered {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
// 只缓存json类型请求
|
||||
// if (!WebFluxUtils.isJsonRequest(exchange)) {
|
||||
// return chain.filter(exchange);
|
||||
// }
|
||||
return ServerWebExchangeUtils.cacheRequestBody(exchange, (serverHttpRequest) -> {
|
||||
if (serverHttpRequest == exchange.getRequest()) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
return chain.filter(exchange.mutate().request(serverHttpRequest).build());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
package com.qiuguo.iot.gateway.handler;
|
||||
|
||||
import com.qiuguo.iot.gateway.util.WebFluxUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
|
||||
import org.springframework.cloud.gateway.support.NotFoundException;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 网关统一异常处理.
|
||||
*
|
||||
*/
|
||||
@Slf4j
|
||||
@Order(-1)
|
||||
@Configuration
|
||||
public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
|
||||
|
||||
@Override
|
||||
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
|
||||
final ServerHttpResponse response = exchange.getResponse();
|
||||
|
||||
if (exchange.getResponse().isCommitted()) {
|
||||
return Mono.error(ex);
|
||||
}
|
||||
|
||||
String msg;
|
||||
|
||||
if (ex instanceof NotFoundException) {
|
||||
msg = "服务未找到";
|
||||
} else if (ex instanceof ResponseStatusException) {
|
||||
ResponseStatusException responseStatusException = (ResponseStatusException) ex;
|
||||
msg = responseStatusException.getMessage();
|
||||
} else {
|
||||
msg = "内部服务器错误";
|
||||
}
|
||||
|
||||
log.error("[网关异常处理]请求路径:{},异常信息:{}", exchange.getRequest().getPath(), ex.getMessage());
|
||||
|
||||
return WebFluxUtils.webFluxResponseWriter(response, msg);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
package com.qiuguo.iot.gateway.util;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import java.util.HashMap;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* WebFlux 工具类.
|
||||
*/
|
||||
public class WebFluxUtils {
|
||||
|
||||
/**
|
||||
* 是否是Json请求.
|
||||
*
|
||||
* @param exchange HTTP请求
|
||||
*/
|
||||
public static boolean isJsonRequest(ServerWebExchange exchange) {
|
||||
String header = exchange.getRequest().getHeaders().getFirst(HttpHeaders.CONTENT_TYPE);
|
||||
return StringUtils.startsWithIgnoreCase(header, MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置webflux模型响应.
|
||||
*
|
||||
* @param response ServerHttpResponse
|
||||
* @param value 响应内容
|
||||
* @return Mono
|
||||
*/
|
||||
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value) {
|
||||
return webFluxResponseWriter(response, HttpStatus.OK, value, HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置webflux模型响应.
|
||||
*
|
||||
* @param response ServerHttpResponse
|
||||
* @param code 响应状态码
|
||||
* @param value 响应内容
|
||||
* @return Mono
|
||||
*/
|
||||
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code) {
|
||||
return webFluxResponseWriter(response, HttpStatus.OK, value, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置webflux模型响应.
|
||||
*
|
||||
* @param response ServerHttpResponse
|
||||
* @param status http状态码
|
||||
* @param code 响应状态码
|
||||
* @param value 响应内容
|
||||
* @return Mono
|
||||
*/
|
||||
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value,
|
||||
int code) {
|
||||
return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置webflux模型响应.
|
||||
*
|
||||
* @param response ServerHttpResponse
|
||||
* @param contentType content-type
|
||||
* @param status http状态码
|
||||
* @param code 响应状态码
|
||||
* @param value 响应内容
|
||||
* @return Mono
|
||||
*/
|
||||
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status,
|
||||
Object value, int code) {
|
||||
response.setStatusCode(status);
|
||||
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("message", value.toString());
|
||||
map.put("status", code);
|
||||
map.put("code", "error");
|
||||
map.put("timestamp", System.currentTimeMillis());
|
||||
DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(map).getBytes());
|
||||
return response.writeWith(Mono.just(dataBuffer));
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user