Java-Http请求及处理

发送请求

JDK HttpURLConnection

Apche HttpClient

OKHttp

RestTemplate(推荐)

底层执行引擎还是上述三个之一,默认是HttpURLConnection。
SpringBoot的版本需要低于2.4.0

注意事项

1、RequestBody使用频度少可以直接使用HashMap,如果上传的是图片可以使用MultiValueMap。
2、推荐使用exchange而非getForObject等方法
3、exchage拿到的返回值用ObjectMapper + JsonNode解析(万金油)

retrofit2

RestTemplate使用步骤

1、增加配置类

package com.example.upload_json_image.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestConfig {
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

2、在需要发起请求的地方自动注入

@RequestMapping("/welcome")
@RestController
public class WelcomeConfigController {
    @Autowired
    RestTemplate restTemplate;
    
    @GetMapping("/interactive")
    public void interactive(HttpServletRequest httpServletRequest,@RequestBody Task task){
    	//装配URL
        String url="https://open.feishu.cn/open-apis/im/v1/messages/user_id";
        //请求头
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Authorization","t-68ff8a45a4190a71fc0e78d5ba0525509a95ff54");
        requestHeaders.add("Content-Type","application/json; charset=utf-8");
        //请求体
        Map<String, String> requestBody = new HashMap<>();
        requestBody.add("receive_id","9g841951");
        requestBody.add("msg_type","text");
        requestBody.add("content","{\"text\":\"Tom test content\"}");
		//请求头和请求体组装
        HttpEntity<Map<String,String>> requestEntity = new HttpEntity<>(larkCollaborator,requestHeaders);
        //三个参数分别是请求的URL、请求头+请求体、返回值类型
        restTemplate.postForEntity(url,requestEntity,Object.class);
    }
}

3、解析返回值
注意取出来的值可能包含双引号,会被Java转义,从而导致多出两个引号。

//解析数组
//使用getBody()方法获取响应体
ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, httpEntity, String.class);
String body = exchange.getBody();
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(body);
//例如有一个key-value在第一层name
String s=root.get("name").asText();
//例如有一个key-value在第一层data下第二层num
Long num=root.get("data").get("num").asLong();
//例如有一个JSON数组
Iterator<JsonNode> iterator = root.get("data").get("items").iterator();
//使用Java集合迭代器依次遍历
//同name和num一样取出来

Feign(微服务)

Feign 是一个声明式的 Web Service 客户端。基本用在微服务调用。
1、引入依赖:

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
dependency>

2、启动类加注解

/** 开启 Feign 扫描支持 */
@EnableFeignClients

3、Feign接口编写
因为是声明式,就和Controller层很像

//使用 Feign 访问 Github 查询 API
@FeignClient(name = "github-client", url = "https://api.github.com")
public interface GitHubFeign {

    @RequestMapping(
            value = "/search/repositories",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE
    )
    String searchRepo(@RequestParam("q") String q);

}

4、真实Controller层

@RestController
@RequestMapping(
        value = "/github",
        produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public class GitHubController {

    @Resource
    private GitHubFeign gitHubFeign;

    @RequestMapping(
            value = "/search/repositories",
            method = RequestMethod.GET
    )
    String searchRepo(@RequestParam("q") String q) {
        return gitHubFeign.searchRepo(q);
    }

}

@FeignClient 注解

name:指定 Feign Client 的名称,如果项目使用了 Ribbon,name 属性会作为微服务的名称,用于服务发现。
url:url 一般用于调试,可以手动指定 @FeignClient 调用的地址。
decode404:当发生404错误时,如果该字段为 true,会调用 decoder 进行解码,否则抛出 FeignException。
configuration:Feign 配置类,可以自定义 Feign 的 Encoder、Decoder、LogLevel、Contract。
fallback:定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback 指定的类必须实现 @FeignClient 标记的接口。
fallbackFactory:工厂类,用于生成 fallback 类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码。
path:定义当前 FeignClient 的统一前缀。

处理返回到JSON

解析到类中

解析到Map中

ResponseEntity

不带泛型的这么处理

try {
	String body = EntityUtils.toString(response.getEntity(), "UTF-8");
	JsonNode root = mapper.readTree(body);
	chat_id = root.get("data").get("chat_id").textValue();
} catch (IOException e) {
	e.printStackTrace();
}

JSONObject

前端传入的JSON

如果前端传入JSON,又不想专门写一个类,或者前端传入的JSON无法确保映射到一个确定的类,可以用一下方法:

public Map<String, String> testChallenge(@RequestBody Map<String, Object> body){
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        JsonNode root = objectMapper.readTree(objectMapper.writeValueAsString(body));
        if(root.get("header").get("event_type")!=null){
			
        }
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }

    return null;
}

接收请求

GET

接收请求头里的参数

@RequestHeader("Authorization") String token

接收路径里面的参数RESTful

@PathVariable Long courseId

POST

请求头和路径里面的参数同GET

@RequestBody

处理application/json或者是application/xml等类型的请求体

	$.ajax({
        url:"/login",
        type:"POST",
        data:'{"userName":"admin","pwd","admin123"}',
        content-type:"application/json charset=utf-8",
        success:function(data){
          alert("request success ! ");
        }
    });

    @requestMapping("/login")
    public void login(@requestBody String userName,@requestBody String pwd){
      System.out.println(userName+" :"+pwd);
    }

@RequestParam

获取request中的参数,可以用@RequestParam的value属性指定别名。
通常使用场景是非RESTful风格的请求。
可以取URL路径中的参数值,也可以取application/x-www-form-urlcoded编码的请求体的值

@RequestPart

可以用来完成同时上传文件和JSON的需求。(只上传文件可以直接用@RequestBody接受文件)
后端代码

    @RequestMapping("/jsonDataAndUploadFile")
    @ResponseBody
    public String jsonDataAndUploadFile(@RequestPart("uploadFile") MultipartFile uploadFiles[],
                                        @RequestPart("jsonData") Person person) {

        return person.toString() + ":::" + uploadFiles.length;
    }

前端请求

curl --location --request POST 'http://127.0.0.1:8080/welcome/jsonDataAndUploadFile' \
--form 'uploadFile=@"/Users/bytedance/Downloads/ww.jpeg"' \
--form 'jsonData="{\"name\":\"zhangsan\"}";type=application/json'

注:前端上传多个文件,都叫uploadFile就行。

返回响应体

ResponseEntity

既可以拿来获取restTemplate请求到的结果,也可以用来给前端返回。需要制定泛型。

@ResponseBody可以直接返回Json结果, @ResponseEntity不仅可以返回json结果,还可以定义返回的HttpHeaders和HttpStatus。
ResponseEntity类继承自HttpEntity,有三个关键属性 httpStatus 、body、httpHeader,分别代表响应状态码、响应体、响应头信息;

注意事项

1、ResponseEntity之后跟的范型是responseBody的class
2、构造方法很多,至少包含状态码,具体使用根据需求来选择具体的构造方法

示例

作为:接收请求返回值
In RestTemplate, this class is returned by getForEntity() and exchange():

//示例
ResponseEntity<String> entity = template.getForEntity("https://example.com", String.class);
String body = entity.getBody();
MediaType contentType = entity.getHeaders().getContentType();
HttpStatus statusCode = entity.getStatusCode();
//处理响应体(例:JSON)
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(body);
chat_id = root.get("data").get("chat_id").textValue();

作为:返回值
通常泛型使用枚举类型 来复用返回结果
This can also be used in Spring MVC as the return value from an @Controller method:

 @RequestMapping("/handle")
 public ResponseEntity<String> handle() {
   URI location = ...;
   HttpHeaders responseHeaders = new HttpHeaders();
   responseHeaders.setLocation(location);
   responseHeaders.set("MyResponseHeader", "MyValue");
   return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
 }

HttpResponse

你可能感兴趣的:(Java,java,http)