1.添加依赖
剩下的依赖自行添加...
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2.创建配置文件
这里我使用了Nacos,使用时需要添加Nacos依赖 及配置gateway路由配置
server:
port: 8080
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
gateway:
discovery:
locator:
enabled: true
routes:
- id: testservice
uri: lb://testservice
predicates:
- Path=/test/**
filters:
- RequestSign
3.过滤器
直接看代码
import com.alibaba.fastjson.JSONObject;
import com.example.itvcommoncore.commonUtils.AESCoder;
import io.netty.buffer.ByteBufAllocator;
import org.springframework.core.io.buffer.NettyDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@Component
public class RequestSignGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
private static final Logger log = LoggerFactory.getLogger(RequestSignGatewayFilterFactory.class);
@Override
public GatewayFilter apply(Object config) {
return new RequestSignGatewayFilter();
}
public class RequestSignGatewayFilter implements GatewayFilter, Ordered {
@SneakyThrows
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String decryptedParam ="";
if( exchange.getRequest().getMethod().matches(String.valueOf(HttpMethod.GET))){
MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
log.warn("request GET param :{}", queryParams.toString());
decryptedParam=queryParams.getFirst("REQUEST");
String decryptedValue = decrypt(decryptedParam);
// 编码参数值
String encodedDecryptedParam = URLEncoder.encode(decryptedValue, StandardCharsets.UTF_8);
// 构建修改后的URI
URI modifiedUri = UriComponentsBuilder.fromUri(exchange.getRequest().getURI())
.replaceQueryParam("REQUEST", encodedDecryptedParam)
.build(true)
.toUri();
// 修改请求,设置新的URI
ServerHttpRequest modifiedRequest = exchange.getRequest().mutate()
.uri(modifiedUri)
.build();
// 用修改后的请求继续处理请求链
return chain.filter(exchange.mutate().request(modifiedRequest).build());
}else {
//获取请求体数据
AtomicReference<String> requestBody = new AtomicReference<>("");
RecorderServerHttpRequestDecorator requestDecorator = new RecorderServerHttpRequestDecorator(request);
Flux<DataBuffer> body = requestDecorator.getBody();
body.subscribe(buffer -> {
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(buffer.asByteBuffer());
requestBody.set(charBuffer.toString());
});
//我这里是用request=参数 格式
String decode = URLDecoder.decode(requestBody.get());
String param = decode.replace("REQUEST=", "");
log.warn("request POST param :{}",decode);
decryptedParam=param;
//解密的方法
String decryptedValue = decrypt(decryptedParam);
//编码参数值
String encodedDecryptedParam = URLEncoder.encode(decryptedValue, StandardCharsets.UTF_8);
//拼接新的请求体
String str="REQUEST="+encodedDecryptedParam;
DataBuffer bodyDataBuffer = stringBuffer(str);
//添加到请求体
Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);
MediaType contentType = request.getHeaders().getContentType();
ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
exchange.getRequest()) {
@Override
public HttpHeaders getHeaders() {
//重新设置请求头
HttpHeaders httpHeaders = new HttpHeaders();
int length = str.getBytes().length;
httpHeaders.putAll(super.getHeaders());
httpHeaders.remove(HttpHeaders.CONTENT_TYPE);
httpHeaders.remove(HttpHeaders.CONTENT_LENGTH);
httpHeaders.setContentLength(length);
httpHeaders.set(HttpHeaders.CONTENT_TYPE, contentType.toString());
// 设置CONTENT_TYPE
return httpHeaders;
}
@Override
public Flux<DataBuffer> getBody() {
return bodyFlux;
}
};
return chain.filter(exchange.mutate().request(mutatedRequest).build());
}
}
@Override
public int getOrder() {
return 2;
}
}
/**
* 转换参数的方法
* @param value
* @return
*/
protected DataBuffer stringBuffer(String value) {
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes);
return buffer;
}
/**
* 解密方法
* @param encryptedParam
* @return
*/
private String decrypt(String encryptedParam) {
String returnResult = "";
JSONObject json = JSONObject.parseObject(encryptedParam);
//我的参数在data里
String encrypt = json.getString("data");
try {
//解密
returnResult = AESCoder.decryptAES(encrypt, "test");
return returnResult;
} catch (Exception e) {
e.printStackTrace();
}
return returnResult;
}
public class RecorderServerHttpRequestDecorator extends ServerHttpRequestDecorator {
private final List<DataBuffer> dataBuffers = new ArrayList<>();
public RecorderServerHttpRequestDecorator(ServerHttpRequest delegate) {
super(delegate);
super.getBody().map(dataBuffer -> {
dataBuffers.add(dataBuffer);
return dataBuffer;
}).subscribe();
}
@Override
public Flux<DataBuffer> getBody() {
return copy();
}
private Flux<DataBuffer> copy() {
return Flux.fromIterable(dataBuffers)
.map(buf -> buf.factory().wrap(buf.asByteBuffer()));
}
}
}
4.接口层
这里要新建一个testservice服务,在testservice工程里写这个接口
@RestController
public class Test{
@GetMapping("hello") //这里根据需要更换get、post请求
public String test(@RequestParam("REQUEST")String result){
System.out.println(result);
return result;
}
}
配置文件:
spring:
application:
name: testservice
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
group: test
prefix: test
server:
servlet:
context-path: /test
5. 测试
我这里是编写了一个测试类
public static void main(String[] args) throws Exception {
try {
JSONObject jo = new JSONObject();
jo.put("param1", "测试啊");
jo.put("param2", "1");
JSONObject reqjo = new JSONObject();
String params = "";
//加密请求参数
encrypt = AESCoder.encrypt(jo.toString(), "test");
reqjo.put("data", params );
String responseBody = "";
// 请求参数
String sendparam= "REQUEST="
+ URLEncoder.encode(reqjo.toString(), "UTF-8");
String localUrl="htp://localhost:8081/test/hello"
HttpClientCommon hc = new HttpClientCommon();
responseBody = hc.responseBody(localUrl + "?" + sendparam, sendparam);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(responseBody);
JSONObject json = JSONObject.fromObject(responseBody);
String res = (String) json.get("RESPONSE=");
res = URLDecoder.decode(res, "UTF-8");
byte[] bytes = AESCoder.decrypt(res, "test");
String returnResult = new String(bytes, "UTF-8");
System.out.println("返回参数:" + returnResult);
}