如何使用Spring RestTemplate发布表单数据?


147

我想将以下(工作)curl代码段转换为RestTemplate调用:

curl -i -X POST -d "email=first.last@example.com" https://app.example.com/hr/email

如何正确传递email参数?以下代码导致404 Not Found响应:

String url = "https://app.example.com/hr/email";

Map<String, String> params = new HashMap<String, String>();
params.put("email", "first.last@example.com");

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity( url, params, String.class );

我试图在PostMan中制定正确的调用,并且可以通过在主体中将email参数指定为“ form-data”参数来使其正常工作。在RestTemplate中实现此功能的正确方法是什么?


尝试restTemplate.exchange();
我们是博格

您在此处提供的网址的可接受的内容类型是什么?
Tharsan Sivakumar

看看这个博客正试图做同样的事情,我想techie-mixture.blogspot.com/2016/07/...
Tharsan西瓦库玛

@TharsanSivakumar网址将返回JSON。
sim

Answers:


355

POST方法应沿着HTTP请求对象发送。并且该请求可以包含HTTP标头或HTTP正文或两者。

因此,让我们创建一个HTTP实体并在正文中发送标头和参数。

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
map.add("email", "first.last@example.com");

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);

ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class );

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#postForObject-java.lang.String-java.lang.Object-java.lang。类-java.lang.Object ...-


1
你可以参考以下链接以及更多信息techie-mixture.blogspot.com/2016/07/...
Tharsan西瓦库玛

1
您保存了我的一天,我希望使用resttemplate很明显,但是有一些技巧!
Sergii Getman'1

1
ResponseEntity<String> response = new RestTemplate().postForEntity(url, request, String.class);我得到了org.springframework.http.converter.HttpMessageNotWritableExc‌​eption: Could not write content: No serializer found for class java.util.Collections$3
Shivkumar Mallesappa '17

当其他人是字符串但其中一个是String []类型时如何传递主体参数,如下面的请求数据args是String的数组curl -X POST --data '{"file": "/xyz.jar", "className": "my.class.name", "args": ["100"]}' -H "Content-Type: application/json" localhost:1234/batches
khawarizmi,

2
因此,这仅适用于字符串...如果要在有效载荷中发送Java对象怎么办?
devssh

23

如何发布混合数据:File,String [],一个请求中的String。

您只能使用所需的东西。

private String doPOST(File file, String[] array, String name) {
    RestTemplate restTemplate = new RestTemplate(true);

    //add file
    LinkedMultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
    params.add("file", new FileSystemResource(file));

    //add array
    UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("https://my_url");
    for (String item : array) {
        builder.queryParam("array", item);
    }

    //add some String
    builder.queryParam("name", name);

    //another staff
    String result = "";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity =
            new HttpEntity<>(params, headers);

    ResponseEntity<String> responseEntity = restTemplate.exchange(
            builder.build().encode().toUri(),
            HttpMethod.POST,
            requestEntity,
            String.class);

    HttpStatus statusCode = responseEntity.getStatusCode();
    if (statusCode == HttpStatus.ACCEPTED) {
        result = responseEntity.getBody();
    }
    return result;
}

POST请求的正文和下一个结构中将包含File:

POST https://my_url?array=your_value1&array=your_value2&name=bob 

我尝试了这种方法,但对我不起作用。我面临用多部分格式的数据发出POST请求的问题。我的问题是,如果你能引导我一个解决方案stackoverflow.com/questions/54429549/...
深Lathia

8

这是使用spring的RestTemplate进行POST调用的完整程序。

import java.util.HashMap;
import java.util.Map;

import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import com.ituple.common.dto.ServiceResponse;

   public class PostRequestMain {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
        Map map = new HashMap<String, String>();
        map.put("Content-Type", "application/json");

        headers.setAll(map);

        Map req_payload = new HashMap();
        req_payload.put("name", "piyush");

        HttpEntity<?> request = new HttpEntity<>(req_payload, headers);
        String url = "http://localhost:8080/xxx/xxx/";

        ResponseEntity<?> response = new RestTemplate().postForEntity(url, request, String.class);
        ServiceResponse entityResponse = (ServiceResponse) response.getBody();
        System.out.println(entityResponse.getData());
    }

}

7
那发布了application / json而不是表单数据
MaciejStępyra17年

ResponseEntity<?> response = new RestTemplate().postForEntity(url, request, String.class);。我得到org.springframework.http.converter.HttpMessageNotWritableException: Could not write content: No serializer found for class java.util.Collections$3
Shivkumar Mallesappa,

您能否分享您的整个程序,或者让我知道,我将分享一些示例示例程序@ShivkumarMallesappa
Piyush Mittal,

如果您用替换application/json内容类型,application/x-www-form-urlencoded则会得到org.springframework.web.client.RestClientException:java.util.HashMap的HttpMessageConverter和内容类型为“ application / x-www-form-urlencoded” -请参见stackoverflow.com/q / 31342841/355438
Lu55

-3

您的url字符串需要为传递给您的地图使用可变标记,例如:

String url = "https://app.example.com/hr/email?{email}";

或者,您可以将查询参数明确地编码为String开头,而不必完全传递映射,例如:

String url = "https://app.example.com/hr/email?email=first.last@example.com";

另请参阅https://stackoverflow.com/a/47045624/1357094

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.