一个springboot项目要调用另外一个springboot项目的接口合前端的一样要知道ip,端口,和资源的url这里就要用到低端的java.ne包的内容,在项目开发过程一般用到的是HttpClient类和RestTemplate类两个类来实现
springboot中RestTemplate及httpClient的之间的区别
RestTemplate的方式对端必须是标准的RestFul接口规范,否则就会抱如下的错误信息:
Invalid mime type “text/html,charset=utf8; charset=ISO-8859-1”
httpClient采用这个方式获取不存在类似的问题,但是这中间fastJson对象解析为json的时候,会出现变量首字母自动变成小写的问题。采用
TypeUtils.compatibleWithJavaBean = true;
即可解决
比较两者主要从这几个方面来比较
连接池
超时时间设置(连接超时、读取超时等)
是否支持异步
请求和响应的编解码
可扩展性
RestTemplate 本身基于成熟的 HTTP Client 实现(Apache HttpClient、OkHttp 等),并可以灵活地在这些实现中切换,而且具有良好的扩展性。最重要的是提供了前面几个 HTTP Client 不具备的消息编解码能力。
代码实现
Httpclient的get请求和post请求的实现不注重学习
可参考
着重学习RestTemplate类的get请求和post请求
参考
下面这个通过form-data来完成的,是请求参数是Map<String,>,返回体的是String 类型的,要继续学习实体类的
@Autowired
RestTemplate restTemplate;
@Override
public String call(String param) {
String url="http://192.168.11.128:8082/saveToRedis";
String result;
try {
//因为在config配置中已经注入配置过了就不用再写了
SimpleClientHttpRequestFactory requestFactory=new SimpleClientHttpRequestFactory();
//设置超时
requestFactory.setConnectTimeout(1000);
requestFactory.setReadTimeout(1000);
//利用复杂构造器可以实现超时设置,内部实际实现为 HttpClient
RestTemplate restTemplate02=new RestTemplate(requestFactory);
//设置请求头,设置编码等信息
HttpHeaders httpHeaders=new HttpHeaders();
httpHeaders.set("Accept-Charset", "utf-8");
httpHeaders.set("Content-type", "text/xml; charset=utf-8");// 设置编码
//这个是定义请求参数类型为form-data的
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
//设置请求体
MultiValueMap map=new LinkedMultiValueMap();
map.add("name",param);
HttpEntity requestBody=new HttpEntity(map,httpHeaders);
//设置响应体
ResponseEntity<String> responseEntity=restTemplate02.postForEntity(url,requestBody,String.class);
result=responseEntity.getBody();
}catch (Exception e){throw e;}
return url+"调用了,返回"+result;
}
下面我们看请求参数为json字符串的
ResTemplate请求参数为json字符串,返回实体类的时比较复杂,可参考文章
传过去:
把参数不断地put到下面这个Map里面
HttpHeaders httpHeaders=new HttpHeaders();
//参数类型是json所以用MediaType.APPLICATION_JSON_UTF8
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
RestTemplate带参传的时候要用HttpEntity<?>对象传递
Map<String,Object> map=new LinkedHashMap<>();
例如请求参数为:
{
“name”:“小项目”,
“pageSize”:3,
“pageNum”:3
}
map.put("name","小项目");
map.put("pageSize",3);
map.put("pageNum",3);
再声明一请求实体HttpEntitiies
HttpEntity<Map<String,Object>> requestEntity=new HttpEntity<Map<String, Object>>(map,httpHeaders);
传回来:
获取反应实体类ResponseBody的body,这是一个json字符串
ResponseEntity<String> responseEntity=restTemplate.postForEntity(url,requestEntity,String.class);
System.out.println("requestEntity"+requestEntity);
String responseBody=responseEntity.getBody();
System.out.println("responseBody"+responseBody);
问题来了,如何把这个json字符串转化为实体类的对象呢??????????
例如返回Json字符串为:
{
“code”: 200,
“msg”: “成功”,
“data”: {
“id”: 1,
“projectName”: “小项目”,
“detectType”: “到货检测”,
“projectCode”: “123”,
“manager”: “小刘”,
“projectTime”: null,
“outsourceContractNum”: null,
“itemTableLineDtoList”: [
{
“id”: 6,
“itemName”: “分项7”,
“itemStatus”: null,
“reportAmount”: 2,
“itemType”: “正常”,
“estimateSampleDate”: “2019-08-15 16:00:00”,
“expirationSampleDate”: “2019-08-16 16:00:00”
}
],
“nextPage”: 0,
“prePage”: 1,
“total”: 4,
“pages”: 2,
“pageSize”: 3,
“pageNum”: 2
}
}
这个时候就要封装项目的实体类对象,把访问项目接口返回的封装类文件copy过来
这两个类是从访问项目那copy过来的,GetItemtableBack.java是加上其他的code,msg信息的封装的类:
public class GetItemtableBack {
private String code;
private String msg;
private ItemTableDetail data;
最后通过import net.sf.json.JSONObject包通过把JSONObject转化为封装类
JSONObject jsonObject02=JSONObject.fromObject(responseBody);
GetItemtableBack getItemtableBack=(GetItemtableBack)JSONObject.toBean(jsonObject02,GetItemtableBack.class);
System.out.println(getItemtableBack.getCode());
System.out.println(getItemtableBack.getMsg());
System.out.println(getItemtableBack.getData());
ItemTableDetail itemTableDetail=getItemtableBack.getData();
System.out.println("所有的分项信息"+itemTableDetail.getItemTableLineDtoList());
注意在pom文件导入net.sf.json 时报错解决方法:
要加jdk15
<!-- https://mvnrepository.com/artifact/net.sf.json-lib/json-lib -->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
@Value("${}")配置整个项目的全局变量的应用
server.port=8084
person.name="小华"
@Value("${person.name}")
private String name;
@Test
public void contextLoads() {
System.out.println(name);
}
但这会出现乱码,原因是application.properties这个文件的编码格式错了
解决方案: