[SPRING] Cloud API 게이트웨이에 대한 응답 본문에 데이터를 추가하는 방법
SPRINGCloud API 게이트웨이에 대한 응답 본문에 데이터를 추가하는 방법
일부 인증 로직을 클라우드 API 게이트웨이에 추가하고 있습니다. 나는 GatewayFilter를 추가했다.
import java.util.List;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PatternMatchUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
public class AuthorizationFilter implements GatewayFilter {
@Override
public Mono<Void> filter(
ServerWebExchange exchange, GatewayFilterChain chain) {
List<String> authorization = exchange.getRequest().getHeaders().get("Authorization");
if (CollectionUtils.isEmpty(authorization) &&
!PatternMatchUtils.simpleMatch(URL_WITHOUT_AUTH, exchange.getRequest().getURI().toString())) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//Add some custom data in body of the response
return exchange.getResponse().setComplete();
}
String token = authorization.get(0).split(" ")[1];
// token validation
return chain.filter(exchange);
}
}
하지만 응답 본문에 일부 데이터를 추가 할 수는 없습니다. 어떻게 작동하는지 그리고 어떻게 사용자 정의 할 수 있는지 알아 주시겠습니까?
추신 플럭스를 사용하여 응답으로 일부 데이터를 추가하려고하지만 작동하지 않습니다.
DataBuffer b = exchange.getResponse().bufferFactory().allocateBuffer(256);
b.write("12345".getBytes());
return exchange.getResponse().writeWith(s -> Flux.just(b));
내가 뭘 잘못하고있어?
해결법
-
==============================
1.봄 녀석들의 도움을 받아, 나는 일하게 만들 수 있었다. 따라서 응답에 직접 작성하는 대신 사용자 정의 예외를 던져 올바르게 처리해야했습니다.
봄 녀석들의 도움을 받아, 나는 일하게 만들 수 있었다. 따라서 응답에 직접 작성하는 대신 사용자 정의 예외를 던져 올바르게 처리해야했습니다.
@Bean public ErrorWebExceptionHandler myExceptionHandler() { return new MyWebExceptionHandler(); } public class MyWebExceptionHandler implements ErrorWebExceptionHandler { @Override public Mono<Void> handle( ServerWebExchange exchange, Throwable ex) { byte[] bytes = "Some text".getBytes(StandardCharsets.UTF_8); DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes); return exchange.getResponse().writeWith(Flux.just(buffer)); } }
-
==============================
2.ServerHttpResponseDecorator를 사용하여 응답을 수정해야합니다.
ServerHttpResponseDecorator를 사용하여 응답을 수정해야합니다.
코드는 다음과 같아야합니다.
import java.util.List; import org.reactivestreams.Publisher; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.http.HttpStatus; import org.springframework.util.CollectionUtils; import org.springframework.util.PatternMatchUtils; import org.springframework.web.server.ServerWebExchange; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.http.server.reactive.ServerHttpResponseDecorator; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.core.Ordered; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; public class AuthorizationFilter implements GatewayFilter { @Override public Mono<Void> filter( ServerWebExchange exchange, GatewayFilterChain chain) { List<String> authorization = exchange.getRequest().getHeaders().get("Authorization"); if (CollectionUtils.isEmpty(authorization) && !PatternMatchUtils.simpleMatch(URL_WITHOUT_AUTH, exchange.getRequest().getURI().toString())) { exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); 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); byte[] uppedContent = new String(content, Charset.forName("UTF-8")).toUpperCase().getBytes(); return bufferFactory.wrap(uppedContent); })); } return super.writeWith(body); // if body is not a flux. never got there. } }; return chain.filter(exchange.mutate().response(decoratedResponse).build()); // replace response with decorator } String token = authorization.get(0).split(" ")[1]; // token validation return chain.filter(exchange); } }
여기서 완전한 예를 찾을 수 있습니다.
from https://stackoverflow.com/questions/48491098/how-to-add-some-data-in-body-of-response-for-cloud-api-gateway by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] @DataJpaTest로 Spring 테스트는 @Repository로 클래스를 autowire 할 수 없습니다 (하지만 인터페이스 저장소가 작동합니다!). (0) | 2019.04.24 |
---|---|
[SPRING] 도커가있는 스프링 부트가 요청 된 대상 오류에 대한 유효한 인증 경로를 찾을 수 없습니다. (0) | 2019.04.24 |
[SPRING] Dozer의 사용자 지정 변환기를 사용하여 개체 목록을 다른 목록에 매핑 (0) | 2019.04.24 |
[SPRING] 봄에 속성 파일로드 (0) | 2019.04.24 |
[SPRING] 빈 응답이있는 내 사용자 정의 ClientHttpRequestInterceptor (0) | 2019.04.24 |