在控制臺列印亂碼,編碼格式換過一個遍了,只要轉String再轉byte就亂碼, 回傳到potman顯示 獲取不到response,大佬們幫忙看看
package com.
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Charsets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.reactivestreams.Publisher;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
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.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
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.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;
import static com.sun.org.glassfish.external.statistics.impl.StatisticImpl.START_TIME;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;
@Slf4j
@Component
public class DataRespEncryptFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
// String ip = IpUtil.getRemoteHost(request);
//執行完成后 進行呼叫耗時埋點
exchange.getAttributes().put(START_TIME, System.currentTimeMillis());
//原始回應類
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
//初始化一個 默認的 responseBody
AtomicReference<String> responseBody= new AtomicReference<>("no-responseBody");
//重新包裝的回應類
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
DataBuffer join = dataBufferFactory.join(dataBuffers);
byte[] content = new byte[join.readableByteCount()];
join.read(content);
// 釋放掉記憶體
DataBufferUtils.release(join);
String str = new String(content, Charset.forName("UTF-8"));
originalResponse.getHeaders().setContentLength(str.getBytes().length);
System.out.println(str);
return bufferFactory.wrap(str.getBytes());
}));
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build())
.then(Mono.fromRunnable(() -> {
//列印回應日志
logResponse(exchange, responseBody.get());
Long startTime = exchange.getAttribute(START_TIME);
if (startTime != null) {
Long executeTime = (System.currentTimeMillis() - startTime);
//influxDB埋點
// metricService.pointRequestLatency(ip, request.getURI().getPath(), executeTime);
}
}));
}
/**
* 列印回應報文
*
* @param exchange
*/
public void logResponse(ServerWebExchange exchange, String response) {
ServerHttpRequest request = exchange.getRequest();
log.info("回應報文 URL:{},Method:{},headers:{},response:{}", request.getURI().getPath(), request.getMethod(), exchange.getResponse().getHeaders(), response);
}
@Override
public int getOrder() {
return -10;
}
}
控制臺列印:

postman 界面:

上面的UTF-8 試過 US_ASCII , ISO_8859_1 , UTF_16BE ,UTF_16LE ,UTF_16
但是將直接獲取的content 直接回傳就沒問題:


大佬們幫忙看看 為啥亂碼
uj5u.com熱心網友回復:
結貼,有個gzip編碼 做個解碼就ok
if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
// 獲取ContentType,判斷是否回傳JSON格式資料
String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
if(StringUtils.isNotBlank(originalResponseContentType) && originalResponseContentType.contains("application/json")) {
// 如果需要加密才進行處理
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
DataBuffer join = dataBufferFactory.join(dataBuffers);
byte[] content = new byte[join.readableByteCount()];
join.read(content);
String responseData = new String(uncompress(content), Charsets.UTF_8);
System.out.println(responseData);
byte[] uppedContent = compress(responseData,"UTF-8");
originalResponse.getHeaders().setContentLength(uppedContent.length);
originalResponse.getHeaders().set("encrypt", "true");
return bufferFactory.wrap(uppedContent);
}));
}
}gizp:
/*解碼 gzip*/
public static byte[] uncompress(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
try {
GZIPInputStream ungzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n;
while ((n = ungzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
} catch (IOException e) {
log.error("gzip uncompress error.", e);
}
return out.toByteArray();
}
/*編碼 gzip*/
public static byte[] compress(String str, String encoding) {
if (str == null || str.length() == 0) {
return null;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip;
try {
gzip = new GZIPOutputStream(out);
gzip.write(str.getBytes(encoding));
gzip.close();
} catch (IOException e) {
log.error("gzip compress error.", e);
}
return out.toByteArray();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/268009.html
標籤:Java相關
上一篇:請教:管理員登錄后臺以后在用戶管理串列中一鍵跳轉前端并實作用戶登錄
下一篇:密鑰簽名RSA 格式 PKCS7
