1. 程式人生 > >spring-boot-admin原始碼分析及單機監控spring-boot-monitor的實現(三)

spring-boot-admin原始碼分析及單機監控spring-boot-monitor的實現(三)

SpringBootMonitor


spring-boot-admin原始碼分析及單機監控spring-boot-monitor的實現(一)

spring-boot-admin原始碼分析及單機監控spring-boot-monitor的實現(二)

spring-boot-admin原始碼分析及單機監控spring-boot-monitor的實現(三)

1.spring-boot-monitor設計


設計我們自己的springbootmonitor,就不能用springbootadmin的那套東西,需要自己畫頁面。

新建登陸頁面login.html。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>sbim monitor</title>
    <link href='css/bootstrap.min.css' rel="stylesheet" >
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <style type="text/css">
      /* Override some defaults */
      html, body {
        background-color: #eee;
      }
      body {
        padding-top: 40px; 
      }
      .container {
        width: 300px;
      }

      /* The white background content wrapper */
      .container > .content {
        background-color: #fff;
        padding: 20px;
        margin: 0 -20px; 
        -webkit-border-radius: 10px 10px 10px 10px;
           -moz-border-radius: 10px 10px 10px 10px;
                border-radius: 10px 10px 10px 10px;
        -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
           -moz-box-shadow: 0 1px 2px rgba(0,0,0,.15);
                box-shadow: 0 1px 2px rgba(0,0,0,.15);
      }

    .login-form {
      margin-left: 65px;
    }
  
    legend {
      margin-right: -50px;
      font-weight: bold;
      color: #404040;
    }

    </style>

</head>
<body>
  	<div class="container">
      	<div class="content">
          	<div class="row">
              	<div class="login-form">
                  	<h2>Login</h2>
                  	<form id="loginForm" method="post" autocomplete="off" >
                      	<fieldset>
                      	  	<div id="alertInfo" class="alert alert-error clearfix" style="margin-bottom: 5px;width: 195px; padding: 2px 15px 2px 10px;display: none;">
                      	  		The username or password you entered is incorrect.
						  	</div>
                          	<div class="clearfix">
                              	<input type="text" placeholder="使用者名稱" name="loginUsername" >
                          	</div>
                          	<div class="clearfix">
                              	<input type="password" placeholder="密碼" name="loginPassword">
                          	</div>
                          	<button id="loginBtn" class="btn btn-primary" type="button">Sign in</button>
                          	<button class="btn" type="reset">Reset</button>
                      	</fieldset>
                  	</form>
              	</div>
          	</div>
      	</div>
  	</div> <!-- /container -->
	<script type="text/javascript">
  		$.namespace("sbim.login");
  		sbim.login = function () {  
   			return  {
	  			login : function() {
	  				$.ajax({
	  				  type: 'POST',
	  				  url: "api/login",
	  				  data: $("#loginForm").serialize(),
	  				  success: function(data) {
	  					if("success" == data)
	  						location.href = "index.html";
	  					else {
	  						$("#alertInfo").show();
	  						$("#loginForm")[0].reset();
	  					}
	  				  },
	  				  dataType: "text"
	  				});
	  			}
   			}
  		}();

  		$(document).ready(function() {
  			$("#loginBtn").click(sbim.login.login);
 		});
  	</script>
</body>
</html>

使用jquery與後臺進行互動。

2.spring-boot-monitor後臺設計

package com.cff.boot.monitor.web;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.http.HttpRequest;
import org.springframework.web.bind.annotation.RequestBody;
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.ResponseBody;

import com.cff.boot.monitor.config.MonitorProperties;
import com.cff.boot.monitor.model.AppInfo;
import com.cff.boot.monitor.model.SbimUser;
import com.cff.boot.monitor.store.SimpleAppInfoStore;

@WebController
@RequestMapping("/sbim/api")
@ResponseBody
public class RestApiController {
	private final MonitorProperties monitorProperties;
	private final SimpleAppInfoStore simpleAppInfoStore;
	private String contextPath = "/";
	public RestApiController(MonitorProperties monitorProperties, SimpleAppInfoStore simpleAppInfoStore) {
		this.monitorProperties = monitorProperties;
		this.simpleAppInfoStore = simpleAppInfoStore;
		contextPath = monitorProperties.getContextPath();
	}
	
	@RequestMapping(value= "/login", method=RequestMethod.POST)
    public String login(@RequestParam String loginUsername, @RequestParam String loginPassword, HttpServletRequest req) {
		SbimUser sbimUser = new SbimUser();
		sbimUser.setLoginUsername(loginUsername);
		sbimUser.setLoginPassword(loginPassword);
		if (monitorProperties.getUsername().equals(sbimUser.getLoginUsername())
				&& monitorProperties.getPassword().equals(sbimUser.getLoginPassword())){
			req.getSession().setAttribute("sbimUser", sbimUser);
	        return "success";
		} else {
			return "failed";
		}
		
    }
	
	@RequestMapping(value= "/appInfo", method=RequestMethod.POST)
    public List<AppInfo> appInfo(HttpServletRequest req) {
		SbimUser sbimUser = (SbimUser) req.getSession().getAttribute("sbimUser");
		if(sbimUser == null){
			return null;
		}
		
		List<AppInfo> lists = simpleAppInfoStore.getAll();
		return lists;
    }
	
	@RequestMapping(value= "/appRemove", method=RequestMethod.POST)
    public List<AppInfo> appRemove(HttpServletRequest req) {
		SbimUser sbimUser = (SbimUser) req.getSession().getAttribute("sbimUser");
		if(sbimUser == null){
			return null;
		}
		String appName = req.getParameter("appName");
		simpleAppInfoStore.remove(appName);
		List<AppInfo> lists = simpleAppInfoStore.getAll();
		return lists;
    }
}

後臺提供登陸介面,可以將登陸資訊直接放入session,這樣做的目的是可以不用使用springsecurity控制登陸。自己實現簡單的登陸。


3.SimpleAppInfoStore應用資訊儲存


雖然是單機監控,我們還是要儲存應用資訊,方便與前臺進行互動。


package com.cff.boot.monitor.store;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.cff.boot.monitor.model.AppInfo;

public class SimpleAppInfoStore {
	private final ConcurrentMap<String, AppInfo> map = new ConcurrentHashMap<>();

	public SimpleAppInfoStore() {
	}
	
	public void addApp(AppInfo appInfo){
		map.put(appInfo.getAppId(), appInfo);
	}
	
	public void remove(String appId){
		map.remove(appId);
	}
	
	public List<AppInfo> getAll(){
		List<AppInfo> lists = new ArrayList<AppInfo>(map.values()); 
		return lists;
	}
	
	public AppInfo getApp(String appId){
		return map.get(appId);
	}
}

類似於springbootadmin,我們都使用ConcurrentMap去儲存應用資訊,雖然並不必要。
這樣,一個簡單的監控登陸+首頁已經ok了。剩下的就是不斷新增前臺頁面和後臺邏輯的問題了。