使用SendGrid发送带附件邮件时抛出NoHttpResponseException求助
Java使用SendGrid发送带附件邮件时抛出NoHttpResponseException异常
使用SendGrid 4.9.3、commons-codec 1.15和httpclient5 5.2.1版本发送带附件邮件时,抛出org.apache.http.NoHttpResponseException: api.sendgrid.com failed to respond异常,以下是相关代码及堆栈跟踪:
参考代码
public synchronized void sendEmail() { try { Email from = new Email("qa-automation@revmedia.my"); String subject = "Buletin TV3 Test Automation Report"; Email to = new Email("nicholaswkc34@gmail.com"); Content content = new Content("text/plain", "Dear Stakeholders, please find the test automation report from attachment"); Mail mail = new Mail(from, subject, to, content); Path reportFilePath = Paths.get(".//report//TestReport-Spark.html"); Attachments attachments = new Attachments(); attachments.setFilename("TestReport-Spark.html"); attachments.setType("text/html"); attachments.setDisposition("attachment"); byte[] attachBytes = Files.readAllBytes(reportFilePath); String attachContent = Base64.getMimeEncoder().encodeToString(attachBytes); String s = Base64.getEncoder().encodeToString(attachBytes); attachments.setContent(s); mail.addAttachments(attachments); SendGrid sg = new SendGrid("API_Keys"); Request request = new Request(); request.setMethod(Method.POST); request.setEndpoint("mail/send"); request.setBody(mail.build()); Response response = sg.api(request); System.out.println(response.getStatusCode()); System.out.println(response.getBody()); System.out.println(response.getHeaders()); } catch (IOException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } }
堆栈跟踪信息
org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57) org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167) org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271) org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107) com.sendgrid.Client.executeApiCall(Client.java:377) com.sendgrid.Client.post(Client.java:249) com.sendgrid.Client.api(Client.java:407) com.sendgrid.BaseInterface.makeCall(BaseInterface.java:253)
排查及解决方案
1. 版本兼容性问题
SendGrid 4.9.3依赖的是Apache HttpClient 4.5.x版本,而你使用的HttpClient5 5.2.1是完全重构的大版本,API和内部实现与4.x不兼容,会导致连接处理逻辑异常。
- 解决方案:将httpclient5替换为SendGrid官方依赖的HttpClient版本(如4.5.13),移除httpclient5相关依赖,确保版本匹配。
2. 附件Base64编码格式错误
SendGrid要求附件内容使用MIME兼容的Base64编码(自动添加换行符分割长内容),但你的代码中使用了普通的Base64.getEncoder(),生成的无换行长字符串可能触发服务端异常处理,导致连接被关闭。
- 解决方案:替换为
Base64.getMimeEncoder().encodeToString(attachBytes)设置附件内容:byte[] attachBytes = Files.readAllBytes(reportFilePath); String attachContent = Base64.getMimeEncoder().encodeToString(attachBytes); attachments.setContent(attachContent);
3. 网络连通性与拦截
- 检查服务器是否能正常访问
api.sendgrid.com,可以用telnet api.sendgrid.com 443或curl -v https://api.sendgrid.com/v3/mail/send测试连通性。 - 确认是否有防火墙、代理服务器拦截了HTTPS请求,必要时配置代理参数到SendGrid客户端。
4. 客户端超时与重试配置
默认的SendGrid客户端超时时间较短,且重试策略不足,网络波动时易出现无响应异常。可以手动配置客户端参数:
SendGrid sg = new SendGrid("API_Keys"); Client client = sg.getClient(); client.setConnectTimeout(30000); // 30秒连接超时 client.setReadTimeout(60000); // 60秒读取超时 client.setRetryOnConnectionFailure(true); // 开启连接失败重试
5. API密钥验证
确认你的SendGrid API密钥是否有效,且拥有mail.send权限。可以在SendGrid控制台生成新的测试密钥,替换后再次尝试。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

