restTemplate 发送post请求

夹谷阳夏
2023-12-01
        <!--jackson 依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>

package com.atguli.common.demo;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;

/**
 * User: ldj
 * Date: 2022/3/25
 * Time: 1:30
 * Description: restTemplate
 */
@Slf4j
public class RestTemplateDemo {
    public static void main(String[] args) throws JsonProcessingException {

        String url = "http://locahost:8080/test";
        
        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        
        ArrayList<Object> similarList = new ArrayList<>();
        similarList.add("1");
        similarList.add("2");
        similarList.add("3");

        JSONObject requestMap = new JSONObject();
        requestMap.put("name", "ldj");
        requestMap.put("age", "15");
        requestMap.put("similarList",similarList);

        HttpEntity<JSONObject> entity = new HttpEntity<>(requestMap, headers);

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            String similarJSON = objectMapper.writeValueAsString(requestMap);
            log.info("similarJSON:{}",similarJSON);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //使用JSONObject,不需要创建实体类VO来接受返参,缺点是别人不知道里面有哪些字段,即不知道有那些key
        JSONObject body1 = restTemplate.postForObject(url, entity, JSONObject.class);
        log.info("body1:{}",objectMapper.writeValueAsString(body1));

        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(url, requestMap, JSONObject.class);
        JSONObject body2 = responseEntity.getBody(); //响应体
        HttpStatus statusCode = responseEntity.getStatusCode(); //状态码
        HttpHeaders headers1 = responseEntity.getHeaders();//获取到头信息
    }
}
package com.jt;

import com.jt.model.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.*;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: ldj
 * @Date: 2022/06/24/11:32
 * @Description:
 */

@Slf4j
@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class RestTemplateTest {

    @Autowired
    private RestTemplate restTemplate;

    public void test() {
        String url = "http://localhost:8089/UserController/test";

        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("id", 145515555);
        requestMap.put("name", "ldj");

        UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(url);

        //拼接url参数 "http://localhost:8089/UserController/test?id=145515555&name=ldj"
        requestMap.forEach(uriComponentsBuilder::queryParam);

        URI uri = uriComponentsBuilder.build().encode(StandardCharsets.UTF_8).toUri();

        //1.请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        //httpHeaders.setContentType(MediaType.valueOf(MediaType.APPLICATION_JSON_UTF8_VALUE));
        httpHeaders.setContentType(MediaType.parseMediaType("application/json; charset=UTF-8"));
        httpHeaders.add("Accept", MediaType.APPLICATION_JSON.toString());

        //2.请求体
        HttpEntity<Void> httpEntity = new HttpEntity<>(null, httpHeaders);

        //3.响应体
        ResponseEntity<UserDTO> responseEntity = null;

        //4.发送get请求
        try {
            responseEntity = restTemplate.exchange(uri.toString(), HttpMethod.GET, httpEntity, UserDTO.class);
        } catch (RestClientException e) {
            log.error("[RestTemplateTest-test] http request error", e);
        }
        
        //5.数据处理
        if (Objects.nonNull(responseEntity)) {
            UserDTO body = responseEntity.getBody();
            if (Objects.isNull(body)) {
                log.info("返回错误的响应的状态码");
            } else {
                String status = body.getStatus();
                if (!Objects.equals("2000", status)) {
                    log.info("返回错误的响应的状态码");
                }

                //数据进行业务处理 略
            }
        }
        
        //===============================================================================   
        //4.发送post请求
        RequestEntity<Map<String,Object>> requestEntity = RequestEntity
                .post(uri)
                .header("Accept", MediaType.APPLICATION_JSON.toString())
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.APPLICATION_JSON)
                .body(new LinkedMultiValueMap<>()); //也可以是DTO

        try {
            responseEntity = restTemplate.exchange(requestEntity,UserDTO.class);
        } catch (RestClientException e) {
            log.error("[RestTemplateTest-test] http request error", e);
        }
    }
}

后续补充:向阿里云发送post请求获取短信验证码测试

 配置restTemplate   

package com.atguli.common.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * User: ldj
 * Date: 2022/9/1
 * Time: 5:00
 * Description: No Description
 */
@RefreshScope //动态加载配置文件(可不加)
@Configuration
public class RestTemplateConfig {

    //连接超时时间,当配置文件没设定时间时,默认6000ms
    @Value("${resttemplate.parameter.connectTimeout:6000}")
    private Integer connectTimeout;

    //读取超时时间,当配置文件没设定时间时,默认6000ms
    @Value("${resttemplate.parameter.readTimeout:6000}")
    private Integer readTimeout;

    @Bean
    //@LoadBalanced //客户端对服务器的负载均衡
    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
        return new RestTemplate(factory);
    }

    @Bean
    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setReadTimeout(readTimeout);
        factory.setConnectTimeout(connectTimeout);
        return factory;
    }
}

配置Jackson序列化与反序列化规则

package com.atguli.common.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

/**
 * User: ldj
 * Date: 2022/7/23
 * Time: 20:50
 * Description: No Description
 */

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder)
    {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        SimpleModule simpleModule = new SimpleModule();
        //Long -> String 解决返回前端id是Long类型精度降低,后位数变成0 配置注解 @JsonSerialize(using = ToStringSerializer.class)使用
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);

        // Include.Include.ALWAYS 默认
        // Include.NON_DEFAULT 属性为默认值不序列化
        // Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,忽略该字段
        // Include.NON_NULL  属性为NULL 不序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

        // 允许出现单引号
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        return objectMapper;
    }
}

如果报错:java.lang.IllegalStateException: No instances available for dfsns.market.alicloudapi.com

at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute

@LoadBalanced 的作用是负载均衡,使用ip地址访问,无法起到负载均衡的作用,因为每次都是调用同一个服务 ;注释掉配置类//@LoadBalanced 


import com.aliyun.oss.OSSClient;
import com.atguli.common.config.RestTemplateConfig;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.nio.charset.StandardCharsets;

@Slf4j
@Import(value = {RestTemplateConfig.class, JacksonConfig.class})
@RunWith(SpringRunner.class)
@SpringBootTest
public class ThirdPartyApplicationTests {
    
    @Autowired
    private RestTemplate restTemplate;


    @Autowired
    private ObjectMapper objectMapper;
    
    @Test
    public void smsTest() {
        //4.发送post请求
        String url = "http://dfsns.market.alicloudapi.com/data/send_sms";
        String appCode = "APPCODE 65ed5499417944f1ad101a12014a80c9";
        UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = uriComponentsBuilder.build().encode(StandardCharsets.UTF_8).toUri();

        //1.请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("Authorization", appCode);
        httpHeaders.setContentType(MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE));

        MultiValueMap<String, String> requestMap = new LinkedMultiValueMap<>();
        requestMap.add("content", "code:6666");
        requestMap.add("phone_number", "填写真正的手机号码");
        requestMap.add("template_id", "TPL_0000");

        RequestEntity<MultiValueMap<String, String>> requestEntity = RequestEntity
                .post(uri)
                .headers(httpHeaders)
                .body(requestMap);

        ResponseEntity<Response> responseEntity;
        try {
            responseEntity = restTemplate.exchange(requestEntity, Response.class);
            //log.info(Objects.requireNonNull(responseEntity.getBody()).toString());
            log.info(objectMapper.writeValueAsString(responseEntity.getBody()));
        } catch (RestClientException e) {
            log.error("[RestTemplateTest-test] http request error", e);
        }

    }

    @Data
    //局部起作用注解,JacksonConfig是全局起作用,本测试不做全局配置,使用一个注解就可以
    @JsonInclude(value= JsonInclude.Include.NON_NULL)
    public static class Response {

        private String status;

        private String request_id;

        private String reason;
    }
    
}

 类似资料: