RestTemplate设置通用header 并获取header请求参数

在开发项目过程中,使用的架构 springboot + vue,但java项目又拆分成一个基础授权(base)项目,一个获取授权(auth)项目,还有两个业务系统。此时需要通过auth项目去获取base项目的授权信息。因此使用了springboot的RestTemplate来实现不同项目之间的访问。但是在base项目中,安全起见增加了请求拦截器,此时获取header成了问题。搜索了很多的帖子,终于在今天解决掉了,现在把实现方案记录下来。

请求方

增加interceptor

public static class UserAgentInterceptor implements ClientHttpRequestInterceptor {
 
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
            HttpHeaders headers = request.getHeaders();
            // 这种方案我没有实现成功,所以用的自定义字段
            // headers.add(HttpHeaders.USER_AGENT, "your agent");
            headers.add("customer_agent", "your agent");
            return execution.execute(request, body);
        }
    }

设置interceptor 

@Bean
    public RestTemplate restTemplate() {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        httpRequestFactory.setConnectionRequestTimeout(CONN_TIMEOUT_IN_MILLIS);
        httpRequestFactory.setConnectTimeout(CONN_TIMEOUT_IN_MILLIS);
        httpRequestFactory.setReadTimeout(READ_TIMEOUT_IN_MILLIS);
 
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters()
                .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        restTemplate.setInterceptors(Collections.singletonList(new UserAgentInterceptor()));
        return restTemplate;
    }

服务方

获取自定义的header

Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
String value = request.getHeader(key);

 

<think>我们使用Java发送multipart/form-data类型的POST请求到本地ChatTTS服务。这里提供两种方法:使用ApacheHttpClient(通用)和使用SpringRestTemplate(适合Spring项目)。两种方法都会将文本发送到本地服务,将返回的音频保存为文件。###方法1:使用ApacheHttpClient(通用,不依赖Spring)步骤:1.添加ApacheHttpClient依赖。2.构建一个包含文本参数的多部分表单实体。3.发送POST请求到ChatTTS服务(假设地址为http://localhost:8000/generate)。4.将响应的音频数据写入文件。代码示例:```javaimportorg.apache.http.HttpEntity;importorg.apache.http.client.methods.CloseableHttpResponse;importorg.apache.http.client.methods.HttpPost;importorg.apache.http.entity.mime.MultipartEntityBuilder;importorg.apache.http.impl.client.CloseableHttpClient;importorg.apache.http.impl.client.HttpClients;importjava.io.File;importjava.io.FileOutputStream;importjava.io.InputStream;publicclassChatTTSClient{publicstaticvoidmain(String[]args){StringapiUrl="http://localhost:8000/generate";//替换为你的ChatTTS服务地址Stringtext="你好,欢迎使用ChatTTS语音合成。";StringoutputFile="output.wav";//输出文件名try(CloseableHttpClienthttpClient=HttpClients.createDefault()){//构建多部分表单MultipartEntityBuilderbuilder=MultipartEntityBuilder.create();builder.addTextBody("text",text);//添加文本参数//可以添加其他参数,例如://builder.addTextBody("speaker","female");//builder.addTextBody("speed","1.0");HttpEntitymultipart=builder.build();HttpPosthttpPost=newHttpPost(apiUrl);httpPost.setEntity(multipart);//发送请求try(CloseableHttpResponseresponse=httpClient.execute(httpPost)){intstatusCode=response.getStatusLine().getStatusCode();if(statusCode==200){//获取响应内容(音频数据)HttpEntityresponseEntity=response.getEntity();if(responseEntity!=null){try(InputStreamin=responseEntity.getContent();FileOutputStreamout=newFileOutputStream(newFile(outputFile))){byte[]buffer=newbyte[1024];intlen;while((len=in.read(buffer))!=-1){out.write(buffer,0,len);}}System.out.println("音频文件已保存至:"+outputFile);}}else{System.err.println("请求失败,状态码:"+statusCode);}}}catch(Exceptione){e.printStackTrace();}}}```####Maven依赖```xml<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version><!--使用最新版本--></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>4.5.13</version><!--用于multipart/form-data--></dependency>```###方法2:使用SpringRestTemplate(适合Spring项目)步骤:1.添加SpringWeb依赖(如果已有SpringBoot项目)。2.使用RestTemplate发送multipart/form-data请求。3.将响应保存为文件。代码示例:```javaimportorg.springframework.core.io.FileSystemResource;importorg.springframework.http.*;importorg.springframework.util.LinkedMultiValueMap;importorg.springframework.util.MultiValueMap;importorg.springframework.web.client.RestTemplate;importjava.io.File;importjava.io.FileOutputStream;publicclassChatTTSRestClient{publicstaticvoidmain(String[]args){StringapiUrl="http://localhost:8000/generate";Stringtext="你好,这是通过SpringRestTemplate发送的请求。";StringoutputFile="output_spring.wav";//构建请求体(multipart/form-data)MultiValueMap<String,Object>body=newLinkedMultiValueMap<>();body.add("text",text);//文本参数//可以添加其他参数//body.add("speaker","male");//设置请求头HttpHeadersheaders=newHttpHeaders();headers.setContentType(MediaType.MULTIPART_FORM_DATA);//创建请求实体HttpEntity<MultiValueMap<String,Object>>requestEntity=newHttpEntity<>(body,headers);//发送请求RestTemplaterestTemplate=newRestTemplate();ResponseEntity<byte[]>response=restTemplate.exchange(apiUrl,HttpMethod.POST,requestEntity,byte[].class);if(response.getStatusCode()==HttpStatus.OK){//将响应体(音频数据)写入文件byte[]audioData=response.getBody();try(FileOutputStreamfos=newFileOutputStream(outputFile)){fos.write(audioData);System.out.println("音频文件已保存至:"+outputFile);}catch(Exceptione){e.printStackTrace();}}else{System.err.println("请求失败:"+response.getStatusCode());}}}```####Maven依赖(SpringBoot)```xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.2.0</version></dependency>```###注意事项:1.**参数设置**:根据ChatTTS服务的API文档,可能需要传递额外的参数(如`speaker`、`speed`、`format`等),请按需添加。2.**错误处理**:增加适当的异常处理和重试机制。3.**服务地址**:确保服务地址和端口正确,且服务已启动。4.**中文编码**:如果遇到中文乱码问题,确保服务端和客户端都使用UTF-8编码。###测试服务是否可用使用curl命令测试:```bashcurl-XPOSThttp://localhost:8000/generate-F"text=测试文本"--outputtest.wav```如果上述命令能生成音频文件,则服务正常。###常见问题解决:-**连接超时**:检查服务是否运行,或防火墙设置。-**中文乱码**:在构建请求时,确保文本以UTF-8编码发送(通常上述代码已处理)。-**大文本处理**:如果文本很长,考虑分片发送或检查服务是否支持长文本。###§§相关问题§§1.如何调整生成的音频的语速和音量?2.如何选择不同的发音人(音色)?3.如何处理长文本的语音合成(分片或流式)?4.如何将生成的音频直接播放而不保存为文件?5.如何监控语音合成的进度?</think>### Java 实现 ChatTTS 文字转音频的完整方案 我将提供两种使用 Java 发起 form-data 类型 POST 请求到本地 ChatTTS 应用的实现方案,支持中文文本转换保存音频文件。 --- ### 方案一:使用 Apache HttpClient(通用方案) ```java import org.apache.http.HttpEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import java.io.*; public class ChatTTSService { public static void main(String[] args) { String apiUrl = "http://localhost:8000/generate"; // ChatTTS服务地址 String text = "你好,这是一段测试文本,将被转换为语音"; String outputPath = "output.wav"; // 输出文件路径 try (CloseableHttpClient httpClient = HttpClients.createDefault()) { // 1. 构建multipart/form-data请求体 HttpEntity multipartEntity = MultipartEntityBuilder.create() .addTextBody("text", text, org.apache.http.entity.ContentType.TEXT_PLAIN) .addTextBody("speaker", "female") // 发音人(可选) .addTextBody("speed", "1.0") // 语速(可选) .addTextBody("format", "wav") // 输出格式(可选) .build(); // 2. 创建POST请求 HttpPost httpPost = new HttpPost(apiUrl); httpPost.setEntity(multipartEntity); // 3. 发送请求处理响应 try (CloseableHttpResponse response = httpClient.execute(httpPost); InputStream content = response.getEntity().getContent(); FileOutputStream fos = new FileOutputStream(outputPath)) { // 4. 验证响应状态 if (response.getStatusLine().getStatusCode() == 200) { // 5. 将音频流写入文件 byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = content.read(buffer)) != -1) { fos.write(buffer, 0, bytesRead); } System.out.println("音频文件生成成功: " + new File(outputPath).getAbsolutePath()); } else { System.err.println("请求失败: " + response.getStatusLine()); } } } catch (Exception e) { e.printStackTrace(); } } } ``` #### 关键说明: 1. **依赖添加**(Maven): ```xml <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>4.5.13</version> </dependency> ``` 2. **参数说明**: - `text`: 必需参数,要转换的文本 - `speaker`: 发音人(如 `female`, `male`) - `speed`: 语速(1.0 为正常速度) - `format`: 输出格式(wav, mp3等) 3. **中文支持**: ```java .addTextBody("text", text, ContentType.create("text/plain", "UTF-8")) ``` --- ### 方案二:使用 Java 11+ HttpClient(无需额外依赖) ```java import java.net.URI; import java.net.http.*; import java.net.http.HttpRequest.BodyPublishers; import java.nio.file.*; import java.util.*; public class ChatTTSJava11 { public static void main(String[] args) throws Exception { String apiUrl = "http://localhost:8000/generate"; String text = "Java 11+ 原生HTTP客户端实现"; String outputPath = "output_java11.mp3"; // 1. 构建multipart/form-data边界 String boundary = "----Java11FormBoundary" + System.currentTimeMillis(); // 2. 创建多部分请求体 Map<Object, Object> formData = new LinkedHashMap<>(); formData.put("text", text); formData.put("emotion", "happy"); // 情感参数(可选) formData.put("volume", "0.9"); // 音量(可选) // 3. 构建请求体 HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(apiUrl)) .header("Content-Type", "multipart/form-data; boundary=" + boundary) .POST(createMultipartBody(formData, boundary)) .build(); // 4. 发送请求 HttpClient client = HttpClient.newHttpClient(); HttpResponse<Path> response = client.send( request, HttpResponse.BodyHandlers.ofFile(Paths.get(outputPath)) ); // 5. 处理响应 if (response.statusCode() == 200) { System.out.println("音频文件保存至: " + response.body().toAbsolutePath()); } else { System.err.println("请求失败: " + response.statusCode()); } } private static BodyPublisher createMultipartBody(Map<Object, Object> data, String boundary) { List<byte[]> byteArrays = new ArrayList<>(); byte[] separator = ("--" + boundary + "\r\nContent-Disposition: form-data; name=").getBytes(); for (Map.Entry<Object, Object> entry : data.entrySet()) { byteArrays.add(separator); byteArrays.add(("\"" + entry.getKey() + "\"\r\n\r\n" + entry.getValue() + "\r\n").getBytes()); } byteArrays.add(("--" + boundary + "--").getBytes()); return BodyPublishers.ofByteArrays(byteArrays); } } ``` #### 关键说明: 1. **无需额外依赖**:使用 Java 11+ 内置 HTTP 客户端 2. **参数扩展**: ```java // 添加自定义参数 formData.put("pitch", "1.2"); // 音调 formData.put("silence", "0.5"); // 句间停顿 ``` --- ### 注意事项与优化建议 1. **服务验证**: ```bash curl -X POST http://localhost:8000/generate -F "text=测试文本" -o test.wav ``` 2. **错误处理增强**: ```java // 添加重试机制 int maxRetries = 3; for (int i = 0; i <= maxRetries; i++) { try { // 发送请求... break; // 成功则跳出循环 } catch (ConnectException e) { if (i == maxRetries) throw e; Thread.sleep(1000 * (i + 1)); // 指数退避 } } ``` 3. **大文本处理**: ```java // 分块发送长文本 int chunkSize = 500; // 按字符分块 for (int i = 0; i < text.length(); i += chunkSize) { String chunk = text.substring(i, Math.min(i + chunkSize, text.length())); // 发送chunk... } ``` 4. **性能优化**: ```java // 使用连接池(Apache HttpClient) PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(20); CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm).build(); ``` --- ### 常见问题解决 | 问题类型 | 解决方案 | |------------------|--------------------------------------------------------------------------| | 连接拒绝 | 检查 ChatTTS 服务是否运行在指定端口 (`netstat -ano \| findstr :8000`) | | 中文乱码 | 明确设置 UTF-8 编码:`ContentType.create("text/plain", "UTF-8")` | | 音频无法播放 | 检查响应头 `Content-Type` (应为 `audio/wav` 或 `audio/mpeg`) | | 长文本处理失败 | 分块发送文本,每次不超过 1000 字符 | | 服务无响应 | 添加超时控制:`.setConnectTimeout(5000, TimeUnit.MILLISECONDS)` | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值