企业代理环境下连接Google Cloud语音转文本API遇故障求助
你遇到的核心问题是GRPC(Google Cloud Java客户端的底层依赖)不识别JVM的HTTP代理系统属性,而且之前配置的GRPC_PROXY_EXP环境变量格式可能不符合要求。别担心,下面是一步步的解决方案:
1. 先修正GRPC代理环境变量格式
GRPC对代理环境变量的格式有严格要求,必须带上http://前缀,如果你的代理需要用户名密码认证,还要把信息包含进去:
Windows(命令行):
set GRPC_PROXY_EXP=http://[你的代理用户名:密码@]X.X.X.X:3128
Linux/macOS:
export GRPC_PROXY_EXP=http://[你的代理用户名:密码@]X.X.X.X:3128
举个例子:如果代理地址是
10.0.0.5:3128,用户名是john,密码是doe123,那就是http://john:doe123@10.0.0.5:3128;不需要认证的话直接去掉用户名:密码@部分。
设置完后记得重启你的Java应用,让环境变量生效。
2. 代码中手动配置代理(更可靠的方式)
如果环境变量还是不生效,你可以直接在代码里给SpeechClient配置带代理的GRPC通道。修改你的代码如下:
import io.grpc.ManagedChannel; import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder; import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts; import io.grpc.netty.shaded.io.netty.handler.proxy.HttpProxyHandler; import io.grpc.netty.shaded.io.netty.handler.proxy.ProxyHandler; import io.grpc.netty.shaded.io.netty.channel.socket.InetSocketAddress; import com.google.cloud.speech.v1.SpeechClient; import com.google.cloud.speech.v1.SpeechSettings; public class SpeechToTextDemo { public static void main(String[] args) throws Exception { // 代理配置信息 String proxyHost = "X.X.X.X"; int proxyPort = 3128; String proxyUsername = "your-proxy-user"; // 不需要认证就设为null String proxyPassword = "your-proxy-pass"; // 不需要认证就设为null // 创建带代理的GRPC通道 NettyChannelBuilder channelBuilder = NettyChannelBuilder.forTarget("speech.googleapis.com:443") .sslContext(GrpcSslContexts.forClient().build()); // 添加代理处理器 channelBuilder.handlerConfigurator(ctx -> { ProxyHandler proxyHandler; if (proxyUsername != null && !proxyUsername.isEmpty()) { proxyHandler = new HttpProxyHandler( new InetSocketAddress(proxyHost, proxyPort), proxyUsername, proxyPassword); } else { proxyHandler = new HttpProxyHandler( new InetSocketAddress(proxyHost, proxyPort)); } ctx.pipeline().addFirst(proxyHandler); return null; }); ManagedChannel channel = channelBuilder.build(); SpeechSettings speechSettings = SpeechSettings.newBuilder() .setChannelProvider(() -> channel) .build(); // 用自定义的Settings创建SpeechClient try (SpeechClient speech = SpeechClient.create(speechSettings)) { // --- 这里放你原来的音频处理代码 --- String fileName = "D:\\RecordAudio1.flac"; System.out.println("path " + fileName); byte[] data = java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(fileName)); com.google.protobuf.ByteString audioBytes = com.google.protobuf.ByteString.copyFrom(data); com.google.cloud.speech.v1.RecognitionConfig config = com.google.cloud.speech.v1.RecognitionConfig.newBuilder() .setEncoding(com.google.cloud.speech.v1.RecognitionConfig.AudioEncoding.FLAC) .setSampleRateHertz(16000) .setLanguageCode("en-US") .build(); com.google.cloud.speech.v1.RecognitionAudio audio = com.google.cloud.speech.v1.RecognitionAudio.newBuilder() .setContent(audioBytes) .build(); com.google.cloud.speech.v1.RecognizeResponse response = speech.recognize(config, audio); System.out.println("came to line 69 " + response.getResultsList().size()); for (com.google.cloud.speech.v1.SpeechRecognitionResult result : response.getResultsList()) { com.google.cloud.speech.v1.SpeechRecognitionAlternative alternative = result.getAlternativesList().get(0); System.out.printf("Transcription: %s%n", alternative.getTranscript()); } } catch (Exception e) { e.printStackTrace(); } } }
3. 先验证代理是否能连通Google API
在调试代码前,先确认你的代理能正常访问Speech-to-Text的API端点:
用curl命令测试(Windows需要安装curl,或者用PowerShell的Invoke-WebRequest):
curl -x http://X.X.X.X:3128 https://speech.googleapis.com/v1/speech:recognize
如果返回类似{"error":{"code":400,"message":"Required parameter: config","status":"INVALID_ARGUMENT"}}的内容,说明代理连通正常;如果返回连接超时或无法解析主机,那得先联系企业IT团队确认代理是否允许访问Google的API服务。
4. 处理企业代理的SSL证书(如果有需要)
如果你的企业代理用了自签名SSL证书,GRPC会因为证书验证失败而拒绝连接。这时候需要把代理的证书导入到JVM的信任库:
- 从IT团队获取代理的SSL证书文件(比如
proxy-cert.crt) - 用
keytool命令导入:
keytool -import -alias proxy-cert -file proxy-cert.crt -keystore "%JAVA_HOME%\lib\security\cacerts"
默认的信任库密码是changeit,输入密码后确认导入即可。
内容的提问来源于stack exchange,提问作者user1302

