目录
接口运行功能效果图
Response包括:
- Headers:响应头
- Body:响应体
- statusCode:响应状态码
批量导入接口信息:
一次性通过swagger .yml .json——导入可以做扩展开发。
可以把swagger.yml文件做导入,但平台首先要支持导入功能。
接口运行功能前端代码apiRun.html
修改如下代码:
找到paramline这个div。
QUERIES:
BODY:
HEADERS:
将paramline下面的代码注释掉:
前端代码apiRun.html这里name="requestParams[${i}].value"
需要requestParams的value值,但是后端代码中没有,所以需要去后端代码中添加。
修改后端代码ApiRequestParam.java,添加如下代码:
@TableField(exist=false)
private String value; //临时用来封装数据的,并不是直接在表当中的,不能直接操作这个表,只是用来封装的,真正的值在另外一个数据库表当中
ApiRequestParam.java的完整代码如下所示:
package com.one.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author annie
* @since 2020-02-16
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="ApiRequestParam对象", description="")
public class ApiRequestParam implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "主键id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "关联的接口编号")
private Integer apiId;
@ApiModelProperty(value = "参数名称")
private String name;
@ApiModelProperty(value = "字段类型(string、int...)")
private String paramType;
@ApiModelProperty(value = "参数类型(1:query参数;2:body参数;3:header)")
private Integer type;
@ApiModelProperty(value = "参数值示例")
private String exampleData;
@ApiModelProperty(value = "字段描述")
private String description;
@TableField(exist=false)
private String value; //临时用来封装数据的,并不是直接在表当中的,不能直接操作这个表,只是用来封装的,真正的值在另外一个数据库表当中
}
在apiRun.html前端代码中,给每个div加上id,以便区分。
接口运行功能代码修改完成效果图
注册接口:
登录接口:
json类接口:
接口发送功能代码修改
apiRun.js的代码修改如下:
$(".btn-send").click(function(){
$.ajax({
url:lemon.config.global.adminUrl+"/api/run",
headers:{"Authorization":$.cookie("sessionId")},
data:$("[name='apiRunForm']").serialize(),
type:'post',
dataType:'json',
success:function(ret){
if(ret.status=="1"){
$("[name='responseHeader']").html("<pre style='{white-space: pre-wrap; word-wrap: break-word; }'>"+ret.data.headers+"</pre>");
$("[name='responseData']").html("<pre>"+ret.data.body+"</pre>");
}else{
alert(ret.message);
}
}
});
});
spring封装的工具类
远程调用:resttemplate exchange
resttemplate默认底层实现是httpclient,也可以改成okhttp
可参阅:Spring RestTemplate 之exchange方法
httpclient走的是http协议,跨源跨平台,python和java都可以写。
dubbo走的是rpc协议,provider提供者,consumer消费者,还有一个注册中心。dubbo只能用java语言去调用。
请求–网关–(微)服务,加网关可以有安全控制,就不知道(微)服务的网关和端口,只知道网关的ip和端口,有点像反向代理,如zuul网关。
接口发送功能后端代码修改
在com.one.common下面增加类ApiRunResult.java
package com.one.common;
import lombok.Data;
@Data
public class ApiRunResult {
private String statusCode;
private String headers; //HttpHeaders 底层是MultiValueMap,它是Map的子类(Map是接口) 需要转String
private String body;
}
在ApiController.java中增加如下代码:
@RequestMapping("/run")
public Result run(ApiVO apiRunVO){
ApiRunResult apiRunResult = apiService.run(apiRunVO);
Result result = new Result("1",apiRunResult);
return result;
}
在ApiService.java中增加如下代码:
public ApiRunResult run(ApiVO apiRunVO);
ApiService.java完整代码如下:
package com.one.service;
import com.one.common.ApiListVO;
import com.one.common.ApiRunResult;
import com.one.common.ApiVO;
import com.one.pojo.Api;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 服务类
* </p>
*
* @author annie
* @since 2020-02-16
*/
public interface ApiService extends IService<Api> {
public List<ApiListVO> showApiListByProject(Integer projectId);
public List<ApiListVO> showApiListByApiClassification(Integer apiClassificationId);
public ApiVO findApiViewVO(Integer apiId);
public ApiRunResult run(ApiVO apiRunVO);
}
可参阅:RestTemplate几种常用方法说明(转)
主要从以下四个方面来看RestTemplate的使用:
- GET请求
- POST请求
- PUT请求
- DELETE请求
RestTemplate GET请求
第一种:getForEntity
getForEntity方法的返回值是一个ResponseEntity,ResponseEntity是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。
第二种:getForObject
getForObject函数实际上是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时可以使用getForObject。
RestTemplate POST请求也是类似:
第一种:postForEntity
第二种:postForObject
可以用统一的方法RestTemplate exchange
如果使用jackson的话,修改ApiController.java的代码如下:
@RequestMapping("/run")
public Result run(ApiVO apiRunVO){
ApiRunResult apiRunResult = null;
try {
apiRunResult = apiService.run(apiRunVO);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Result result = new Result("1",apiRunResult);
return result;
}
如果使用fastjson的话,可以去掉try catch,修改ApiController.java的代码如下:
@RequestMapping("/run")
public Result run(ApiVO apiRunVO){
ApiRunResult apiRunResult = null;
apiRunResult = apiService.run(apiRunVO);
Result result = new Result("1",apiRunResult);
return result;
}
如果使用jackson的话,修改ApiService.java的代码如下:
如果使用fastjson的话,就不用修改。
public interface ApiService extends IService<Api> {
public List<ApiListVO> showApiListByProject(Integer projectId);
public List<ApiListVO> showApiListByApiClassification(Integer apiClassificationId);
public ApiVO findApiViewVO(Integer apiId);
public ApiRunResult run(ApiVO apiRunVO) throws JsonProcessingException;
}
在ApiServiceImpl.java中增加如下代码:
@Override
public ApiRunResult run(ApiVO apiRunVO){
//远程调用
RestTemplate restTemplate = new RestTemplate();
String url = apiRunVO.getHost()+apiRunVO.getUrl();
String method = apiRunVO.getMethod();
List<ApiRequestParam> list = apiRunVO.getRequestParams();
LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
LinkedMultiValueMap<String, String> bodyParams = new LinkedMultiValueMap<String, String>();
for(ApiRequestParam apiRequestParam : list){
if(apiRequestParam.getType()==3){ //头
headers.add(apiRequestParam.getName(), apiRequestParam.getValue());
}else{
//body 2 4,注意此时type==1没有处理
bodyParams.add(apiRequestParam.getName(), apiRequestParam.getValue());
}
}
HttpEntity httpEntity = null;
ResponseEntity response = null;
ApiRunResult apiRunResult = new ApiRunResult();
try{
if("get".equalsIgnoreCase(method)){
//httpEntity = new HttpEntity(headers);
httpEntity = new HttpEntity(bodyParams,headers);
response = restTemplate.exchange(url,HttpMethod.GET,httpEntity,String.class);
}
else if("post".equalsIgnoreCase(method)){
httpEntity = new HttpEntity(bodyParams,headers);
response = restTemplate.exchange(url,HttpMethod.POST,httpEntity,String.class);
}
apiRunResult.setStatusCode(response.getStatusCodeValue()+"");
HttpHeaders headsResult = response.getHeaders();
//将java转成json的字符串
//第一种方法:jackson
//apiRunResult.setHeaders(new ObjectMapper().writeValueAsString(headsResult));
//第二种方法:fastjson
apiRunResult.setHeaders(JSON.toJSONString(headsResult));
apiRunResult.setBody(response.getBody().toString());
}catch(HttpStatusCodeException e){
//注意此时有调用异常,有body或没有
apiRunResult.setStatusCode(e.getRawStatusCode()+"");
apiRunResult.setHeaders(JSON.toJSONString(e.getResponseHeaders()));
apiRunResult.setBody(e.getResponseBodyAsString());
}
return apiRunResult;
}
在apiRun.html删除写死的代码:
需要在apiRun.html中增加的主要代码如下:
<script src="/lemon/js/vue.js"></script>
<script src="/lemon/js/axios.min.js"></script>
<script type="text/javascript" src="/lemon/js/jquery.cookie.js" charset="UTF-8"></script>
<script type="text/javascript">
var app = new Vue({
el: ".right-interpre",
data: {
api: {},
host: "",
projectId: ""
},
methods: {
showApi() {
let apiId = sessionStorage.getItem("apiId");
axios.get(lemon.config.global.adminUrl + "/api/toApiView", {
headers: { "Authorization": $.cookie("sessionId") },
params: { "apiId": apiId }
}).then(response => {
this.api = response.data.data;
if (this.api.status == 1 & this.api.message == "未登陆") {
location.href = lemon.config.global.rootUrl + "/html/login.html";
}
let requestParams = this.api.requestParams;
for (let i = 0; i < requestParams.length; i++) {
let param = requestParams[i];
let str = `<div class="line-com line-interrun">
<input name="requestParams[${i}].id" value="${param.id}" type="hidden">
<input name="requestParams[${i}].type" value="${param.type}" type="hidden">
<div class="ipt-interrun f-l" style="width:15%">
<div class="ltipt-interrun">
<input class=" disabled" readonly="readonly" value="${param.name==null?'json':param.name}" name="requestParams[${i}].name" type="text">
</div>
<div class="equal-interrun f-r">=</div>
<input class="disabled f-r" disabled="" checked="" type="checkbox">
</div>
<div class="ipt-interrun f-l" style="width:85%">
<input placeholder="参数值" style="width:100%" name="requestParams[${i}].value" value="${param.exampleData}" type="text">
<div class="edit-interrun f-l"></div>
</div>
</div>`;
if (param.type == 1) {
$("#reqpQuery").append(str);
} else if (param.type == 2||param.type == 4) {
$("#reqpBody").append(str);
} else if (param.type == 3) {
$("#reqpHeaders").append(str);
}
}
});
}
},
created() {
this.host = sessionStorage.getItem("host");
this.projectId = sessionStorage.getItem("projectId");
this.showApi();
}
})
</script>
<script type="text/javascript" src="/lemon/js/apiRun.js"></script>
遇到的问题汇总
问题:始终无法使用fastjson的jar包,jar包已经下载下来,手动import也无效。
解决方法:把fastjson的jar包从高版本1.2.62换成了低版本1.2.58,问题解决。