带参数的get请求

Map<String, String> param = new HashMap<>();
param.put("status", status);
param.put("objectId", objectId);
restTemplate.getForEntity(url + "?status={status}&objectId={objectId}", String.class, param);

带headers的post请求

//请求头
HttpHeaders headers = new HttpHeaders();
headers.add("AppToken", AppToken);
headers.setContentType(MediaType.APPLICATION_JSON);
//参数
Map param = new HashMap();
param.put("projectId", Long.valueOf(projectId));
param.put("moldClampingStatus", moldClampingStatus);
param.put("sendMsg", sendMsg);
param.put("errorMsg", errorMsg);
HttpEntity httpEntity = new HttpEntity<>(JSON.toJSONString(param), headers);
restTemplate.postForObject(baseUrl + sendModelClampingStatusUrl, httpEntity, String.class);

带headers的get请求

//请求头
HttpHeaders headers = new HttpHeaders();
headers.add("AppToken", AppToken);

//封装请求头
HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<MultiValueMap<String, Object>>(headers);

ResponseEntity res = restTemplate.exchange(baseUrl + authenticateUrl + "?token="+ token + "&projectId=" + projectId, HttpMethod.GET, formEntity, Map.class);
Map body = (Map) res.getBody();

解决中文乱码问题

更换默认的StringHttpMessageConverterString转换器

HttpHeaders httpHeaders = new HttpHeaders();
HttpEntity<Object> httpEntity = new HttpEntity<>(null, httpHeaders);
//自定义转换器
ArrayList<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
StringHttpMessageConverter messageConverter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
messageConverters.add(messageConverter);
//使用自定义转换器初始化RestTemplate
RestTemplate restTemplate = new RestTemplate(messageConverters);
String url = "https://www.baidu.com";
ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
System.out.println(responseEntity.getStatusCode());
String body = responseEntity.getBody();
System.out.println(body);

在restTemplate的MessageConverters集合里加入StringHttpMessageConverter

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));

解决返回XML问题

RestTemplate restTemplate =new RestTemplate();
restTemplate.getMessageConverters().clear();
restTemplate.getMessageConverters().add(new FastJsonHttpMessageConverter());

使用FileSystemResource上传文件

MultiValueMap<String, Object> resultMap = new LinkedMultiValueMap<>();
Resource resource = new FileSystemResource(file);
param.put("file", resource);

// 实例
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);

MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
Resource resource = new FileSystemResource(sourceFile);
param.add("file", resource);
param.add("fileName", fileName);

HttpEntity httpEntity = new HttpEntity<>(param, headers);
ResponseEntity<Boolean> result = restTemplate.postForEntity(url, httpEntity, Boolean.class);

上传文件过大时解决内存溢出

@Bean
public RestTemplate restTemplate() {
    SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    requestFactory.setBufferRequestBody(false);
    RestTemplate rest = new RestTemplate(requestFactory);
    return rest;
}
该代码的意思是请求工厂类是否应用绣冲请求正文内部,默认值为tue,当post或者put大文件的时候会造成内存溢出情况,设置为false将数据直接流入底层HttpURLConnection。

使用InputStreamResource上传文件

MultiValueMap<String, Object> resultMap = new LinkedMultiValueMap<>();
Resource resource = new InputStreamResource(inputStream);
param.put("file", resource);

// 使用InputStreamResource上传文件时,需要重写该类的两个方法,contentLength和getFilename。
public class CommonInputStreamResource extends InputStreamResource {
    private int length;

    public CommonInputStreamResource(InputStream inputStream) {
        super(inputStream);
    }

    public CommonInputStreamResource(InputStream inputStream, int length) {
        super(inputStream);
        this.length = length;
    }

    /**
     * 覆写父类方法
     * 如果不重写这个方法,并且文件有一定大小,那么服务端会出现异常
     * {@code The multi-part request contained parameter data (excluding uploaded files) that exceeded}
     *
     * @return
     */
    @Override
    public String getFilename() {
        return "temp";
    }

    /**
     * 覆写父类 contentLength 方法
     * 因为 {@link org.springframework.core.io.AbstractResource#contentLength()}方法会重新读取一遍文件,
     * 而上传文件时,restTemplate 会通过这个方法获取大小。然后当真正需要读取内容的时候,发现已经读完,会报如下错误。
     * <code>
     * java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
     * at org.springframework.core.io.InputStreamResource.getInputStream(InputStreamResource.java:96)
     * </code>
     * <p>
     * ref:com.amazonaws.services.s3.model.S3ObjectInputStream#available()
     *
     * @return
     */
    @Override
    public long contentLength() {
        int estimate = length;
        return estimate == 0 ? 1 : estimate;
    }
}
最后修改:2023 年 07 月 20 日
如果觉得我的文章对你有用,请随意赞赏