将OkHttp请求转换为Spring RestTemplate请求。

huangapple go评论64阅读模式
英文:

Convert OkHttp Request to Spring RestTemplate Request

问题

Sure, here is the translated code part:

我有一个类似这样的 OkHttp 请求

    public String createImageEditWithOkHttp(String prompt) throws IOException
    {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .callTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .build();
        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("image","file",
                        RequestBody.create(MediaType.parse("application/octet-stream"),
                                ResourceUtils.getFile("classpath:image_edit_original.png")))
                .addFormDataPart("mask","file",
                        RequestBody.create(MediaType.parse("application/octet-stream"),
                                ResourceUtils.getFile("classpath:image_edit_mask.png")))
                .addFormDataPart("prompt", prompt)
                .addFormDataPart("n", "1")
                .addFormDataPart("size", ImageSize.SMALL.getSize())
                .build();
        Request request = new Request.Builder()
                .url(IMAGE_EDIT_URL)
                .method("POST", body)
                .addHeader("Authorization", "Bearer " + OPENAI_API_KEY)
                .build();
        Response response = client.newCall(request).execute();

        return response.body().string();
    }

在这里从资源文件中读取文件并将其作为 MultipartFile 发送到 okhttp post 请求OkHttp 版本像预期的那样工作但是当我尝试将其转换为 resttemplate 版本时它无法在请求正文中找到文件

我想将其转换为 spring resttemplate 请求

    public String createImageEditWithRestTemplate(String prompt) throws FileNotFoundException
    {
        HttpEntity<MultiValueMap<String, Object>> requestEntity
                = new HttpEntity<>(createBody(prompt), commonHttpHeaders());

        ResponseEntity<String> response = restTemplate.postForEntity(IMAGE_EDIT_URL, requestEntity, String.class);

        return response.getBody();
    }

    private MultiValueMap<String, Object> createBody(String prompt) throws FileNotFoundException
    {
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

        body.add("image", ResourceUtils.getFile("classpath:image_edit_original.png"));
        body.add("mask", ResourceUtils.getFile("classpath:image_edit_mask.png"));
        body.add("prompt", prompt);
        body.add("n", "1");
        body.add("size", ImageSize.SMALL.getSize());

        return body;
    }

    private HttpHeaders commonHttpHeaders()
    {
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();

        headers.add("Authorization", "Bearer " + OPENAI_API_KEY);
        headers.add("Content-Type", org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE);

        return new HttpHeaders(headers);
    }

但是它无法在请求中找到图像作为文件有什么建议吗
英文:

I have a OkHttp request like:

public String createImageEditWithOkHttp(String prompt) throws IOException
{
OkHttpClient client = new OkHttpClient().newBuilder()
.connectTimeout(30, TimeUnit.SECONDS)
.callTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart(&quot;image&quot;,&quot;file&quot;,
RequestBody.create(MediaType.parse(&quot;application/octet-stream&quot;),
ResourceUtils.getFile(&quot;classpath:image_edit_original.png&quot;)))
.addFormDataPart(&quot;mask&quot;,&quot;file&quot;,
RequestBody.create(MediaType.parse(&quot;application/octet-stream&quot;),
ResourceUtils.getFile(&quot;classpath:image_edit_mask.png&quot;)))
.addFormDataPart(&quot;prompt&quot;,prompt)
.addFormDataPart(&quot;n&quot;,&quot;1&quot;)
.addFormDataPart(&quot;size&quot;, ImageSize.SMALL.getSize())
.build();
Request request = new Request.Builder()
.url(IMAGE_EDIT_URL)
.method(&quot;POST&quot;, body)
.addHeader(&quot;Authorization&quot;, &quot;Bearer &quot; + OPENAI_API_KEY)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}

Here, read file from resources and send it as multipartfile with okhttp post request. OkHttp version works like expected. But when I try to convert it to resttemplate version, it couldn't find files on the request boy.

and I want to convert it to spring resttemplate request:

public String createImageEditWithRestTemplate(String prompt) throws FileNotFoundException
{
HttpEntity&lt;MultiValueMap&lt;String, Object&gt;&gt; requestEntity
= new HttpEntity&lt;&gt;(createBody(prompt), commonHttpHeaders());
ResponseEntity&lt;String&gt; response = restTemplate.postForEntity(IMAGE_EDIT_URL, requestEntity, String.class);
return response.getBody();
}
private MultiValueMap&lt;String, Object&gt; createBody(String prompt) throws FileNotFoundException
{
MultiValueMap&lt;String,Object&gt; body = new LinkedMultiValueMap&lt;&gt;();
body.add(&quot;image&quot;, ResourceUtils.getFile(&quot;classpath:image_edit_original.png&quot;));
body.add(&quot;mask&quot;, ResourceUtils.getFile(&quot;classpath:image_edit_mask.png&quot;));
body.add(&quot;prompt&quot;,prompt);
body.add(&quot;n&quot;,&quot;1&quot;);
body.add(&quot;size&quot;, ImageSize.SMALL.getSize());
return body;
}
private HttpHeaders commonHttpHeaders()
{
MultiValueMap&lt;String,String&gt; headers = new LinkedMultiValueMap&lt;&gt;();
headers.add(&quot;Authorization&quot;, &quot;Bearer &quot; + OPENAI_API_KEY);
headers.add(&quot;Content-Type&quot;, org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE);
return new HttpHeaders(headers);
}

But it couldn't find image as file in the request. Any suggestion?

答案1

得分: 0

I found the problem. We need to send the file with the FileSystemResource wrapper.

private MultiValueMap<String, Object> createBody(String prompt) throws FileNotFoundException {
    MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

    body.add("image", new FileSystemResource(ResourceUtils.getFile("classpath:image_edit_original.png")));
    body.add("mask", new FileSystemResource(ResourceUtils.getFile("classpath:image_edit_mask.png")));
    body.add("prompt", prompt);
    body.add("n", "1");
    body.add("size", ImageSize.SMALL.getSize());

    return body;
}
英文:

Ok, I found the problem. We need to send file with FileSystemResource wrapper.

private MultiValueMap&lt;String, Object&gt; createBody(String prompt) throws FileNotFoundException
{
MultiValueMap&lt;String,Object&gt; body = new LinkedMultiValueMap&lt;&gt;();
body.add(&quot;image&quot;, new FileSystemResource(ResourceUtils.getFile(&quot;classpath:image_edit_original.png&quot;)));
body.add(&quot;mask&quot;, new FileSystemResource(ResourceUtils.getFile(&quot;classpath:image_edit_mask.png&quot;)));
body.add(&quot;prompt&quot;,prompt);
body.add(&quot;n&quot;,&quot;1&quot;);
body.add(&quot;size&quot;, ImageSize.SMALL.getSize());
return body;
}

答案2

得分: 0

你需要使用 Resource 而不是文件对象。由于你从类路径中读取文件,可以使用 ClassPathResource。此外,Headers 部分你有方法来设置 BearerAuth 和 Content-Type。

public String createImageEditWithRestTemplate(String prompt) throws FileNotFoundException {
    HttpEntity&lt;MultiValueMap&lt;String, Object&gt;&gt; requestEntity =
            new HttpEntity&lt;&gt;(createBody(prompt), commonHttpHeaders());
    ResponseEntity&lt;String&gt; response = restTemplate.postForEntity(IMAGE_EDIT_URL, requestEntity, String.class);
    return response.getBody();
}

private MultiValueMap&lt;String, Object&gt; createBody(String prompt) throws FileNotFoundException {
    MultiValueMap&lt;String, Object&gt; body = new LinkedMultiValueMap&lt;&gt;();
    body.add(&quot;image&quot;, new ClassPathResource(&quot;image_edit_original.png&quot;));
    body.add(&quot;mask&quot;, new ClassPathResource(&quot;image_edit_mask.png&quot;));
    body add(&quot;prompt&quot;, prompt);
    body add(&quot;n&quot;, &quot;1&quot;);
    body add(&quot;size&quot;, ImageSize.SMALL.getSize());
    return body;
}

private HttpHeaders commonHttpHeaders() {
    HttpHeaders headers = new HttpHeaders();
    headers.setBearerAuth(OPENAI_API_KEY);
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    return headers;
}

如果你没有在 RestTemplate 中设置超时,那么使用 httpclient 库生成 RestTemplate 对象如下。

public RestTemplate getRestTemplate() throws KeyManagementException, NoSuchAlgorithmException {
    SSLContext sslContext = SSLContexts.custom().build();
    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).useSystemProperties().build();
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setHttpClient(httpClient);
    requestFactory.setConnectTimeout(30000);
    requestFactory.setReadTimeout(30000);
    requestFactory.setConnectionRequestTimeout(30000);
    return new RestTemplate(requestFactory);
}
英文:

You need to use Resource instead of file object. As you reading file from classpath you can use ClassPathResource. Also, Headers you have method to set BearerAuth and Content-Type.

public String createImageEditWithRestTemplate(String prompt) throws FileNotFoundException {
    HttpEntity&lt;MultiValueMap&lt;String, Object&gt;&gt; requestEntity =
            new HttpEntity&lt;&gt;(createBody(prompt), commonHttpHeaders());
    ResponseEntity&lt;String&gt; response = restTemplate.postForEntity(IMAGE_EDIT_URL, requestEntity, String.class);
    return response.getBody();
}

private MultiValueMap&lt;String, Object&gt; createBody(String prompt) throws FileNotFoundException {
    MultiValueMap&lt;String, Object&gt; body = new LinkedMultiValueMap&lt;&gt;();
    body.add(&quot;image&quot;, new ClassPathResource(&quot;image_edit_original.png&quot;));
    body.add(&quot;mask&quot;, new ClassPathResource(&quot;image_edit_mask.png&quot;));
    body.add(&quot;prompt&quot;, prompt);
    body.add(&quot;n&quot;, &quot;1&quot;);
    body.add(&quot;size&quot;, ImageSize.SMALL.getSize());
    return body;
}

private HttpHeaders commonHttpHeaders() {
    HttpHeaders headers = new HttpHeaders();
    headers.setBearerAuth(OPENAI_API_KEY);
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    return headers;
}

Incase if you have not set the timeout in RestTemplate then use httpclient library and generate RestTemplate object as following.

public RestTemplate getRestTemplate() throws KeyManagementException, NoSuchAlgorithmException {
    SSLContext sslContext = SSLContexts.custom().build();
    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).useSystemProperties().build();
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setHttpClient(httpClient);
    requestFactory.setConnectTimeout(30000);
    requestFactory.setReadTimeout(30000);
    requestFactory.setConnectionRequestTimeout(30000);
    return new RestTemplate(requestFactory);
}

huangapple
  • 本文由 发表于 2023年4月10日 20:03:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75976938.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定