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

Posted

技术标签:

【中文标题】如何使用 Spring RestTemplate 发布表单数据?【英文标题】:How to POST form data with Spring RestTemplate? 【发布时间】:2016-11-17 06:22:40 【问题描述】:

我想将以下(工作)curl sn-p 转换为 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 中制定正确的调用,我可以通过将电子邮件参数指定为正文中的“表单数据”参数来使其正常工作。在 RestTemplate 中实现此功能的正确方法是什么?

【问题讨论】:

试试restTemplate.exchange(); 您在此处提供的 url 可接受的内容类型是什么? 看看这个博客,我猜它正在尝试做同样的事情techie-mixture.blogspot.com/2016/07/… @TharsanSivakumar 该网址将返回 JSON。 RestTemplate uriVariables not expanded的可能重复 【参考方案1】:

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.Class-java.lang.Object...-

【讨论】:

您也可以参考此链接以获取更多信息techie-mixture.blogspot.com/2016/07/… ResponseEntity&lt;String&gt; 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 当其他是String但其中一个是String[]类型时如何传递body参数,如下所示请求数据args是一个String数组curl -X POST --data '"file": "/xyz.jar", "className": "my.class.name", "args": ["100"]' -H "Content-Type: application/json" localhost:1234/batches 任何服务器端 sn-p 可用于此? 所以这只适用于字符串......如果我想在有效负载中发送一个java对象怎么办?【参考方案2】:

如何在一个请求中发布混合数据:文件、字符串[]、字符串。

你只能使用你需要的东西。

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 请求的正文和下一个结构中包含文件:

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

【讨论】:

我尝试了这种方法,但对我不起作用。我在使用多部分格式的数据发出 POST 请求时遇到问题。这是我的问题,如果你能指导我解决方案***.com/questions/54429549/…【参考方案3】:

这是使用 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());
    


【讨论】:

发布 application/json 而不是表单数据 ResponseEntity&lt;?&gt; 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 能否请您分享您的整个程序或让我知道我将分享一些示例示例程序@ShivkumarMallesappa 如果你用 application/x-www-form-urlencoded 替换 application/json 内容类型,你会得到 org.springframework.web.client.RestClientException: No HttpMessageConverter for java.util.HashMap and content type " application/x-www-form-urlencoded" - 见***.com/q/31342841/355438【参考方案4】:

客户端.java

@PostMapping(value = "/employee", consumes = "application/json")
public Employee createProducts(@RequestBody Employee product) 
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    HttpEntity<Employee> entity = new HttpEntity<Employee>(product,headers);

    ResponseEntity<Employee> response = restTemplate.exchange(
            "http://hello-server/rest/employee", HttpMethod.POST, entity, Employee.class);

    return response.getBody();

服务器.java

private static List<Employee> list = new ArrayList<>();

@PostMapping(path="rest/employee", consumes = "application/json")
public Employee createEmployee(@RequestBody Employee employee)


    list.add(employee);
    return employee;

static

    list.add(new Employee(1, "albert", "Associate", "mphasis"));
    list.add(new Employee(2, "sachin", "software engineer", "mphasis"));
    list.add(new Employee(3, "dhilip", "Lead engineer", "IBM"));

Employee.java

public class Employee 

private Integer id;
private String name;
private String Designation;
private String company;
 // generate getter setter and toString()

1. 发帖请求

【讨论】:

以上是关于如何使用 Spring RestTemplate 发布表单数据?的主要内容,如果未能解决你的问题,请参考以下文章

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

如何在 Spring RestTemplate 中记录响应?

如何在 Spring RestTemplate 请求上设置“Accept:”标头?

如何使用 Spring RestTemplate 使用 Page<Entity> 响应

如何使用 RestTemplate 在 Spring MVC 应用程序中访问来自(来自 Spring RESTful 服务)的巨大 JSON

Spring Boot:如何使用 WebClient 而不是 RestTemplate 来执行非阻塞和异步调用