RestTemplat发送HTTP请求

RestTemplate 是一个 spring-web 提供的执行HTTP请求的同步阻塞式工具类。
RestTemplate默认是使用SimpleClientHttpRequestFactory,内部是调用jdk的HttpConnection,默认超时为-1

1. 添加 Maven 坐标

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

2. RestTemplate 配置

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.TimeUnit;

@Configuration
public class RestTemplateConfig {

    /**
     * 没有实例化RestTemplate时,初始化RestTemplate
     * RestTemplate默认是使用SimpleClientHttpRequestFactory,
     * 内部是调用jdk的HttpConnection,默认超时为-1
     * @return
     */
    @ConditionalOnMissingBean(RestTemplate.class)
    @Bean
    public RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }

    /**
     * 使用HttpClient作为底层客户端
     * @return
     */
//    private ClientHttpRequestFactory getClientHttpRequestFactory() {
//        int timeout = 5000;
//        RequestConfig config = RequestConfig.custom()
//                .setConnectTimeout(timeout)
//                .setConnectionRequestTimeout(timeout)
//                .setSocketTimeout(timeout)
//                .build();
//        CloseableHttpClient client = HttpClientBuilder
//                .create()
//                .setDefaultRequestConfig(config)
//                .build();
//        return new HttpComponentsClientHttpRequestFactory(client);
//    }


    /**
     * 使用OkHttpClient作为底层客户端
     * @return
     */
//    private ClientHttpRequestFactory getClientHttpRequestFactory(){
//        OkHttpClient okHttpClient = new OkHttpClient.Builder()
//                .connectTimeout(5, TimeUnit.SECONDS)
//                .writeTimeout(5, TimeUnit.SECONDS)
//                .readTimeout(5, TimeUnit.SECONDS)
//                .build();
//        return new OkHttp3ClientHttpRequestFactory(okHttpClient);
//    }

}

3. 请求测试接口 TestController,FileController

TestController

import com.alibaba.fastjson.JSON;
import com.example.demo.req.UserReq;
import com.example.demo.res.GlobalResult;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

@Controller
public class TestController {

    /**
     * 无参get请求
     * @return
     */
    @RequestMapping(value = "testGet", method = RequestMethod.GET)
    @ResponseBody
    public GlobalResult testGet(){
        GlobalResult result = new GlobalResult();
        result.setCode("200");
        result.setMsg("success,method:testGet");
        return result;
    }

    /**
     * 带参的get请求
     * @return
     */
    @RequestMapping(value = "testGet2/{id}/{name}", method = RequestMethod.GET)
    @ResponseBody
    public GlobalResult testGetByRestFul(@PathVariable(value = "id") String id, @PathVariable(value = "name") String name){
        GlobalResult result = new GlobalResult();
        result.setCode("200");
        result.setMsg(String.format("success,method:testGet2,id:%s name:%s", id, name));
        return result;
    }

    /**
     * 带参的get请求
     * 占位符号传参
     * @return
     */
    @RequestMapping(value = "testGetByParam", method = RequestMethod.GET)
    @ResponseBody
    public GlobalResult testGetByParam(@RequestParam("userName") String userName,
                                       @RequestParam("userPwd") String userPwd){
        GlobalResult result = new GlobalResult();
        result.setCode("200");
        result.setMsg(String.format("success,method:testGetByParam,userName:%s,userPwd:%s",  userName , userPwd));
        return result;
    }


    /**
     * post表单请求
     * @return
     */
    @RequestMapping(value = "testPostByForm", method = RequestMethod.POST)
    @ResponseBody
    public GlobalResult testPostByForm(@RequestParam("userName") String userName,
                                       @RequestParam("userPwd") String userPwd){
        GlobalResult result = new GlobalResult();
        result.setCode("200");
        result.setMsg(String.format("success,method:testPostByForm,userName:%s,userPwd:%s",  userName , userPwd));
        return result;
    }


    /**
     * post表单请求
     * @param userReq
     * @return
     */
    @RequestMapping(value = "testPostByFormAndObj", method = RequestMethod.POST)
    @ResponseBody
    public GlobalResult testPostByForm(UserReq userReq){
        GlobalResult result = new GlobalResult();
        result.setCode("200");
        result.setMsg(String.format("success,method:testPostByFormAndObj,json:%s",  JSON.toJSONString(userReq)));
        return result;
    }

    /**
     * post请求 JSON
     * @param userReq
     * @return
     */
    @RequestMapping(value = "testPostByJson", method = RequestMethod.POST)
    @ResponseBody
    public GlobalResult testPostByJson(@RequestBody UserReq userReq){
        GlobalResult result = new GlobalResult();
        result.setCode("200");
        result.setMsg(String.format("success,method:testPostByJson,json:%s",  JSON.toJSONString(userReq)));
        return result;
    }

    /**
     * put请求 JSON
     * @param userReq
     * @return
     */
    @RequestMapping(value = "testPutByJson", method = RequestMethod.PUT)
    @ResponseBody
    public void testPutByJson(@RequestBody UserReq userReq){
        System.out.println(String.format("success,method:testPutByJson,param:%s",  JSON.toJSONString(userReq)));
    }

    /**
     * delete请求 JSON
     * @return
     */
    @RequestMapping(value = "testDeleteByJson", method = RequestMethod.DELETE)
    @ResponseBody
    public void testDeleteByJson(){
        System.out.println("success,method:testDeleteByJson");
    }

    /**
     * 重定向
     * @param userReq
     * @return
     */
    @RequestMapping(value = "testPostByLocation", method = RequestMethod.POST)
    public String testPostByLocation(@RequestBody UserReq userReq){
        return "redirect:index.html";
    }

}

FileController

import com.example.demo.res.GlobalResult;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.UUID;

@RestController
public class FileController {

    private static final String UPLOAD_PATH = "/home/cms/file/";

    /**
     * 文件上传
     * @param uploadFile
     * @return
     */
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public GlobalResult upload(@RequestParam("uploadFile") MultipartFile uploadFile,
                               @RequestParam("userName") String userName) {
        // 在 uploadPath 文件夹中通过用户名对上传的文件归类保存
        File folder = new File(UPLOAD_PATH + userName);
        if (!folder.isDirectory()) {
            folder.mkdirs();
        }

        // 对上传的文件重命名,避免文件重名
        String oldName = uploadFile.getOriginalFilename();
        String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));

        //定义返回视图
        GlobalResult result = new GlobalResult();
        try {
            // 文件保存
            uploadFile.transferTo(new File(folder, newName));
            result.setCode("200");
            result.setMsg("文件上传成功,方法:upload,文件名:" + newName);
        } catch (IOException e) {
            e.printStackTrace();
            result.setCode("500");
            result.setMsg("文件上传失败,方法:upload,请求文件:" + oldName);
        }
        return result;
    }


    /**
     * 带参的get请求(restful风格)
     * @return
     */
    @RequestMapping(value = "downloadFile/{userName}/{fileName}", method = RequestMethod.GET)
    public void downloadFile(@PathVariable(value = "userName") String userName,
                             @PathVariable(value = "fileName") String fileName,
                             HttpServletRequest request,
                             HttpServletResponse response) throws Exception {

        File file = new File(UPLOAD_PATH + userName + File.separator + fileName);
        if (file.exists()) {
            //获取文件流
            FileInputStream fis = new FileInputStream(file);
            //获取文件后缀(.png)
            String extendFileName = fileName.substring(fileName.lastIndexOf('.'));
            //动态设置响应类型,根据前台传递文件类型设置响应类型
            response.setContentType(request.getSession().getServletContext().getMimeType(extendFileName));
            //设置响应头,attachment表示以附件的形式下载,inline表示在线打开
            response.setHeader("content-disposition","attachment;fileName=" + URLEncoder.encode(fileName,"UTF-8"));
            //获取输出流对象(用于写文件)
            OutputStream os = response.getOutputStream();
            //下载文件,使用spring框架中的FileCopyUtils工具
            FileCopyUtils.copy(fis,os);
        }
    }

}

用户请求参数对象 UserReq, 全局返回对象 GlobalResult

public class UserReq {

    private String userName;

    private String userPwd;

    //GET and SET  and  toString()
}
public class GlobalResult {

    private String code;

    private String msg;

    //GET and SET  and  toString()
}

4. RestTemplate使用示例

import com.example.demo.req.UserReq;
import com.example.demo.res.GlobalResult;
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.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestTemplate;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

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

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 不带参的get请求
     */
    @Test
    public void testGet(){
        String url = "http://localhost:8080/testGet";
        //发起请求
        GlobalResult responseBean = restTemplate.getForObject(url, GlobalResult.class);
        System.out.println(responseBean.toString());
    }

    /**
     * 带参的get请求
     */
    @Test
    public void testGet2(){
        String url = "http://localhost:8080/testGet2/{1}/{2}";
        //发起请求
        GlobalResult responseBean = restTemplate.getForObject(url, GlobalResult.class, "001", "张三");
        System.out.println(responseBean.toString());
    }

    /**
     * 带参的get请求
     */
    @Test
    public void testGetByParam(){
        String url = "http://localhost:8080/testGetByParam?userName={userName}&userPwd={userPwd}";
        //请求参数
        Map<String, String> uriVariables = new HashMap<>();
        uriVariables.put("userName", "张三");
        uriVariables.put("userPwd", "123456");
        //发起请求(带参数请求)
        GlobalResult responseBean = restTemplate.getForObject(url, GlobalResult.class, uriVariables);
        System.out.println(responseBean.toString());
    }

    /**
     * Get全部信息
     */
    @Test
    public void testAllGet(){
        String url = "http://localhost:8080/testGet";
        //发起请求,返回全部信息
        ResponseEntity<GlobalResult> response = restTemplate.getForEntity(url, GlobalResult.class);
        // 获取响应体
        System.out.println("HTTP 响应body:" + response.getBody().toString());

        HttpStatus statusCode = response.getStatusCode();
        int statusCodeValue = response.getStatusCodeValue();
        HttpHeaders headers = response.getHeaders();
        System.out.println("HTTP 响应状态:" + statusCode);
        System.out.println("HTTP 响应状态码:" + statusCodeValue);
        System.out.println("HTTP Headers信息:" + headers);
    }


    /**
     * post表单提交
     */
    @Test
    public void testPostByForm(){
        String url = "http://localhost:8080/testPostByForm";
        // 设置请求头,x-www-form-urlencoded格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //设置提交参数
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("userName", "张三");
        map.add("userPwd", "123456");
        // 组装请求体
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
        //发起请求
        GlobalResult responseBean = restTemplate.postForObject(url, request, GlobalResult.class);
        System.out.println(responseBean.toString());
    }


    /**
     * post表单提交
     */
    @Test
    public void testPostByForm2(){
        String url = "http://localhost:8080/testPostByFormAndObj";
        // 设置请求头,x-www-form-urlencoded格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //设置提交参数
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("userName", "张三");
        map.add("userPwd", "123456");
        // 组装请求体
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
        //发起请求
        GlobalResult responseBean = restTemplate.postForObject(url, request, GlobalResult.class);
        System.out.println(responseBean.toString());
    }

    /**
     * post请求JSON格式
     */
    @Test
    public void testPostByJson(){
        String url = "http://localhost:8080/testPostByJson";
        UserReq request = new UserReq();
        request.setUserName("张三");
        request.setUserPwd("123456");
        //String类型接收响应结果JSON字符串
        GlobalResult responseBean = restTemplate.postForObject(url, request, GlobalResult.class);
        System.out.println(responseBean.toString());
    }

    /**
     * put请求JSON格式
     */
    @Test
    public void testPutByJson(){
        String url = "http://localhost:8080/testPutByJson";
        UserReq userReq = new UserReq();
        userReq.setUserName("张三");
        userReq.setUserPwd("123456789");
        //put请求
        restTemplate.put(url, userReq);
    }


    /**
     * delete请求
     */
    @Test
    public void testDeleteByJson(){
        String url = "http://localhost:8080/testDeleteByJson";
        //delete请求
        restTemplate.delete(url);
    }

    /**
     * 重定向,post请求
     */
    @Test
    public void testPostByLocation(){
        String url = "http://localhost:8080/testPostByLocation";
        UserReq request = new UserReq();
        request.setUserName("张三");
        request.setUserPwd("123456789");
        //返回跳转url
        String s = restTemplate.postForObject(url, request, String.class);
        System.out.println(s);
        URI uri = restTemplate.postForLocation(url, request);
        System.out.println(uri.toString());
    }


    /**
     * 文件上传,post请求
     */
    @Test
    public void upload(){
        //需要上传的文件
        String filePath = "/home/file/Downloads/test.jpg";
        //请求地址
        String url = "http://localhost:8080/upload";
        // 设置请求头,multipart/form-data格式的数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        //设置参数
        MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
        param.add("uploadFile", new FileSystemResource(new File(filePath)));
        //服务端如果接受额外参数,可以传递
        param.add("userName", "张三");
        // 请求体
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(param, headers);
        //发起请求
        GlobalResult responseBean = restTemplate.postForObject(url, request, GlobalResult.class);
        System.out.println(responseBean.toString());
    }


    /**
     * 小文件下载
     * @throws IOException
     */
    @Test
    public void downloadFile() throws IOException {
        String userName = "张三";
        String fileName = "b4f9fabb-213f-4017-aaa0-9470de31864e.jpg";
        //请求地址
        String url = "http://localhost:8080/downloadFile/{1}/{2}";
        //发起请求
        ResponseEntity<byte[]> rsp = restTemplate.getForEntity(url, byte[].class, userName,fileName);
        System.out.println("文件下载请求结果状态码:" + rsp.getStatusCode());
        // 保存到本地
        String targetPath = "/home/file/Downloads/"  + fileName;
        Files.write(Paths.get(targetPath), Objects.requireNonNull(rsp.getBody(), "未获取到下载文件"));
    }

    /**
     * 大文件下载
     * @throws IOException
     */
    @Test
    public void downloadBigFile() throws IOException {
        String userName = "张三";
        String fileName = "b4f9fabb-213f-4017-aaa0-9470de31864e.jpg";
        //请求地址
        String url = "http://localhost:8080/downloadFile/{1}/{2}";
        //定义请求头的接收类型
        RequestCallback requestCallback = request -> request.getHeaders()
                .setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
        //对响应进行流式处理而不是将其全部加载到内存中
        String targetPath = "/home/file/Downloads/"  + fileName;
        restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {
            Files.copy(clientHttpResponse.getBody(), Paths.get(targetPath));
            return null;
        }, userName, fileName);
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
"Content type 'application/xml;charset=UTF-8' not supported"报错表示请求的内容类型不被支持。根据引用和引用的信息,可以看出,在发送POST请求时,使用了错误的内容类型。根据引用中的正确示例,可以通过设置正确的请求头来解决这个问题。正确的做法是设置请求头的Content-Type为"application/json;charset=UTF-8",并将其添加到HttpHeaders中,然后将HttpHeaders对象作为参数传递给HttpEntity。最后,将HttpEntity作为参数传递给restTemplate.postForObject方法来发送请求。这样就可以正确地发送POST请求并得到预期的响应数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [restTemplat发post请求报错Content type ‘application/xml;charset=UTF-8‘ not supported](https://blog.csdn.net/baidu_21349635/article/details/120756529)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [RestTemplate远程调用报错:Content type ‘application/xml;charset=UTF-8‘ not supported](https://blog.csdn.net/manba_out/article/details/121022258)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值