现在系统之间的功能模块,相互调用以及数据的传递,如果采用http模式通讯,很少有人用webservice了,大多都是使用Restful接口,因为方便、简单嘛。
先说说怎么创建Restful接口吧,这个和普通的Controller的写法感觉差不多,就是对外路径稍微有所不同。直接看代码。
package com.springboot.controller;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.springboot.entity.ProductOrder;
import com.springboot.entity.ReqData;
import net.sf.json.JSONObject;
@RestController
public class RestfulController {
@RequestMapping(value = "/api/data", method = RequestMethod.POST)
public ProductOrder postObject(@RequestBody ReqData data) {
if (data == null) {
return null;
}
return getone(data.requestType);
}
@RequestMapping(value = "/api/map", method = RequestMethod.POST)
public List<ProductOrder> postMap(@RequestBody Map<String, String> map) {
if (map == null || map.isEmpty()) {
return null;
}
return getData();
}
@RequestMapping(value = "/api/json", method = RequestMethod.POST)
public ProductOrder postJson(@RequestBody JSONObject jsonRequest) {
if (jsonRequest == null || jsonRequest.isEmpty()) {
return null;
}
return getone("json");
}
//
@GetMapping(value = "/api/product/{id}")
public ProductOrder findone(@PathVariable("id") String id){
if (id == null)
{
id = ".";
}
return getone(id);
}
/**
* 模拟数据
* */
private List<ProductOrder> getData(){
List<ProductOrder> list=new ArrayList<ProductOrder>();
ProductOrder m1 = new ProductOrder();
m1.setId("1");
m1.setName("admin1");
m1.setPrice(0.8553f);
m1.setPDate(new Date());
list.add(m1);
ProductOrder m2 = new ProductOrder();
m2.setId("2");
m2.setName("admin2");
m2.setPrice(0.633f);
m2.setPDate(new Date());
list.add(m2);
ProductOrder m3 = new ProductOrder();
m3.setId("3");
m3.setName("admin3");
m3.setPrice(0.344f);
m3.setPDate(new Date());
list.add(m3);
return list;
}
private ProductOrder getone(String id){
ProductOrder m1 = new ProductOrder();
m1.setId(id);
m1.setName("admin");
m1.setPrice(0.8553f);
m1.setPDate(new Date());
return m1;
}
}
就是前面三个方法,这个好像很简单,注意每个方法都带不同的参数,ReqData,map,JSONObject ,对应不同的调用方法,也不多说直接上代码。这个test类因为有main方法,直接右键 Debug as ---> Java Application就可以运行了。
package com.springboot.service;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.client.RestTemplate;
import com.springboot.entity.Body;
import com.springboot.entity.Pojo;
import com.springboot.entity.ReqData;
import net.sf.json.JSONObject;
public class test {
public static void main(String[] args) {
testModel();
testMap();
testJson();
}
private static void testModel()
{
String url = "http://localhost:8181/webapp/api/data";
RestTemplate client = new RestTemplate();
ReqData m = new ReqData("01","2020-03-24 22:29:00");
String result = client.postForObject(url, m, String.class);
System.out.println(result);
}
private static void testMap()
{
String url = "http://localhost:8181/webapp/api/map";
RestTemplate client = new RestTemplate();
Map<String, Object> hashMap = new HashMap<String, Object>();
hashMap.put("key1", 999);
hashMap.put("key2", "admin");
String result = client.postForObject(url, hashMap, String.class);
System.out.println(result);
}
private static void testJson()
{
String url = "http://localhost:8181/webapp/api/json";
RestTemplate client = new RestTemplate();
JSONObject json = new JSONObject();
json.put("key1", 999);
json.put("key2", "admin");
String result = client.postForObject(url, json, String.class);
System.out.println(result);
}
}
RestTemplate 这个就是springboot下专门用来调用restful接口,这个看起来好像很简单,确实也简单。实体类代码也简单。
package com.springboot.entity;
public class ReqData {
public ReqData(String requestType,String timestamp){
this.requestType = requestType;
this.timestamp = timestamp;
}
public String requestType;
public String timestamp;
}
如果你的代码不需要JSONObject,json-lib节点可以删除。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
需要注意的是,这两部分代码理论上是放在两个工程里面下,现实场景中对外接口都是提供给别的第三方来调用。
用 RestTemplate 类调用Restful接口时,默认的情况下,GET方法是不可以传递body数据的。需要把 RestTemplate 类扩展一下。
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());
HttpGetRequestWithEntity 类
package com.springboot.config;
import java.net.URI;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.springframework.http.HttpMethod;
public class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
public HttpGetRequestWithEntity(final URI uri) {
super.setURI(uri);
}
@Override
public String getMethod() {
return HttpMethod.GET.name();
}
}
HttpComponentsClientRestfulHttpRequestFactory 类
package com.springboot.config;
import java.net.URI;
import org.apache.http.client.methods.HttpUriRequest;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
public class HttpComponentsClientRestfulHttpRequestFactory extends HttpComponentsClientHttpRequestFactory {
@Override
protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
if (httpMethod == HttpMethod.GET) {
return new HttpGetRequestWithEntity(uri);
}
return super.createHttpUriRequest(httpMethod, uri);
}
}
调用代码如下
String url = "http://127.0.0.1:8181/api/data";
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
headers.add("dataType", "json");
ReqData r = new ReqData("01","2020-03-24 22:29:00");
HttpEntity<ReqData> formEntity = new HttpEntity<ReqData>(r, headers);
ResponseEntity<String> exchange = restTemplate.exchange(url,HttpMethod.GET,formEntity, String.class);
String body = exchange.getBody();
System.out.println(body);
如果想测试代码的话,restful接口最好是自己重新写一个。 使用RestTemplate类还是比较方便,相对 httpclient 已经方便多了,尤其是在springboot下。
如果是真实业务场景,写restful接口的时候,个人建议参数类型,不要实体类型,不要map,也不要JSONObject,尽量都用String,传进去是String,返回的也是String 。当然,这个String往往是可以json组成的,这样一来,数据类型简单,而且还能应付复杂的业务场景。
这样就是你好,我好,大家好。否则总会有各种各样麻烦,搞个接口调试的人应该知道。这样做似乎有点土,是笨办法,回避复杂的做法,但是,可以避免被人吐槽你写的接口,甚至.......