• SpringBoot-调用外部接口(三种方式)


    方式一:使用原始httpClient请求

    @RequestMapping("/submit/{documentId}")
    public String submit1(@PathVariable String documentId) throws ParseException {
    
    	//将要发送的数据转换为json格式字符串
    	Map<String,Object> map = task2Service.getMap(documentId);
    	String jsonStr = JSON.toJSONString(map,SerializerFeature.WRITE_MAP_NULL_FEATURES,SerializerFeature.QuoteFieldNames);
    	JSONObject jsonObject = JSON.parseObject(jsonStr);
    	JSONObject sr = task2Service.doPost(jsonObject);
    	return sr.toString();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    使用原生的httpClient调用外部接口

    public static JSONObject doPost(JSONObject date){
    
    	String assessToken="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ";
    	CloseableHttpClient client = HttpClients.createDefault();
    
    	//需要调用的接口url
    	 String url = "http://39.103.201.110:30661 /xdap-open/open/process/v1/submit";
    	 HttpPost post = new HttpPost(url);
    
    	JSONObject jsonObject = null;
    	try{
    		//创建请求体并添加数据
    		StringEntity s = new StringEntity(data.toString());
    		
    		//此处相当于在header里头添加content-type等参数
            s.setContentType("application/json");
            s.setContentEncoding("UTF-8");
    
    		post.setEntity(s);
    
    		//此处相当于在Authorization里头添加Bear token参数信息
            post.addHeader("Authorization", "Bearer " +assessToken);
            HttpResponse res = client.execute(post);
            String response1 = EntityUtils.toString(res.getEntity());
            if (res.getStatusLine()
                    .getStatusCode() == HttpStatus.SC_OK) {
                // 返回json格式:
                String result = EntityUtils.toString(res.getEntity());
                jsonObject = JSONObject.parseObject(result);
            }
    	}catch(Exception e){
    		throw new RuntimeException(e);
    	}
    	return jsonObject;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    使用了map转String,使用了JSON,这里引入JSON包

    <dependency>
          <groupId>com.alibaba.fastjson2groupId>
          <artifactId>fastjson2artifactId>
          <version>2.0.25version>    
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    服务端代码

    
    @RestController
    public class SysUserController {
    
        @PostMapping(value = "/sysUser/saveUser")
        public String saveUser(@RequestBody Map map) {
            return "人员新增成功";
        }
    
        @GetMapping(value = "/sysUser/getSysUserById")
        public String getSysUserById(String userId) {
            return "郭郭";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    public class TestHttpClient{
    	
    	@Test
    	public void doGet() throws IOException{
    		
    		//创建httpClient实例
    		CloseableHttpClient httpClient = HttpClients.createDefault();
    
    		//创建Http请求
    		HttpGet httpGet = new HttpGet("http://127.0.0.1:8094/masterdata/sysUser/getSysUserById?userId=郭郭");
    		
    		//发送请求并获取响应数据
    		CloseableHttpResponse response = httpClient.execute(httpGet);
    
    		//处理响应数据
    		HttpEntity entity = response.getEntity();
    		String result = EntityUtils.toString(entity);
    
    		//关闭HttpClient和response
    		response.close();
    		httpClient.close();
    		
    	}
    
    	@Test
    	public void doPost() throws IOException {
    		
    		//步骤一:创建httpClient实例
            CloseableHttpClient httpClient = HttpClients.createDefault();
            //步骤二:创建HTTP请求
            HttpPost httpPost = new HttpPost("http://127.0.0.1:8094/masterdata/sysUser/saveUser");
            //步骤三:设置请求体数据,使用JSON格式
            Map map = new HashMap<>();
            map.put("name", "郭郭");
            String requestBody = JSON.toJSONString(map);
            StringEntity stringEntity = new StringEntity(requestBody, "UTF-8");
            stringEntity.setContentType("application/json");
            httpPost.setEntity(stringEntity);
            
            //步骤四:发送请求并获取响应数据
            CloseableHttpResponse response = httpClient.execute(httpPost);
            //步骤五:处理响应数据
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);
            //步骤五:关闭httpClient和response
            response.close();
            httpClient.close();
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    方式二:使用RestTemplate方法

    get请求

    提供了getForObject、getForEntity两种方式,其中getForEntity如下三种方法的实现:

    Get–getForEntity,存在以下两种方式重载

    
    getForEntity(Stringurl,Class responseType,Object…urlVariables)
    getForEntity(URI url,Class responseType)
    
    • 1
    • 2
    • 3

    Get–getForEntity(URI url,Class responseType)

    
    //该方法使用URI对象来替代之前的url和urlVariables参数来指定访问地址和参数绑定。URI是JDK java.net包下的一个类,表示一个统一资源标识符(Uniform Resource Identifier)引用。参考如下:
    RestTemplate restTemplate=new RestTemplate();
    UriComponents 
    uriComponents=UriComponentsBuilder.fromUriString("http://USER-SERVICE/user?name={name}")
    .build()
    .expand("dodo")
    .encode();
    URI uri=uriComponents.toUri();
    ResponseEntityresponseEntity=restTemplate.getForEntity(uri,String.class).getBody();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Get–getForEntity(Stringurl,Class responseType,Object…urlVariables)

    //该方法提供了三个参数,其中url为请求的地址,responseType为请求响应body的包装类型,urlVariables为url中的参数绑定,该方法的参考调用如下:
    // http://USER-SERVICE/user?name={name)
    RestTemplate restTemplate=new RestTemplate();
    Mapparams=new HashMap<>();
    params.put("name","dada"); //
    ResponseEntityresponseEntity=restTemplate.getForEntity("http://USERSERVICE/user?name={name}",String.class,params);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Get–getForObject,存在以下三种方式重载

    getForObject(String url,Class responseType,Object...urlVariables)
    getForObject(String url,Class responseType,Map urlVariables)
    getForObject(URI url,Class responseType)
    
    • 1
    • 2
    • 3

    getForObject方法可以理解为对getForEntity的进一步封装,它通过HttpMessageConverterExtractor对HTTP的请求响应体body内容进行对象转换,实现请求直接返回包装好的对象内容。

    Post请求

    Post请求提供有postForEntity、postForObject和postForLocation三种方式,其中每种方式都有三种方法,下面介绍postForEntity的使用方法。

    Post–postForEntity,存在以下三种方式重载

    postForEntity(String url,Object request,Class responseType,Object...  uriVariables) 
    postForEntity(String url,Object request,Class responseType,Map  uriVariables) 
    postForEntity(URI url,Object request,Class responseType)
    
    • 1
    • 2
    • 3
    /**
    	第二种重载方式
    */
    @PostMapping("/submit2")
    public Object insertFinanceCompensation(@RequestBody JSONObject jsonObject) {
        String documentId=jsonObject.get("documentId").toString();
        return task2Service.submit(documentId);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    public String submit(String documentId){
        String assessToken="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ";
        RestTemplate restTemplate = new RestTemplate();
        //创建请求头
        HttpHeaders httpHeaders = new HttpHeaders();
        //此处相当于在Authorization里头添加Bear token参数信息
        httpHeaders.add(HttpHeaders.AUTHORIZATION, "Bearer " + assessToken);
        //此处相当于在header里头添加content-type等参数
        httpHeaders.add(HttpHeaders.CONTENT_TYPE,"application/json");
        Map<String, Object> map = getMap(documentId);
        String jsonStr = JSON.toJSONString(map);
        //创建请求体并添加数据
        HttpEntity<Map> httpEntity = new HttpEntity<Map>(map, httpHeaders);
        String url = "http://39.103.201.110:30661/xdap-open/open/process/v1/submit";
        ResponseEntity<String> forEntity = restTemplate.postForEntity(url,httpEntity,String.class);//此处三个参数分别是请求地址、请求体以及返回参数类型
        return forEntity.toString();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    ①、引入依赖

     <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-webartifactId>
      dependency>
    
    • 1
    • 2
    • 3
    • 4

    虽然SpringBoot会自动的装配很多常见的bean,但是RestTemplate,我们需要显示的配置它。

    ②、RestTemplateConfig配置类

    @Configuration
    public class RestTemplateConfig{
    	
    	@Bean
    	public RestTemplate restTemplate(ClientHttpRequestFactory factory){
    		return RestTemplate(factory)
    	}
    
    	@Bean
    	public ClientHttpRequestFactory simpleClientHttpRequestFactory(){
    		SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    		factory.setReadTimeout(5000);
    		factory.setConnectTimeout(5000);
    		return factory;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ③、测试

    @RestController
    public class TestRestTemplate{
    	
    	@Resource
    	private RestTemplate restTemplate;
    
    	@GetMapping(value="/saveUser")
    	public void saveUser(String userId){
    	
    		String url = "http://127.0.0.1:8094/masterdata/sysUser/saveUser";
    		//参数赋值
    		Map map = new HashMap<>();
    		map.put("name","jordan");
    
    		/**
    			还可以通过HttpHeader增加一些请求头的属性,例如请求头格式,或者一些需要用户认证的信息
    			HttpHeaders httpHeaders = new HttpHeaders();
    			httpHeaders.setContentType(MediaType.APPLICATION_JSON);
    			HttpEntity httpEntity = new HttpEntity(map, httpHeaders);
    			String results = restTemplate.postForObject(url, httpEntity, String.class);
    		*/
    		String results = restTemplate.postForObject(url, map, String.class);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    外部接口

    @RestController
    public class SysUserController{
    	
    	@PostMapping(value="/sysUser/saveUser")
    	public String saveUser(@RequestBody Map map){
    		return "人员新增成功";
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方式三:使用Feign进行消费

    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-feignartifactId>
        <version>1.2.2.RELEASEversion>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    启动类上加上@EnableFeignClients

    @SpringBootApplication
    @EnableFeignClients
    @ComponentScan(basePackages = {"com.definesys.mpaas", "com.xdap.*" ,"com.xdap.*"})
    public class MobilecardApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MobilecardApplication.class, args);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    定义Controller

    
    @Autowired
    PrintService printService;
    
    @PostMapping("/outSide")
    public String test(@RequestBody TestDto testDto) {
        return printService.print(testDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Service接口以及实现类

    
    @Service
    public interface PrintService {
        public String print(TestDto testDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    public class PrintServiceImpl implements PrintService {
    
        @Override
        public String print(TestDto testDto) {
            return "模拟外部系统的接口功能"+testDto.getId();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    构建Feigin的Service

    
    //此处name需要设置不为空,url需要在.properties中设置
    @Service
    @FeignClient(url = "${outSide.url}", name = "service2")
    public interface FeignService2 {
        @RequestMapping(value = "/custom/outSide", method = RequestMethod.POST)
        @ResponseBody
        public String getMessage(@Valid @RequestBody TestDto testDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    定义Controller

    
    @Autowired
    FeignService2 feignService2;
    //测试feign调用外部接口入口
    @PostMapping("/test2")
    public String test2(@RequestBody TestDto testDto) {
        return feignService2.getMessage(testDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Postman进行测试
    在这里插入图片描述

    添加Header解决方法

    将token等信息放入Feign请求头中,主要通过重写RequestInterceptor的apply方法实现

    定义config

    
    @Configuration
    public class FeignConfig implements RequestInterceptor {
        @Override
        public void apply(RequestTemplate requestTemplate) {
            //添加token
            requestTemplate.header("token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ4ZGFwYXBwaWQiOiIzNDgxMjU4ODk2OTI2OTY1NzYiLCJleHAiOjE2NjEyMjY5MDgsImlhdCI6MTY2MTIxOTcwOCwieGRhcHRlbmFudGlkIjoiMzAwOTgxNjA1MTE0MDUyNjA5IiwieGRhcHVzZXJpZCI6IjEwMDM0NzY2MzU4MzM1OTc5NTIwMCJ9.fZAO4kJSv2rSH0RBiL1zghdko8Npmu_9ufo6Wex_TI2q9gsiLp7XaW7U9Cu7uewEOaX4DTdpbFmMPvLUtcj_sQ");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    定义Service

    
    @Service
    @FeignClient(url = "${outSide.url}",name = "feignServer", configuration = FeignDemoConfig.class)
    public interface TokenDemoClient {
        @RequestMapping(value = "/custom/outSideAddToken", method = RequestMethod.POST)
        @ResponseBody
        public String getMessage(@Valid @RequestBody TestDto testDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    定义controller

    //测试feign调用外部接口入口,加上token
    @PostMapping("/testToken")
    public String test4(@RequestBody TestDto testDto) {
        return tokenDemoClient.getMessage(testDto);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方式四:使用FeignClient

    ①、依赖

    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-openfeignartifactId>
        
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ②、启动类添加@EnableFeignClients

    @SpringBootApplication
    @EnableFeignClients
    public class DemoApplication{
    
    	 public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ③、编写Feign客户端

    @FeignClient(name="masterdata",url="${masterdata-service-url}")
    public interface ISysUserClient{
    	
    	@GetMapping(value="/masterdata/getSysUserById")
    	public Map getSysUserById(@RequetParam("userId") String userId);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    @FeignClient注解的常用属性说明:

    • name:指定Feign的名称,如果使用了注册中心,name属性会作为微服务的名称,用于服务发现
    • url:Feign调用的跳转路径,可以在配置文件中设置,多用于代码调试

    方式五:使用WebClient

    RestTemplate有可能在未来的版本中被弃用,所谓替代RestTemplate,在Spring5中引入了WebClient作为异步的非阻塞、响应式的HTTP客户端。

    ①、引入依赖

    <dependency>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-starter-webfluxartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4

    ②、服务提供者

    @RestController
    public class SysUserController{
    	
    	@PostMapping(value="/sysUser/saveUser")
    	public String saveUser(@RequestBody Map map){
    		return "人员新增成功";
    	}
    
    	@GetMapping(value="/sysUser/getSysUserById")
    	public String getSysUserById(String userId){
    		return "jordan";
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    ③、WebClient

    public class TestWebClient{
    	
    	@Test
    	public void doGet(){
    	
    		String userId = "jordan";
    		String url = "http://127.0.0.1:8094/masterdata/sysUser/getSysUserById?userId={userId}"
    		
    		Mono<String> mono = WebClient.create() //创建WebClient实例
    								.get() 
    								.uri(url,userId)
    								.retrieve() //获取响应结果
    								.bodyToMono(String.class); //将结果转换为指定类型
    		System.out.println("响应结果:" + mono.block());
    	}
    
    	@Test
    	public void doPost(){
    	
    		Map map = new HashMap<>();
    		map.put("name","jordan");
    		//接口入参是一个Map,但是需要转换为JSON格式传递,这是因为WebClient默认是使用JSON序列化的
    		String requestBody = JSON.toJSONString(map);
    		String url = "http://127.0.0.1:8094/masterdata/sysUser/saveUser";
    		
    		Mono<String> mono = WebClient.create()
    							.post()
    							.uri(url)
    							.contentType(MediaType.APPLICATION_JSON) //指定请求的Content-Type为JSON
    							.bodyValue(requestBody) //使用bodyValue方法传递请求体
    							.retrieve()
    							.bodyToMono(String.class);
    		//返回最终结果:block是阻塞的/subscribe()非阻塞式获取响应结果
    		System.out.println("响应结果:" + mono.block());
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    方式五:使用HttpURLConnection

    HttpURLConnection 是 Java 自带的一个 HTTP 客户端工具,可以发送 HTTP 请求和接收 HTTP 响应。

    服务提供:

    @RestController
    public class SysUserController {
    
        @PostMapping(value = "/sysUser/saveUser")
        public String saveUser(@RequestBody Map map) {
            return "人员新增成功";
        }
    
        @GetMapping(value = "/sysUser/getSysUserById")
        public String getSysUserById(String userId) {
            return "郭郭";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    public class TestHttpURLConnection{
    	
    	@Test
    	public void doGet() throws IOException{
    		String userId = "郭郭";  // 参数值
            userId = URLEncoder.encode(userId, "UTF-8"); // 对参数值进行URL编码
            //步骤一:创建URL对象
            URL url = new URL("http://127.0.0.1:8094/masterdata/sysUser/getSysUserById?userId=" + userId);
            //步骤二:打开连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //步骤三:设置请求方式
            conn.setRequestMethod("GET");
            //步骤四:读取响应内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            System.out.println(sb.toString());
    	}
    
    	@Test
    	public void doPost() throws IOException{
    		 //创建URL对象
            URL url = new URL("http://127.0.0.1:8094/masterdata/sysUser/saveUser");
            //打开连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //设置请求方式
            conn.setRequestMethod("POST");
            // 设置请求头
            conn.setRequestProperty("Content-Type", "application/json");
            //启用输出流
            conn.setDoOutput(true);
            //设置请求体数据
            Map map = new HashMap<>();
            map.put("name", "郭郭");
            String requestBody = JSON.toJSONString(map);
            //发送请求体数据
            try (DataOutputStream outputStream = new DataOutputStream(conn.getOutputStream())) {
                outputStream.write(requestBody.getBytes(StandardCharsets.UTF_8));
            }
    
            //读取响应内容
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            System.out.println(sb.toString());
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    doPost请求比doGet请求多了一些逻辑,比如我们设置了conn.setDoOutPut,这用于启动输出流。

    为什么要设置conn.setDoOutPut呢?
    当您发送HTTP POST请求时,通常需要将数据发送到服务器,这些数据包含在请求体中。通过调用 setDoOutput(true),您告诉连接对象您将使用输出流来发送数据,这样它会准备好接受输出流,并将数据发送到服务器。这是发送POST请求体数据所必需的步骤。

    另一方面,对于HTTP GET请求,通常不需要发送请求体数据,因此不需要设置 setDoOutput(true)。
    而post请求的入参,我们是放入DataOutputStream进行传递,这里我们使用try语句块来包裹DataOutputStream,是因为DataOutputStream实现了AutoCloseable接口,因此它会在try块结束的时候自动关闭。

    我们介绍了HttpURLConnection,还有一种调用方式是URLConnection,它们是什么关系呢?

    通过查看源码,我们不难发现,HttpURLConnection继承自URLConnection,是它的一个子类,而HttpURLConnection专门用于处理HTTP协议的连接,如果需要处理其他协议,我们可以考虑使用通用的URLConnection。

    方式六:使用OkHttp

    OkHttp是一款高效的HTTP客户端框架,经过优化,具有低内存占有和出色的性能。

    ①、引入依赖

    
      <dependency>
        <groupId>com.squareup.okhttp3groupId>
        <artifactId>okhttpartifactId>
        <version>4.0.0version>
      dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    ②、代码

    public class TestOkHttp {
    
        @Test
        public void doGet() throws IOException {
            OkHttpClient client = new OkHttpClient();
            String url = "http://127.0.0.1:8094/masterdata/sysUser/getSysUserById?userId=郭郭";
            Request request = new Request.Builder().url(url).build();
            try (Response response = client.newCall(request).execute()) {
                ResponseBody body = response.body();
                System.out.println(body.string());
            }
        }
    
        @Test
        public void doPost() throws IOException{
            OkHttpClient client = new OkHttpClient();
            String url = "http://127.0.0.1:8094/masterdata/sysUser/saveUser";
            MediaType mediaType = MediaType.get("application/json; charset=utf-8");
            //requestBody请求入参
            Map map = new HashMap<>();
            map.put("name", "郭郭");
            RequestBody requestBody = RequestBody.create(mediaType, JSON.toJSONString(map));
            Request request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();
            try (Response response = client.newCall(request).execute()) {
                ResponseBody body = response.body();
                System.out.println(body.string());
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    方式七:使用AsyncHttpClient

    AsyncHttpClient是一个支持异步HTTP请求的开源库,用于非阻塞I/O操作,适用于需要高并发,非阻塞的应用。

    ①、引入依赖

    <dependency>
          <groupId>org.asynchttpclientgroupId>
          <artifactId>async-http-clientartifactId>
          <version>2.12.3version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ②、代码

    我们看到doGet、doPost方法都使用了try代码块,对AsyncHttpClient进行包裹,同理因为继承了AutoCloseable,为了自动调用close关闭功能。

    
    public class TestAsyncHttpClient {
        @Test
        public void doGet() throws IOException {
            try (AsyncHttpClient client = new DefaultAsyncHttpClient();) {
                BoundRequestBuilder requestBuilder = client.prepareGet("http://127.0.0.1:8094/masterdata/sysUser/getSysUserById?userId=郭郭");
                CompletableFuture<String> future = requestBuilder.execute()
                        .toCompletableFuture()
                        .thenApply(Response::getResponseBody);
                //使用join等待响应完成
                String responseBody = future.join();
                System.out.println(responseBody);
            }
        }
        @Test
        public void doPost() throws IOException {
            try (AsyncHttpClient client = new DefaultAsyncHttpClient();) {
                BoundRequestBuilder requestBuilder = client.preparePost("http://127.0.0.1:8094/masterdata/sysUser/saveUser");
                //requestBody请求入参
                Map map = new HashMap<>();
                map.put("name", "郭郭");
                String requestBody = JSON.toJSONString(map);
                requestBuilder.addHeader("Content-Type", "application/json");
                requestBuilder.setBody(requestBody);
                CompletableFuture<String> future = requestBuilder.execute()
                        .toCompletableFuture()
                        .thenApply(Response::getResponseBody);
                //使用join等待响应完成
                String responseBody = future.join();
                System.out.println(responseBody);
            }
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    【数据聚类】第八章第一节:谱聚类算法概述及拉普拉斯矩阵
    Nginx优化
    韶音骨传导耳机好不好用,韶音的骨传导耳机怎么样
    小白跟做江科大51单片机之DS1302可调时钟
    下载LLM
    关于网页中的文本选择以及统计选中文本长度
    软件测试行业能干多久?“35岁焦虑“成了多少IT人的梦魇。
    阿里云和AWS的对比研究一:AWS的起源
    大数据面试题(三):MapReduce核心高频面试题
    JAVA计算机毕业设计员工婚恋交友平台Mybatis+源码+数据库+lw文档+系统+调试部署
  • 原文地址:https://blog.csdn.net/usa_washington/article/details/132878649