1. gateway路由yml的坑
虽然最后证明真的只是一个filters写错了
(1)gateway路由问题的排除方法
eureka首先只要在8761界面上显示了就一定没问题;
要被访问的应用只要单独能访问就也一定没问题;
跳不过去一定是gateway的问题。
(2)示例图

首先每个- 后面都要有个空格
然后uri后面跟的服务名都是大写的,因为eureka里面都大写
filters一定要写,要把你的前缀给排除掉
(3) springboot和springcloud的坑
springboot和springcloud是有版本对应关系的,所以也可能是pom文件有问题。
swagger跳转那个,如果springboot版本低于2.0.6的话,可能会出现swagger跳不过去的问题,把版本升高一点就好了。
2. gateway编程
(1) predicate
predicate作用目前只记住一个一般就够了,就是path。
predicate处理的是这个请求,可以理解成if(predicate(request))
,接收这个request,然后通过path、header、cookie来判断走哪个router。
(2) filter和filter工厂
filter的写法是自己实现filter接口,然后实现filter方法,不过如果你写了一个filter类,那么你必须手写RouteLocator,也就是你在yml里面实现的那一套,那一套都必须用java代码来实现,然后把这个RouteLocator注册成bean。
filter工厂,里面有一个apply方法,然后这个方法返回一个filter,你就写一个工厂,返回一个filter类型的匿名类,这一段代码跟你直接写一个filter基本一模一样,以及如果你写的是工厂,就可以用yml来启动了,这个factory要被注册成bean。
全局filter,实现全局filter接口,由于这个全局是给每个RouteLocator都加上去,所以没必要在yml里面注册什么filter了,只是要把这个全局filter注册成bean。
3. 读取数据
(1) 首先是那些正常能读出来的数据,这个有时间详细笔记。
(2) request的数据
如果是Get请求, 直接能读出来
如果是Post请求,body放在一个Flux<DataBuffer>里面,这个就要解析了。
不过说实话,request没什么解析的必要。
(3) response的解析
import org.reactivestreams.Publisher;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.Charset;
/**
* @author wuweifeng wrote on 2018/10/31.
*/
@Component
public class WrapperResponseGlobalFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
// -1 is response write filter, must be called before that
//注意order要小于-1
return -2;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
return super.writeWith(fluxBody.map(dataBuffer -> {
// probably should reuse buffers
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
//释放掉内存
DataBufferUtils.release(dataBuffer);
String s = new String(content, Charset.forName("UTF-8"));
//TODO,s就是response的值,想修改、查看就随意而为了
byte[] uppedContent = new String(content, Charset.forName("UTF-8")).getBytes();
return bufferFactory.wrap(uppedContent);
}));
}
// if body is not a flux. never got there.
return super.writeWith(body);
}
};
// replace response with decorator
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
}
4. 个别注意事项
(1) 新建项目的时候还存在,yml格式编码问题

如果yml读错了,出问题了,把他的编码改一下,改成utf-8
(2)hospital-log模块
这个模块里面基本上只有一句关键逻辑,往数据库里面插入。
这个逻辑比较耗时间,所以想新建线程,不过springboot自带并发,可以新建线程的,所以就不需要了。
网友评论