說明:系統中經需要統計接口的調用情況,所以特此寫了這個功能。(適用於spring boot框架)
1. 統計系統中有哪些接口及接口的功能
思路,當服務器啓動後統計系統的@requestMapper,並根據方法上的註解獲取該接口的功能。
1.1 啓動時註冊一個監聽器
SpringApplication app=new SpringApplication(Application.class);
app.addListeners(new ApplicationStartup());
app.run( args);
1.2 編寫監聽器中的業務邏輯
public class ApplicationStartup implements ApplicationListener<ContextRefreshedEvent>{
public void onApplicationEvent(ContextRefreshedEvent event) {
getAllUrls(event);
}
/**
* 獲取所有的url數據
* @param event
*/
public void getAllUrls(ContextRefreshedEvent event) {
AbstractHandlerMethodMapping<RequestMappingInfo> objHandlerMethodMapping =(AbstractHandlerMethodMapping<RequestMappingInfo>) event.getApplicationContext().getBean("requestMappingHandlerMapping");
InterfaceMethodMapper interfaceMethodMapper=event.getApplicationContext().getBean(InterfaceMethodMapper.class);
Map<RequestMappingInfo, HandlerMethod> mapRet = objHandlerMethodMapping.getHandlerMethods();
//先刪除所有數據
interfaceMethodMapper.deleteByExample(null);
if(mapRet!=null){
List<InterfaceMethod>InterfaceMethodList=new ArrayList<InterfaceMethod>();
Date date=new Date();
for(RequestMappingInfo info:mapRet.keySet()) {
HandlerMethod handlerMethod=mapRet.get(info);
//獲取對應的類
String type=handlerMethod.getBeanType().getName();
//獲取方法
Method method=handlerMethod.getMethod();
InterfaceDescript interfaceScript=method.getAnnotation(InterfaceDescript.class);
String name=method.getName();
//只對有該註解的方法做處理
if(interfaceScript!=null) {
String descript=interfaceScript.value();
//獲取url
Set<String> urls=info.getPatternsCondition().getPatterns();
for(String url:urls) {
InterfaceMethod interfaceMethod=new InterfaceMethod();
interfaceMethod.setPath(url);
interfaceMethod.setClassName(type);
interfaceMethod.setMethodName(name);
interfaceMethod.setRmark(descript);
interfaceMethod.setCreateTime(date);
InterfaceMethodList.add(interfaceMethod);
}
}
}
if(InterfaceMethodList.size()>0) {
//將獲取的url信息插入到數據庫中
interfaceMethodMapper.insertList(InterfaceMethodList);
}
}
}
}
1.3 對應的數據庫(mapper是通過工具直接生成的)
CREATE TABLE `interface_method` (
`path` varchar(200) NOT NULL COMMENT '路徑',
`class_name` varchar(200) NOT NULL COMMENT '類名',
`method_name` varchar(100) NOT NULL COMMENT '方法名',
`rmark` varchar(1000) NOT NULL COMMENT '備註',
`create_time` datetime NOT NULL COMMENT '更新時間',
PRIMARY KEY (`path`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
批量插入數據
<insert id="insertList" parameterType="com.trilink.counter.entity.InterfaceMethod" >
insert into interface_method (path, class_name, method_name,
rmark, create_time)
values
<foreach collection="recordList" separator="," item="record">
(#{record.path,jdbcType=VARCHAR}, #{record.className,jdbcType=VARCHAR}, #{record.methodName,jdbcType=VARCHAR},
#{record.rmark,jdbcType=VARCHAR}, #{record.createTime,jdbcType=TIMESTAMP})
</foreach>
</insert>
2. 通過spring AOP攔截Controller對應的方法獲取返回數據,以便於通過返回值獲取響應數成功與否.
2.1 攔截器的設計
/***
* aop攔截器獲取返回值(返回對象裏面有 errCode字段的可以做出處理)
*
* @author acer
*
*/
@Aspect
@Component
public class ControllerInterceptor {
@Autowired
private InterfaceCounterMapper interfaceCounterMapper;
//用於存放請求數據
private static List<InterfaceCounter> list=new LinkedList<InterfaceCounter>();
//統計數量達到限制後批量寫入數據庫,以減輕數據庫壓力
public static final int UPDATESIZE=3;
/**
* 定義攔截規則:攔截com.xjj.web.controller包下面的所有類中,有@RequestMapping註解的方法。
*/
@Pointcut("(execution(* com.trilink.common.controller..*(..)) || execution(* com.trilink.counter.controller..*(..))) and @annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void controllerMethodPointcut() {
}
/**
* 攔截器具體實現
*
* @param pjp
* @return JsonResult(被攔截方法的執行結果,或需要登錄的錯誤提示。)
*/
@Around("controllerMethodPointcut()") // 指定攔截器規則;也可以直接把「execution(* com.xjj.........)」寫進這裏
public Object Interceptor(ProceedingJoinPoint pjp) {
boolean isError = false;
Object result = null;
Gson gson = new Gson();
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest httpServletRequest = requestAttributes.getRequest();
//獲取請求路徑
String url=httpServletRequest.getRequestURI();
String appId=httpServletRequest.getParameter("appId");
Map<String, String[]> par=httpServletRequest.getParameterMap();
//獲取請求參數
String param=gson.toJson(par);
String errMsg;
int mcode=-1;
try {
result = pjp.proceed();
String json = gson.toJson(result);
Map<String, Object> reponse = gson.fromJson(json, Map.class);
Object code = reponse.get("errCode");
errMsg = (String)reponse.get("errMsg");
if (code != null) {
if (code instanceof Integer) {
mcode=(int)(code);
} else if (code instanceof String) {
mcode=Integer.parseInt((String)code);
} else if (code instanceof Double) {
Double cd=(Double)code;
mcode=cd.intValue();
} else if (code instanceof Long) {
mcode=(int)(code);
}
}
} catch (Throwable e) {
Map<String, Object> error = new HashMap<String, Object>();
error.put("errCode", -1);
error.put("errMsg", e.getMessage());
result = error;
mcode=-2;
isError = true;
errMsg= e.getMessage();
}
InterfaceCounter InterfaceCounter=new InterfaceCounter();
InterfaceCounter.setPath(url);
InterfaceCounter.setParam(param);
InterfaceCounter.setMessage(errMsg);
InterfaceCounter.setStatus(mcode);
InterfaceCounter.setCreateTime(new Date());
InterfaceCounter.setAppId(appId);
list.add(InterfaceCounter);
if(list.size()>=UPDATESIZE) {
interfaceCounterMapper.insertList(list);
list.removeAll(list);
}
return result;
}
}
3. 數據的展示
說明:數據主要以圖表的形式展示,前臺html頁面通過ajax請求來與後臺交互。
3.1 後臺服務的編寫
/**
* 統計接口請求量
* @author acer
*
*/
@Controller
@RequestMapping("interfaceCounter")
public class InterfaceCounterController {
@Autowired
private InterfaceCounterService interfaceCounterService;
@RequestMapping("counterInterface")
@ResponseBody
@InterfaceDescript("統計接口請求量")
/**
* 統計信息
* @param type 類型,1:年,2:月,3:日,4:小時,5:分
* @param year
* @param month
* @param day
* @param hour
* @param min
* @return
*/
public Map<String,Object>counterInterface(Integer type,Integer year,Integer month,Integer day,Integer hour){
Map<String,Object>result=new HashMap<String,Object>();
if(type==null) {
type=1;
year=2010;
}
if(type==1) {
year=2010;
}
try {
result=interfaceCounterService.counterInterface(type,year,month,day,hour);
}catch(Exception e) {
result.put("errCode", 101);
result.put("errMsg", "查詢失敗:"+e.getMessage());
}
return result;
}
@RequestMapping("counterMathods")
@ResponseBody
@InterfaceDescript("某個接口的單位請求量")
/**
*
* @param type 類型,1:年,2:月,3:日,4:小時,5:分
* @param year
* @param month
* @param day
* @param hour
* @return
*/
public Map<String,Object>counterMathods(Integer type,Integer year,Integer month,Integer day,Integer hour){
Map<String,Object>result=new HashMap<String,Object>();
if(type==null) {
type=1;
year=2010;
}
try {
result=interfaceCounterService.counterMathods(type,year,month,day,hour);
}catch(Exception e) {
result.put("errCode", 101);
result.put("errMsg", "查詢失敗:"+e.getMessage());
}
return result;
}
@RequestMapping("mathodsDetail")
@ResponseBody
@InterfaceDescript("所有接口的詳細信息")
/**
*
* @param order 1位降序,2爲升序(時間)
* @param page默認值爲1
* @param rows
* @return
*/
public Map<String,Object>mathodsDetail(Integer order,Integer page,Integer rows,String start,String end){
Map<String,Object>result=new HashMap<String,Object>();
if(page==null||page<1) {
page=1;
}
if(order==null||order<1) {
order=1;
}
if(rows==null||rows<1) {
rows=10;
}
try {
result=interfaceCounterService.mathodsDetail(order,page,rows,start,end);
}catch(Exception e) {
result.put("errCode", 101);
result.put("errMsg", "查詢失敗:"+e.getMessage());
}
return result;
}
}
@Service
public class InterfaceCounterService {
@Autowired
private InterfaceCounterMapper interfaceCounterMapper;
/**
* 統計接口請求信息
* @param type 類型,1:年,2:月,3:日,4:小時,5:分
* @param year
* @param month
* @param day
* @param hour
* @param min
* @return
*/
public Map<String, Object> counterInterface(Integer type,Integer year,Integer month,Integer day,Integer hour) {
Map<String,Object>result=new HashMap<String,Object>();
Calendar calendar=Calendar.getInstance();
List<Date> timeList=null;
if(type==1) {//年
timeList=getListYear(calendar.get(Calendar.YEAR),year);
}else if(type==2) {//月
timeList=getListMonth(year);
}else if(type==3) {//日
timeList=getListDay(year, month);
}else if(type==4) {//時
timeList=getListHour(year, month, day);
}else if(type==5) {//分
timeList=getListMinut(year, month, day, hour);
}
if(timeList==null||timeList.size()<1) {
result.put("errCode", 101);
result.put("errMsg", "輸入的參數存在問題");
return result;
}else {
Date start=null;
Date end=null;
//總請求量
List<Integer>numberList=new ArrayList<Integer>();
//描述
List<Integer> decsList=new ArrayList<Integer>();
//成功請求量
List<Integer>successList=new ArrayList<Integer>();
for(int i=0;i<timeList.size()-1;i++) {
start=timeList.get(i);
end=timeList.get(i+1);
InterfaceCounterExample interfaceCounterExample =new InterfaceCounterExample();
InterfaceCounterExample.Criteria interfaceCounterExampleCriteria = interfaceCounterExample.createCriteria();
interfaceCounterExampleCriteria.andCreateTimeBetween(start, end);
int count=interfaceCounterMapper.countByExample(interfaceCounterExample);
numberList.add(count);
InterfaceCounterExample interfaceCounterExample2 =new InterfaceCounterExample();
InterfaceCounterExample.Criteria interfaceCounterExampleCriteria2 = interfaceCounterExample2.createCriteria();
interfaceCounterExampleCriteria2.andStatusEqualTo(0);
interfaceCounterExampleCriteria2.andCreateTimeBetween(start, end);
int countSuccess=interfaceCounterMapper.countByExample(interfaceCounterExample2);
successList.add(countSuccess);
//根據不同的類型返回不同的座標數據
if(type==1) {//年
decsList.add(start.getYear()+1900);
}else if(type==2) {//月
decsList.add(start.getMonth()+1);
}else if(type==3) {//日
decsList.add(start.getDate());
}else if(type==4) {//時
decsList.add(start.getHours());
}else if(type==5) {//分
decsList.add(start.getMinutes());
}
}
result.put("dataY", numberList);
result.put("sdataY", successList);
result.put("dataX", decsList);
result.put("errCode", 0);
result.put("errMsg", "查詢成功");
}
return result;
}
/**
* 根據日期統計每個接口調用情況
* @param type
* @param year
* @param month
* @param day
* @param hour
* @return
*/
public Map<String, Object> counterMathods(Integer type, Integer year, Integer month, Integer day, Integer hour) {
Map<String,Object>result=new HashMap<String,Object>();
Date start=getFirstDate(type,year, month, day, hour);
Date end=getLastDate(type,year, month, day, hour);
List<InterfaceCounter> list=interfaceCounterMapper.countByDate(start, end);
List<String>dataY=new ArrayList<String>();
List<Integer>dataX=new ArrayList<Integer>();
for(InterfaceCounter item:list) {
dataY.add(item.getPath());
dataX.add(item.getNum());
}
result.put("dataY", dataY);
result.put("dataX", dataX);
result.put("errCode", 0);
result.put("errMsg", "查詢成功");
return result;
}
public Map<String, Object> mathodsDetail(Integer order,Integer page, Integer rows,String start,String end) throws Exception {
Map<String,Object>result=new HashMap<String,Object>();
InterfaceCounterExample interfaceCounterExample = new InterfaceCounterExample();
InterfaceCounterExample.Criteria InterfaceCounterExampleCriteria=interfaceCounterExample.createCriteria();
if(order==1) {
interfaceCounterExample.setOrderByClause("create_time desc");
}else {
interfaceCounterExample.setOrderByClause("create_time asc");
}
//當時間不爲空時根據時間段查詢
if(start!=null&&!start.equals("")&&end!=null&&!end.equals("")) {
SimpleDateFormat fmt=new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date startDate=fmt.parse(start);
Date endDate=fmt.parse(end);
InterfaceCounterExampleCriteria.andCreateTimeBetween(startDate, endDate);
}
PageHelper.startPage(page, rows);
List<InterfaceCounter> list=interfaceCounterMapper.selectByExample(interfaceCounterExample);
PageInfo<InterfaceCounter> pages=new PageInfo<>(list);
result.put("data", list);
result.put("tatal", pages.getTotal());
result.put("errCode", 0);
result.put("errMsg", "查詢成功");
return result;
}
/**
* 獲取當前時間的第一時刻
* @param type 1:年,2:月,3:日,4:小時
* @param year
* @param month
* @param day
* @param hour
* @return
*/
private static Date getFirstDate(Integer type, Integer year, Integer month, Integer day, Integer hour) {
Calendar calendar=Calendar.getInstance();
if(type==1) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
return calendar.getTime();
}else if(type==2) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
return calendar.getTime();
}else if(type==3) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH,day);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
return calendar.getTime();
}else if(type==4||type==5) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH,day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
return calendar.getTime();
}
return null;
}
/**
* 獲取當前時間的第一時刻
* @param type 1:年,2:月,3:日,4:小時
* @param year
* @param month
* @param day
* @param hour
* @return
*/
private static Date getLastDate(Integer type, Integer year, Integer month, Integer day, Integer hour) {
Calendar calendar=Calendar.getInstance();
if(type==1) {
calendar.set(Calendar.YEAR, year+1);
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, -1);
return calendar.getTime();
}else if(type==2) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, -1);
return calendar.getTime();
}else if(type==3) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH,day+1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, -1);
return calendar.getTime();
}else if(type==4||type==5) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH,day);
calendar.set(Calendar.HOUR_OF_DAY, hour+1);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, -1);
return calendar.getTime();
}
return null;
}
/**
* 獲取年的列表
* @param year
* @return
*/
private static List<Date> getListYear(int current,int year) {
List<Date>list=new ArrayList<Date>();
Calendar calendar=Calendar.getInstance();
Date cur=calendar.getTime();
for(;current>=year;year++) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
list.add(calendar.getTime());
}
list.add(cur);
return list;
}
/**
* 獲取月列表
* @param currentYear
* @param year
* @param month
* @return
*/
private static List<Date>getListMonth(int year){
List<Date>list=new ArrayList<Date>();
Calendar calendar=Calendar.getInstance();
Date current=calendar.getTime();
int currentYear=calendar.get(Calendar.YEAR);
int end=0;
if(year<calendar.get(Calendar.YEAR)) {
end=11;
}else {
end=calendar.get(Calendar.MONTH);
}
for(int i=0;i<=end;i++) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, i);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
list.add(calendar.getTime());
}
if(year>=currentYear) {
list.add(current);
}else {
calendar.set(Calendar.YEAR, year+1);
calendar.set(Calendar.MONTH, 0);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, -1);
list.add(calendar.getTime());
}
return list;
}
/**
* 獲取某個月對應的日
* @param year
* @param month
* @return
*/
private static List<Date>getListDay(int year,int month){
List<Date>list=new ArrayList<Date>();
Calendar calendar=Calendar.getInstance();
Date current=calendar.getTime();
int day=calendar.get(Calendar.DAY_OF_MONTH);
int end=0;
Date endDay=calendar.getTime();
if(year<calendar.get(Calendar.YEAR)||(year==calendar.get(Calendar.YEAR)&&(month-1)<calendar.get(Calendar.MONDAY))) {
//獲取本月最後一天
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, -1);
endDay=calendar.getTime();
end=calendar.get(Calendar.DAY_OF_MONTH);
}else if(year==calendar.get(Calendar.YEAR)&&(month-1)==calendar.get(Calendar.MONDAY)){
endDay=current;
end=day;
}
for(int i=1;i<=end;i++) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH, i);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
list.add(calendar.getTime());
}
list.add(endDay);
return list;
}
/**
* 獲取當天的時間列表信息
* @param year
* @param month
* @param day
* @return
*/
private static List<Date>getListHour(int year,int month,int day){
List<Date>list=new ArrayList<Date>();
Calendar calendar=Calendar.getInstance();
Date current=calendar.getTime();
//是當天時間
int end=0;
boolean isCurrent=false;
if(year==calendar.get(Calendar.YEAR)&&(month-1)==calendar.get(Calendar.MONTH)&&day==calendar.get(Calendar.DAY_OF_MONTH)) {
//獲取現在時間
end=calendar.get(Calendar.HOUR_OF_DAY);
isCurrent=true;
}else {
end=23;
}
for(int i=0;i<=end;i++) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, i);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
list.add(calendar.getTime());
}
if(isCurrent) {
list.add(current);
}else {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH, day+1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, -1);
list.add(calendar.getTime());
}
return list;
}
/**
* 獲取當天小時列表
* @param year
* @param month
* @param day
* @param hour
* @return
*/
private static List<Date>getListMinut(int year,int month,int day,int hour){
List<Date>list=new ArrayList<Date>();
Calendar calendar=Calendar.getInstance();
Date current=calendar.getTime();
int minut=0;
if(year==calendar.get(Calendar.YEAR)&&(month-1)==calendar.get(Calendar.MONTH)&&day==calendar.get(Calendar.DAY_OF_MONTH)&&hour==calendar.get(Calendar.HOUR_OF_DAY)) {
minut=calendar.get(Calendar.MINUTE);
}else {
minut=60;
}
//每5分鐘統計一次
for(int i=0;i<=minut;i+=5) {
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY,hour);
calendar.set(Calendar.MINUTE, i);
calendar.set(Calendar.SECOND, 0);
list.add(calendar.getTime());
}
return list;
}
}
/**
* 統計系統接口的數量和基本信息
* @author acer
*
*/
@Controller
@RequestMapping("interfaceMethod")
public class InterfaceMethodController {
@Autowired
private InterfaceMethodService interfaceMethodService;
@RequestMapping("/listMethod")
@ResponseBody
@InterfaceDescript("獲取系統中的調用接口信息")
public Map<String,Object> listMethod(Integer page,Integer rows) {
if(page==null||page<=0) {
page=1;
}
if(rows==null||rows<=0) {
rows=10;
}
Map<String,Object>result=new HashMap<String,Object>();
try {
result=interfaceMethodService.listInterfaceMethod(page, rows);
}catch(Exception e) {
result.put("errCode", 101);
result.put("errMsg", "查詢失敗");
}
return result;
}
}
@Service
public class InterfaceMethodService {
@Autowired
private InterfaceMethodMapper interfaceMethodMapper;
/**
* 查詢接口信息
* @return
*/
public Map<String,Object> listInterfaceMethod(Integer page,Integer rows){
Map<String,Object>result=new HashMap<String,Object>();
PageHelper.startPage(page, rows);
List<InterfaceMethod> list=interfaceMethodMapper.selectByExample(null);
PageInfo<InterfaceMethod> pageinfo=new PageInfo<>(list);
result.put("data", pageinfo.getList());
result.put("total", pageinfo.getTotal());
result.put("errCode", 0);
result.put("errMsg", "查詢成功");
return result;
}
}
3.2數據表
CREATE TABLE `interface_counter` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`path` varchar(200) CHARACTER SET utf8 NOT NULL COMMENT '請求的url',
`status` int(11) DEFAULT '-1' COMMENT '請求狀態碼: 默認值爲-1,0成功,大於0失敗',
`message` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '響應信息',
`create_time` datetime DEFAULT NULL COMMENT '請求時間',
`param` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '請求參數',
`app_id` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT 'app的標識',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=990 DEFAULT CHARSET=utf8mb4;
其中controller中使用了自定義註解,主要是爲了獲取接口功能信息。
3.3html頁面的展示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>系統接口信息</title>
<link href="/css/bootstrap.min.css" rel="stylesheet" />
<link href="/js/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css" rel="stylesheet" media="screen">
<link href="/js/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css" rel="stylesheet" media="screen">
</head>
<style>
.chart{
width:1000px;
height:500px;
}
</style>
<script type="text/javascript" src="/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="/js/echarts.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="/js/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js" charset="UTF-8"></script>
<script type="text/javascript" src="/js/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js" charset="UTF-8"></script>
<body>
<div class="container">
<div class="row">
<div class="col-md-12" style="height:60px;"></div>
<div class="form-group col-md-5">
<label for="type" class="col-sm-3 control-label">視圖方式:</label>
<div class="col-sm-6">
<select id="type" class="form-control">
<option value="5">分鐘</option>
<option value="4">小時</option>
<option value="3" selected >日</option>
<option value="2">月</option>
<option value="1">年</option>
</select>
</div>
</div>
<div class="form-group col-md-5">
<label for="dtp_input1" class="col-md-3 control-label">時間:</label>
<div class="input-group date form_datetime col-md-6" data-date-format="yyyy/MM/dd - hh:ii" data-link-field="dtp_input1">
<input id="dates" class="form-control" size="16" type="text" value="" readonly>
<span class="input-group-addon"><span class="glyphicon glyphicon-remove"></span></span>
<span class="input-group-addon"><span class="glyphicon glyphicon-th"></span></span>
</div>
<input type="hidden" id="dtp_input1" value="" /><br/>
</div>
<div class="form-group col-md-2">
<button class="btn btn-success" id="search">
<span class="glyphicon glyphicon-search"></span>查詢
</button>
</div>
<div class="col-lg-12">
<div id="chart" class="chart">
</div>
</div>
<div class="col-lg-12">
<div id="chart2" class="chart">
</div>
</div>
</div>
</div>
</body>
<script>
//對控件漢化
$.fn.datetimepicker.dates['zh-CN'] = {
days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"],
daysShort: ["週日", "週一", "週二", "週三", "週四", "週五", "週六", "週日"],
daysMin: ["日", "一", "二", "三", "四", "五", "六", "日"],
months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
monthsShort: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
today: "今天",
suffix: [],
meridiem: ["上午", "下午"]
};
var pic=$('.form_datetime').datetimepicker({
format: "yyyy-mm-dd hh:ii",
autoclose: true,
todayBtn: true,
language:'zh-CN',
pickerPosition:"bottom-left"
});
$(function(){
var chart=$("#chart").get(0);
var myChart=echarts.init(chart);
//異步加載數據
var date1=new Date();
$('.form_datetime').data("datetimepicker").setDate(date1);
var year1=date1.getYear()+1900;
var month1=date1.getMonth()+1;
var day1=date1.getDate();
var hours1=date1.getHours();
loadData(myChart,3,year1,month1,day1,hours1);
var chart2=$("#chart2").get(0);
var myChart2=echarts.init(chart2);
loadMethodsData(myChart2,3,year1,month1,day1,hours1);
/*
$("#type").change(function(){
var type=$(this).val();
var date=$('.form_datetime').data("datetimepicker").getDate();
var year=date.getYear()+1900;
var month=date.getMonth()+1;
var day=date.getDate();
var hours=date.getHours();
loadData(myChart,type,year,month,day,hours);
loadMethodsData(myChart2,type,year1,month1,day1,hours1);
//用戶獲取時間數據
});
*/
$("#search").click(function(){
var type=$("#type").val();
var date=new Date($("#dates").val());
var year=date.getYear()+1900;
var month=date.getMonth()+1;
var day=date.getDate();
var hours=date.getHours();
loadData(myChart,type,year,month,day,hours);
loadMethodsData(myChart2,type,year1,month1,day1,hours1);
});
});
function loadMethodsData(myChart,type,year,month,day,hours){
var title="";
if(type==1){
title="年請求量"
}else if(type==2){
title="月請求量"
}else if(type==3){
title="日請求量"
}else if(type==4){
title="時請求量"
}
$.ajax({
url:'/interfaceCounter/counterMathods.do',
data:{'appId':10010,'type':type,'year':year,'month':month,'day':day,'hour':hours},
dataType:'json',
type:'post',
success:function(data){
if(data.errCode==0){
var dataX=data.dataX;
var dataY=data.dataY;
var option = {
dataZoom: {
orient: 'vertical', // 佈局方式,默認爲水平佈局,可選爲:
backgroundColor: 'rgba(0,0,0,0)', // 背景顏色
dataBackgroundColor: '#eee', // 數據背景顏色
fillerColor: 'rgba(144,197,237,0.2)', // 填充顏色
handleColor: 'rgba(70,130,180,0.8)' // 手柄顏色
},
title : {
text: title
},
tooltip : {
trigger: 'axis'
},
legend: {
data:['接口請求']
},
toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
magicType: {show: true, type: ['line', 'bar']},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : true,
xAxis : [
{
type : 'value',
boundaryGap : [0, 0.01]
}
],
yAxis : [
{
type : 'category',
data : dataY
}
],
series : [
{
name:'接口請求',
type:'bar',
data:dataX
}
]
};
myChart.setOption(option);
}
}
});
}
function loadData(myChart,type,year,month,day,hours){
//設置x周軸單位
var wei="hello";
if(type==1){
wei="年";
}else if(type==2){
wei="月";
}else if(type==3){
wei="日";
}else if(type==4){
wei="時";
}else if(type==5){
wei="分";
}
$.ajax({
url:'/interfaceCounter/counterInterface.do',
data:{'appId':10010,'type':type,'year':year,'month':month,'day':day,'hour':hours},
dataType:'json',
type:'post',
success:function(data){
var chartDate=[];
//var weight=[55.4,55.9,53];
var weight=[];
var weight2=[];
var weight3=[];
//對echarts做基礎配置
if(data.errCode==0){
chartDate=data.dataX;
weight=data.dataY;
weight2=data.sdataY;
for(var i=0;i<weight.length;i++){
var temp=weight[i]-weight2[i];
weight3.push(temp);
}
}
option={
toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
magicType : {show: true, type: ['line', 'bar']},
restore : {show: true},
saveAsImage : {show: true}
}
},
calculable : true,
title:{
text: '請求量走勢圖'
},
legend: {
data:['總請求量','成功請求','失敗請求']
},
tooltip : {
trigger: 'axis',
},
label:{
normal:{
show:true,
position:[0,-20],
textStyle:{
color:"#1daffa"
}
}
},
/*
lineStyle:{
normal:{
color: 'rgba(29, 175, 250,1)',
}
},
itemStyle:{
normal:{
color: 'rgba(29, 175, 250, 0.8)',
}
},
*/
xAxis:[
{
type : 'category',
boundaryGap : false,
data :chartDate,
axisLabel : {
formatter: '{value}'+wei
}
}
],
yAxis:{}
,
series:[
{
name:"總請求量",
type:"line",//折線圖,還有pie(餅狀圖),
data:weight,
itemStyle:{
normal:{
color: 'rgba(255,0,0, 0.8)',
}
}
},
{
name:"成功請求",
type:"line",//折線圖,還有pie(餅狀圖),
data:weight2,
itemStyle:{
normal:{
color: 'rgba(0,0,255, 0.8)',
}
}
},
{
name:"失敗請求",
type:"line",//折線圖,還有pie(餅狀圖),
data:weight3,
itemStyle:{
normal:{
color: 'rgba(0, 255, 0, 0.8)',
}
}
}
]
}
myChart.setOption(option);
}
});
}
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>系統接口詳細信息</title>
<link href="/css/bootstrap.min.css" rel="stylesheet" />
<lin color: 'rgba(255,0,0, 0.8)',
}
}
},
{
name:"成功請求",
type:"line",//折線圖,還有pie(餅狀圖),
data:weight2,
itemStyle:{
normal:{
color: 'rgba(0,0,255, 0.8)',
}
}
},
{
name:"失敗請求",
type:"line",//折線圖,還有pie(餅狀圖),
data:weight3,
itemStyle:{
normal:{
color: 'rgba(0, 255, 0, 0.8)',
}
}
}
]
}
myChart.setOption(option);
}
});
}
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>系統接口詳細信息</title>
<link href="/css/bootstrap.min.css" rel="stylesheet" />
<link href="/js/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css" rel="stylesheet" media="screen">
<link href="/js/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css" rel="stylesheet" media="screen">
</head>
<body>
<div class