nginx 这个属性一定要设为 关闭 :proxy_buffering off;
okhttp3默认是禁止重定向的,但是forest内部实现了重定向,如果想让okhttp3和forest实现一样的功能,需要在拦截器中配置重定向定制
pom文件
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.12.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp-sse</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
拦截器
package com.uniauth.satoken.forest; import okhttp3.*; import okio.Buffer; import java.io.IOException; public class CustomLoggingInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Response response = chain.proceed(request); System.out.println("=== Request Headers ==="); for (String name : request.headers().names()) { System.out.println(name + ": " + request.header(name)); } if (request.body() != null) { Buffer buffer = new Buffer(); request.body().writeTo(buffer); System.out.println("=== Request Body ==="); System.out.println(buffer.readUtf8()); } System.out.println("Request URL: " + request.url()); System.out.println("Response Code: " + response.code()); if (response.isRedirect()) { String location = response.header("Location"); System.out.println("Redirect to: " + location); if (location != null && !location.isEmpty()) { // 构建新的请求,保留原始方法 (POST) 和 Body Request newRequest = request.newBuilder() .url(location) // 新的 URL // 确保保留原始的 Body 和 Headers .method(request.method(), request.body()) .build(); System.out.println("重定向====保留原始method:"+request.method()); response.close(); return chain.proceed(newRequest); } } return response; } }
Configuration:如果需要手动重定向,不要在 addNetworkInterceptor 直接写,要在拦截器中写好,通过.addInterceptor(new CustomLoggingInterceptor()) 放进去
因为addNetworkInterceptor 在这里写,会触发安全认证,导致写的重定向不生效
package com.uniauth.satoken.forest; import okhttp3.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.TimeUnit; @Configuration public class Okhttp3Configuration { @Bean public OkHttpClient okHttpClient() { return new OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) .writeTimeout(60, TimeUnit.SECONDS) .followRedirects(false) .followSslRedirects(false) // .addNetworkInterceptor(chain -> { // // }) .addInterceptor(new CustomLoggingInterceptor()) .build(); } }
controller
@GetMapping(value = "/chat",produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter chat(@RequestParam @NotBlank String query) { SseEmitter emitter = new SseEmitter(0L); try{ RequestBody requestBody = RequestBody.create(okhttp3.MediaType.parse("application/json"), JSON.toJSONString(conversationParam)); Request difyRequest = new Request.Builder() .url("http://xxx.cn/ab/xxxxxxxx/runs") .post(requestBody) .addHeader("Authorization", Authorization) .addHeader("X-Authorization", XAuthorization) .addHeader("content-type", "application/json") .build(); return SseForwardUtils.sseForward(difyRequest, okHttpClient); }catch (Exception e){ emitter.completeWithError(e); } return emitter; }
