底层执行引擎还是上述三个之一,默认是HttpURLConnection。
SpringBoot的版本需要低于2.4.0
1、RequestBody使用频度少可以直接使用HashMap,如果上传的是图片可以使用MultiValueMap。
2、推荐使用exchange而非getForObject等方法
3、exchage拿到的返回值用ObjectMapper + JsonNode解析(万金油)
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 是一个声明式的 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);
}
}
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 的统一前缀。
不带泛型的这么处理
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();
}
如果前端传入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;
}
接收请求头里的参数
@RequestHeader("Authorization") String token
接收路径里面的参数RESTful
@PathVariable Long courseId
请求头和路径里面的参数同GET
处理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);
}
获取request中的参数,可以用@RequestParam的value属性指定别名。
通常使用场景是非RESTful风格的请求。
可以取URL路径中的参数值,也可以取application/x-www-form-urlcoded
编码的请求体的值
可以用来完成同时上传文件和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就行。
既可以拿来获取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);
}