[領域驅動設計實踐]並不想吹牛皮,但!爲了把Github博客粉絲轉移到公衆號,我幹了!

微信公衆號:bugstack蟲洞棧 沉澱、分享、成長,專一於原創專題案例,以最易學習編程的方式分享知識,讓本身和他人都能有所收穫。目前已完成的專題有;Netty4.x實戰專題案例、用Java實現JVM、基於JavaAgent的全鏈路監控、手寫RPC框架、架構設計專題案例[Ing]等。css

1. 前言介紹

這個!截至到19年11月我已經工做6年了,從業Java但也折騰過C#、搞PHP也弄過中繼器、IO板卡,彷佛我就是一個很喜歡在技術上折騰的人!與此同時,我也搞了6年的我的小網站,它們的呈現形式多種多樣;有用PHP本身搗鼓的技術站用於分享資料、書籍、軟件等、有用PHPWIND和DISCUZ的搭建的我的論壇、有用emlog和wordpress搭建的我的博客、也有借用於github+hexo/jekyll的能力組裝出的技術博客。但無一例外它們都戰死於征戰的路上了,亡於;org域名不能備案、PHP服務器癱瘓被清空、http鏈接被注入惡意內容、定位不許確常常換模式、缺乏核心優質內容等等。但!老衲的心依然如春(cun),由於喜歡幹一件事,每每來自於幹一了件喜歡的事!html

因此!從19年開始我又繼續寫博客了,註冊了新的域名bugstack.cn,備了案、買了服務器、還喊了新的口號;沉澱、分享、成長,讓本身和他人都能有所收穫!而且將塵封已久的微信公衆號找回;結構上調整、內容上佈局、粉絲上求關注。在這期間遇到了更大的牛;小灰、王二哥、純潔的微笑還有鬆哥等一羣夥伴,從他們那學到不少知識,真的很是感謝!前端

那麼!此次的產品功能總結一句話就是;將基於Github+Jekyll搭建的靜態博客與我並未開發過的微信公衆號功能打通,經過在文章短口令碼加鎖引導用戶到公衆號內回覆密碼可解鎖內容,以此來得到粉絲關注,固然若是取消關注了則文章繼續鎖定。java

在多說一句,我理解的產品;實際上是使用研發技術力搭建出能夠用於承載接收用戶在各類設備上所生產的行爲數據的一種產品化服務。因此有些產品在作減法,同時也有爲豐富的功能作加法,但究其一點咱們其實都是在爲接收有價值數據服務的。興衰存亡,皆在覈心數據沉澱與運做上!mysql

2. 流程設計

爲了使博客粉絲主動關注微信公衆號,咱們在用戶初次瀏覽文章時增長權限驗證,給每個用戶都生成一個惟一碼引導用戶在公衆號內回覆解鎖文章,以此來與微信openid對應。當用戶取消關注時則進行刪除openid或標記狀態,使得用戶沒法繼續瀏覽文章。其實爲了更好的體驗,我參照了大牛的方式內容60%的區域可見,其他內容漸進遮擋,蒙朧朧的感受還挺美。總體流程圖以下; git

微信公衆號:bugstack蟲洞棧 & 流程圖設計

3. 功能實現

爲了實現本產品功能,我準備了;github

  1. 微信公衆號;bugstack蟲洞棧
  2. 博客;本文使用的是github+jekyll;地址:bugstack.cn
  3. 域名;域名申請比較簡單,但可能針對不一樣的服務商還必須備案後纔可使用
  4. 友盟;主要爲了獲取全局的惟一id值,也可使用其餘具有此功能的產品或者本身實現
  5. 部署環境;Java雲服務器、Mysql雲數據庫、https證書、Jdk1.八、tomcat1.8,雲市場比較多按需購買,若是是本地調試可使用https://natapp.cn,作免費網絡穿透映射

3.1 前端

前端主要負責針對發佈時設置了look: need的文章,在用戶瀏覽文章檢查是否有權限查看所有內容,當用戶沒有權限時隱藏文章60%內容,並經過頁面結尾提醒用戶在公衆號內回覆口令解鎖文章。web

  1. 找到加鎖文章容器ID,文章容器選擇器:article.post.container.need,拿到選擇器ID針對這類文章進行縮小隱藏處理。
<article class="post container need lock" itemscope="" itemtype="http://schema.org/BlogPosting" style="height: 4400px;">

    <div class="row">

        
        <div class="col-md-9 markdown-body">

            <h2 id="前言介紹">前言介紹</h2>
<p>爲何會有路由層?由於在微服務架構設計中,每每並不會直接將服務暴漏給調用端,而是經過調用路由層進行業務隔離,以達到不一樣的業務調用對應的服務模塊。</p>

<p><strong>Spring Cloud Zuul</strong></p>
複製代碼
  1. 使用Jquery把文章所在容器高度縮小,這樣會把內容進行壓縮
// 文章所在容器的選擇器
var articleSelector = 'article.post.container.need';
// 找到文章所在的容器
var $article = $(articleSelector);

// 文章的實際高度
var article = $article[0], height = article.clientHeight;
// 文章隱藏後的高度
var halfHeight = height * 0.4;
// 隱藏縮小
$article.css('height', halfHeight + 'px');
$article.addClass('lock');
複製代碼
  1. 給文章加一點朦朧感,漸變隱藏
.asb-post-01 {
 position: absolute;
 left: 0;
 bottom: 0;
 width: 100%;
 display: none;
 z-index: 10000;
margin-bottom: 0;
}

.asb-post-01 .mask {
 height: 240px;
 width: 100%;
 background: -webkit-gradient(linear, 0 top, 0 bottom, from(rgba(255, 255, 255, 0)), to(#fff));
}
複製代碼
  1. 從UM全局惟一ID中獲取token 友盟做爲網站數據採集服務,會生成一個針對用戶的全局惟一值UM_distinctid,而咱們須要就使用這個值部分截取後做爲惟一token加鎖鑰匙
UM_distinctid = 16e9cd64925334-0882eb883c9554-7711b3e-144000-16e9cd6492631c
複製代碼
function getCookie(name) {
	var value = "; " + document.cookie;
	var parts = value.split("; " + name + "=");
	if (parts.length == 2)
		return parts.pop().split(";").shift();
}

function getToken() {
    let value = getCookie('UM_distinctid');
    if (!value) {
        return getUUID().toUpperCase();
    }
    return value.substring(value.length - 6).toUpperCase();
}
複製代碼
  1. 定時輪旋檢查是否關注公衆號並解鎖,能夠優化寫入全局Jquery值或者記錄在cookie,減小輪詢檢查次數
// 查詢後端的結果
var _detect = function() {
	console.info(token);
	$.ajax({
		url : 'https://bugstack.cn/xx/xx/check',
		type: "GET",
		dataType: "text",
		data : {
			token : token
		},
		success : function(data) {
			console.log(data);
			if (data == 'refuse') {
				_lock();
			} else {
				_unlock();
			}
		},
		error : function(data) {
			_unlock();
		}
	})
}

// 定時任務
_detect();
setInterval(function() {
	_detect();
}, 5000);
複製代碼
  1. 引導用戶關注公衆號 如今將token值回顯到頁面,提醒用戶關注公衆號回覆口令解鎖所有文章,以此來獲得粉絲的關注。效果以下;

微信公衆號:bugstack蟲洞棧 & 文章加鎖效果

3.2 後端

  1. 本地環境開發須要安裝(免費)natapp.cn/,作網絡穿透便於咱們進…
  2. 服務度三個主要接口;1同名稱的get、post請求,分別用於公衆號驗驗、接收用戶行爲與回覆信息。2給博客提供驗證是否解鎖接口
  3. 在微信公衆號;開發->基礎設置(服務器配置),修改配置內容並開啓服務,此時服務端會收到驗證請求信息
  4. Java服務度採用領域驅動設計微服務方式開發,DDD的開發模式會更加清晰以及易於後續功能的拓展
  5. (提醒)我的微信號,部分接口權限是沒有的,同時若是開啓開發者功能配置後,自定義菜單和自定義回覆都會失效。而自定義菜單又不開放給我的微信號,因此須要再次配置開啓,可是不能修改

開發環境

  1. jdk 1.八、tomcat八、idea201八、Maven3
  2. Spring Boot 2.1.2.RELEASE
  3. mysql 5.6
  4. natapp 網絡穿透

工程代碼

itstack-ark-wx & 領域驅動設計方式設計ajax

itstack-ark-wx
└── src
    ├── main
    │   ├── java
    │   │   └── org.itstack.demo
    │   │       ├── application
    │   │       │	├── UserLockAuthService.java
    │   │       │	├── WxReceiveService.java	
    │   │       │	└── WxValidateService.java	
    │   │       ├── domain
    │   │       │	├── lockauth
    │   │       │	│   ├── repository
    │   │       │	│   │   └── IUserAuthPatrolRepository.java	
    │   │       │	│   └── service
    │   │       │	│       └── UserLockAuthServiceImpl.java		
    │   │       │	├── receive
    │   │       │	│   ├── model
    │   │       │	│   │   ├── BehaviorMatter.java
    │   │       │	│   │   └── MessageTextEntity.java
    │   │       │	│   ├── repository
    │   │       │	│   │   └── IUserAuthGrantRepository.java	
    │   │       │	│   └── service
    │   │       │	│       ├── engine
    │   │       │	│       │   ├── impl	
    │   │       │	│       │   │	└── MsgEngineHandle.java
    │   │       │	│       │   ├── Engine.java	
    │   │       │	│       │   ├── EngineBase.java	
    │   │       │	│       │   └── EngineConfig.java	
    │   │       │	│       ├── logic
    │   │       │	│       │   ├── impl	
    │   │       │	│       │   │	├── AnswerFilter.java
    │   │       │	│       │   │	├── SubscribeFilter.java
    │   │       │	│       │   │	├── UnlockFilter.java
    │   │       │	│       │   │	└── UnsubscribeFilter.java	
    │   │       │	│       │   └── LogicFilter.java	
    │   │       │	│       └── WxReceiveServiceImpl.java	
    │   │       │	└── validate
    │   │       │	    └── service
    │   │       │	        └── WxValidateServiceImpl.java	
    │   │       ├── infrastructure
    │   │       │	├── common
    │   │       │	│   └── Constants.java
    │   │       │	├── dao	
    │   │       │	│   └── UserAuthDao.java	
    │   │       │	├── po
    │   │       │	│   └── UserAuth.java		
    │   │       │	├── repository
    │   │       │	│   ├── UserAuthGrantRepository.java	
    │   │       │	│   └── UserAuthPatrolRepository.java	
    │   │       │	└── util
    │   │       │	    ├── sdk
    │   │       │	    │   └── SignatureUtil.java	
    │   │       │	    └── XmlUtil.java
    │   │       ├── interfaces
    │   │       │	├── BlogController.java
    │   │       │	└── WxPortalController.java
    │   │       └── WxApplication.java
    │   └── resources	
    │       ├── mybatis
    │       └── application.yml
    └── test
         └── java
             └── org.itstack.ark.wx.test
                 └── ApiTest.java

複製代碼

itstack-ark-wx & 建表語句redis

CREATE TABLE
    user_auth
    (
        id bigint NOT NULL AUTO_INCREMENT,
        openId VARCHAR(64),
        token VARCHAR(16) NOT NULL,
        uuid VARCHAR(128),
        createTime DATETIME,
        updateTime DATETIME,
        PRIMARY KEY (id, token),
        CONSTRAINT idx_uuid UNIQUE (uuid)
    )
    ENGINE=InnoDB DEFAULT CHARSET=utf8
複製代碼

講解部分重點代碼塊,完整代碼下載關注公衆號;bugstack蟲洞棧 & 回覆:itstack-ark-wx

interfaces接口層

WxPortalController.java & 接收微信公衆號驗籤與行爲信息通知

  • 微信公衆號都是經過服務提供方的一個接口的get/post請求來執行操做的{這樣設計真sao但真香}

  • get接口主要是驗證簽名

  • post接口會收到;關注、取消關注、用戶的回覆信息

/** * 微信公衆號:bugstack蟲洞棧 * 純潔版博客:https://bugstack.cn * 沉澱、分享、成長,讓本身和他人都能有所收穫! * Create by 付政委 on @2019 */
@RestController
@RequestMapping("/wx/portal/{appid}")
public class WxPortalController {

    private Logger logger = LoggerFactory.getLogger(WxPortalController.class);

    @Autowired
    private WxValidateService wxValidateService;
    @Autowired
    private WxReceiveService wxReceiveService;

    /** * 處理微信服務器發來的get請求,進行簽名的驗證 * <p> * appid 微信端AppID * signature 微信端發來的簽名 * timestamp 微信端發來的時間戳 * nonce 微信端發來的隨機字符串 * echostr 微信端發來的驗證字符串 */
    @GetMapping(produces = "text/plain;charset=utf-8")
    public String validate(@PathVariable String appid, @RequestParam(value = "signature", required = false) String signature, @RequestParam(value = "timestamp", required = false) String timestamp, @RequestParam(value = "nonce", required = false) String nonce, @RequestParam(value = "echostr", required = false) String echostr) {
        try {
            logger.info("微信公衆號驗籤信息{}開始 [{}, {}, {}, {}]", appid, signature, timestamp, nonce, echostr);
            if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) {
                throw new IllegalArgumentException("請求參數非法,請覈實!");
            }
            boolean check = wxValidateService.checkSign(signature, timestamp, nonce);
            logger.info("微信公衆號驗籤信息{}完成 check:{}", appid, check);
            if (!check) return null;
            return echostr;
        } catch (Exception e) {
            logger.error("微信公衆號驗籤信息{}失敗 [{}, {}, {}, {}]", appid, signature, timestamp, nonce, echostr, e);
            return null;
        }
    }

    /** * 此處是處理微信服務器的消息轉發的 */
    @PostMapping(produces = "application/xml; charset=UTF-8")
    public String post(@PathVariable String appid, @RequestBody String requestBody, @RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, @RequestParam("openid") String openid, @RequestParam(name = "encrypt_type", required = false) String encType, @RequestParam(name = "msg_signature", required = false) String msgSignature) {
        try {
            logger.info("接收微信公衆號信息請求{}開始 {}", openid, requestBody);
            MessageTextEntity message = XmlUtil.xmlToBean(requestBody, MessageTextEntity.class);
            BehaviorMatter behaviorMatter = new BehaviorMatter();
            behaviorMatter.setOpenId(openid);
            behaviorMatter.setFromUserName(message.getFromUserName());
            behaviorMatter.setMsgType(message.getMsgType());
            behaviorMatter.setContent(message.getContent());
            behaviorMatter.setEvent(message.getEvent());
            behaviorMatter.setCreateTime(new Date(Long.parseLong(message.getCreateTime()) * 1000L));
            // 處理消息
            String result = wxReceiveService.doReceive(behaviorMatter);
            logger.info("接收微信公衆號信息請求{}完成 {}", openid, result);
            return result;
        } catch (Exception e) {
            logger.error("接收微信公衆號信息請求{}失敗 {}", openid, requestBody, e);
            return "";
        }
    }

}
複製代碼

BlogController.java & 博客驗權接口,用於判斷文章是否解鎖

  • 由於咱們這個服務部署在二級域名下,所以須要設置跨域訪問
  • 因爲咱們網站是https加密,那麼非https是不能被訪問,須要下載安裝證書到tomcat服務器
  • 本接口只返回success和refuse,經過便可解鎖
/** * 微信公衆號:bugstack蟲洞棧 * 純潔版博客:https://bugstack.cn * 沉澱、分享、成長,讓本身和他人都能有所收穫! * Create by 付政委 on @2019 */
@CrossOrigin("https://bugstack.cn")
@RestController
@RequestMapping("/api")
public class BlogController {

    private Logger logger = LoggerFactory.getLogger(BlogController.class);

    @Autowired
    private UserLockAuthService userLockAuthService;

    @GetMapping(value = "check", produces = "application/json;charset=utf-8")
    public String check(@RequestParam String token) {
        try {
            logger.info("校驗博客瀏覽用戶受權狀態{}開始", token);
            boolean status = userLockAuthService.checkAuth(token);
            logger.info("校驗博客瀏覽用戶受權狀態{}完成", token, status);
            return status ? "success" : "refuse";
        } catch (Exception e) {
            logger.error("校驗博客瀏覽用戶受權狀態{}失敗", token, e);
            return "refuse";
        }
    }

}
複製代碼

application應用層

  • 本層主要定義邏輯分層,屬於很是薄的一層,在一些複雜設計中會有一些服務編排
    • UserLockAuthService 用戶權限驗證
    • WxReceiveService 接收用戶行爲消息
    • WxValidateService 微信公衆號驗籤

UserLockAuthService.java & 定義後由領域層實現

public interface UserLockAuthService {

    boolean checkAuth(String token);

}
複製代碼

domain領域層

  • 領域層完成了;權限驗證、行爲消息處理、公衆號驗籤
  • 這裏最重要的各類行爲消息處理,咱們設計爲決策樹工廠模型,定義了邏輯功能和引擎服務,後續只須要按需擴展便可

logic/LogicFilter.java & 定義邏輯模型,impl中有對應的一組的實現類

public interface LogicFilter {

    String filter(BehaviorMatter request);

}
複製代碼

logic/impl/SubscribeFilter.java & 其中一個實現,關注時行爲處理

@Service("subscribe")
public class SubscribeFilter implements LogicFilter {

    private final String content = "您好!\n" +
            "\n" +
            "很是感謝您關注,微信公衆號:bugstack蟲洞棧 | 也期待您分享給更多小夥伴!\n" +
            "\n" +
            "bugstack蟲洞棧,專一於原創技術專題案例,以最易學習編程開發的方式分享技術知識,讓萌新、小白、大牛都能有所收穫。目前已經完成的專題有;《Netty4.x從入門到實戰》、《手寫RPC框架》、《用Java實現JVM》、《基於JavaAgent的全鏈路監控》、《DDD專題案例》,其餘更多專題還在排兵佈陣中。\n" +
            "\n" +
            "獲取專題案例源碼回覆;netty案例、rpc案例、用Java實現jvm源碼、基於JavaAgent的全鏈路監控案例、DDD落地。\n" +
            "\n" +
            "聯繫做者:付政委 | monkeycode";

    @Override
    public String filter(BehaviorMatter request) {
        return content;
    }

}
複製代碼

engine/impl/MsgEngineHandle.java & 引擎路由調用

@Service("msgEngineHandle")
public class MsgEngineHandle extends EngineBase {

    @Value("${wx.config.originalid:你的Err默認值}")
    private String originalId;

    @Override
    public String process(BehaviorMatter request) throws Exception {
        LogicFilter router = super.router(request);
        if (null == router) return null;
        String resultStr = router.filter(request);
        if (StringUtils.isBlank(resultStr)) return "";
        //反饋信息[文本],暫時只有文本後續按需拓展
        MessageTextEntity res = new MessageTextEntity();
        res.setToUserName(request.getOpenId());
        res.setFromUserName(originalId);
        res.setCreateTime(String.valueOf(System.currentTimeMillis() / 1000L));
        res.setMsgType("text");
        res.setContent(resultStr);
        return XmlUtil.beanToXml(res);
    }

}
複製代碼

infrastructure基礎層

  • 本層主要提供基礎服務能力,包括數據庫操做、緩存操做、工具包等
  • 若是你的服務中由redis能夠在本層來提供
  • 在領域驅動設計中數據庫不提倡共用,是單獨分離,由於此設計中只有用戶表還體現的不明顯

repository/UserAuthGrantRepository.java & 數據庫實現

@Repository("userAuthGrantRepository")
public class UserAuthGrantRepository implements IUserAuthGrantRepository {

    @Autowired
    private UserAuthDao userAuthDao;

    @Override
    public void grantAuth(String openId, String token) {
        UserAuth userAuthReq = new UserAuth();
        userAuthReq.setOpenId(openId);
        userAuthReq.setToken(token);
        userAuthReq.setUuid(openId + "_" + token);
        userAuthDao.insert(userAuthReq);
    }

    @Override
    public void revokeAuth(String openId) {
        userAuthDao.delete(openId);
    }

}
複製代碼

3.3 部署

1. 工程打包

  1. springboot配置打包部署成可運行war包

    pom.xml

    <packaging>war</packaging>
    複製代碼

    WxApplication.java

    @SpringBootApplication
    public class WxApplication extends SpringBootServletInitializer {
    
    	@Override
    	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    		return builder.sources(WxApplication.class);
    	}
    
    	public static void main(String[] args) {
    		SpringApplication.run(WxApplication.class, args);
    	}
    
    }
    複製代碼
  2. 修改配置application.yml,數據庫配置、微信配置

    server:
      port: 80
    
    spring:
    #  datasource:
    #    username: root
    #    password: 123456
    #    url: jdbc:mysql://localhost:3306/itstack-ark-wx?useUnicode=true&characterEncoding=utf8
    #    driver-class-name: com.mysql.jdbc.Driver
    
    
    mybatis:
      mapper-locations: classpath:/mybatis/mapper/*.xml
      config-location:  classpath:/mybatis/config/mybatis-config.xml
    
    # 微信公衆號配置信息
    # originalid:原始ID
    # appid:我的AppID
    # token:開通接口服務自定義設置
    wx:
      config:
    	originalid: xxxxxxx
    	appid: xxxxxxx
    	token: xxxxxxx
    複製代碼

2. 服務上線

  1. 申請雲服務器,目前提供方比較多,通常能夠和域名選擇一個服務商
  2. 準備好Linux服務器jdk1.八、tomcat8
  3. 看我的域名訪問狀況,酌情申請Https,配置RSA
  4. 本地安裝XShell、Xftp,方便部署和文件傳輸
  5. 準備好我的微信公衆號,用於配置服務
  6. 啓動服務
    [root@instance-39394m67 bin]# ./startup.sh
    
     	 .   ____          _            __ _ _
      /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
     ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
      \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
       '  |____| .__|_| |_|_| |_\__, | / / / /
      =========|_|==============|___/=/_/_/_/
      :: Spring Boot ::        (v2.1.2.RELEASE)
    
     2019-11-23 18:10:57.131  INFO 22052 --- [ost-startStop-1] org.itstack.ark.wx.WxApplication         : Starting WxApplication v1.0.0-SNAPSHOT on instance-39394m67 with PID 22052 (/usr/local/java/apache-tomcat-8.5.37/webapps/itstack-ark-wx/WEB-INF/classes started by root in /usr/local/java/apache-tomcat-8.5.37/bin)
     2019-11-23 18:10:57.158  INFO 22052 --- [ost-startStop-1] org.itstack.ark.wx.WxApplication         : No active profile set, falling back to default profiles: default
     2019-11-23 18:10:59.137  INFO 22052 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1890 ms
     2019-11-23 18:11:01.050  INFO 22052 --- [ost-startStop-1] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
     2019-11-23 18:11:01.336  WARN 22052 --- [ost-startStop-1] ion$DefaultTemplateResolverConfiguration : Cannot find template location: classpath:/templates/ (please add some templates or check your Thymeleaf configuration)
     2019-11-23 18:11:01.677  INFO 22052 --- [ost-startStop-1] org.itstack.ark.wx.WxApplication         : Started WxApplication in 5.873 seconds (JVM running for 10.311)
     23-Nov-2019 18:11:01.718 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/java/apache-tomcat-8.5.37/webapps/itstack-ark-wx.war] has finished in [9,226] ms
     23-Nov-2019 18:11:01.720 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/java/apache-tomcat-8.5.37/webapps/ROOT]
     23-Nov-2019 18:11:01.746 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/java/apache-tomcat-8.5.37/webapps/ROOT] has finished in [26] ms
     23-Nov-2019 18:11:01.753 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-80"]
     23-Nov-2019 18:11:01.764 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
     23-Nov-2019 18:11:01.766 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 9326 ms
     2019-11-23 18:11:13.039  INFO 22052 --- [p-nio-80-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
     2019-11-23 18:11:13.059  INFO 22052 --- [p-nio-80-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 20 ms
     2019-11-23 18:11:13.172  INFO 22052 --- [p-nio-80-exec-1] o.i.ark.wx.interfaces.BlogController     : 校驗博客瀏覽用戶受權狀態UDHIUS開始
    複製代碼

3. 功能驗證

  1. 驗證鏈接;bugstack.cn/itstack-dem…

  2. 引導提示;

  3. 文章解鎖;

4. 綜上總結

  1. 仍是很感激那些前途的探路人,爲原創研發貢獻力量
  2. 我博客;bugstack.cn,能夠嘗試驗證或者克隆對應的代碼倉庫
  3. 利用了11月24日週六給本身加個通宵班完成全部代碼的開發和服務申請到部署,從最開始拿到想法到最終實現仍是經歷了不少坎坎坷坷
  4. 這裏面還有不少能夠優化的點以及一些拓展的功能,後續會陸續完善,若是由小夥伴有好的點子歡迎隨時交流
  5. 源碼貢獻給全部研發,微信公衆號內回覆;itstack-ark-wx,便可得到一份基於領域驅動設計開發的微信公衆號與博客打通工程(Star&Frok)
  6. 夜深人靜咣咣敲代碼我也會懷疑,我是誰,我在哪,我在幹什麼!哎,這就是;喜歡幹一份工做,每每來自於幹了一件喜歡的工做

微信公衆號:bugstack蟲洞棧,歡迎關注&獲取源碼
相關文章
相關標籤/搜索