获取SpringCloud gateway 响应的response的值 乱码

爬坑小庄 2021-03-11 09:40:35
在控制台打印乱码,编码格式换过一个遍了,只要转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 直接返回就没问题:



大佬们帮忙看看 为啥乱码
...全文
2785 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
Crazy_4J 2022-04-19
  • 打赏
  • 举报
回复

把postman中的header值 Accept-Encoding 勾掉就不乱吗了

syx12305 2021-04-23
  • 打赏
  • 举报
回复
感谢大佬,确实是这个原因
爬坑小庄 2021-03-11
  • 打赏
  • 举报
回复 2
结贴,有个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();

    }

50,559

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧