JFinal+amazeUI+beetl+layer+shiro+poi+restful+handlebars初認識
剛入職公司,其用的框架為JFinal+amazeUI+beetl+layer+shiro+poi+restful+handlebars。這些一個都不熟悉,沒辦法,只能硬著頭皮上。
經過一週的琢磨,初步搞明白了這些框架的使用場景和基本用法。
JFinal的橫空出世,印證了那一句話:軟體分為兩種,一種設計簡單,明顯沒有Bug;一種設計複雜,沒有明顯Bug。JFinal是一個輕量級的MVC、ORM、AOP框架,作為後端開發的微核心全方位擴充套件的新一代框架,其易用性和開發效率都是難以比肩的,其外掛體系和Db+activeRecord架構也非常好。它主要由JFinalFilter、JFinalConfig、Handler、Interceptor、Controller、Render、Plugin等部分構成。每個部分都是基於介面實現的,支援完整的自定義,使用靈活,擴充套件性強。
其基本執行原理:
從一次新增頁面的add操作請求來看:
1. 首先是客戶端點選新增按鈕,提交一個新增請求,請求中會帶上服務端處理地址url
2. 所有請求都會被JFinalFilter攔截,然後呼叫Handler進行詳細處理
3. Handler是一個鏈條形式的呼叫,包括0-n個自定義Handler,以及最後一個ActionHandler,依次執行,當然可以自定義跳出。
4. 進入ActionHandler後,首先會根據請求的target從快取的ActionMapping中對映獲取到具體操作對應的Action物件,這個物件裡面封裝了方法名、方法上面的攔截器,方法所在的Controller,
5. 接下來通過ActionInvocation的invoke進行具體處理,這是一個明顯的Command模式的實現。首先是攔截器的呼叫,攔截器呼叫中會重新回撥ActionInvocation的invoke,當攔截器呼叫完畢後,會呼叫當前操作的method
6. 當進入具體controller的新增方法add時,呼叫基類的getModel(Systemparam.class);這個方法會從request中解析出所需要的資料,通過反射設定給具體的Model實體類,最終通過ActiveRecord
7. 最後是頁面渲染rerender
Controller的主要作用是從Request中獲取引數,往Request和Session中放入屬性、Cookie,使用ModelInjector的inject方法從Request中獲取model{網頁中的格式為user.name,user.age},該方法有兩個分支,如果model繼承於Model則呼叫set(attrName,attrValue),否則就是普通的JavaBean,呼叫setAttrName(attr)。
Controller呼叫cos框架獲取上傳的檔案,封裝成MultiPartRequest(繼承於HttpServletRequestWrapper),該類可以獲取檔案或者引數。
Handler是處理器,構成責任鏈,因為在handle方法中獲取到了Request和Response,所以它具備對請求的完全控制權。在JFinalFilter的init方法中,構建了這個鏈條,最後一個handler是ActionHandler,並獲取到第一個handler,其配置由JFinalConfig的configHandler完成。
Action就代表Controller中的一個方法,包括Controller這個Class,controllerKey,actionKey,Method,methodName,interceptors,viewPath,是一個簡單的只讀JavaBean。
ActionHandler中的handle方法中呼叫controller的init方法,通過Invocation呼叫controller之中的Interceptor,然後呼叫controller的getRender獲取Render,之後判斷是不是ActionRender,避免呼叫相同的controller的相同方法造成死迴圈。因為在一般的controller的方法中都會呼叫controller中的render()方法系列,將controller中的render引用為某render,故在ActionHandler的handler方法最後呼叫render.render()就會呼叫不同render的render方法。在配置Constans的時候調動setMainRenderFactory,就能設定程式的主Render工廠,以後獲取的就是這個工廠生產的Render,這就是典型的工廠方法模式。
Render代表渲染器,擁有request和response的引用,所以render()方法中就能作不同的處理,例如FileRender就會呼叫response的setHeader(“Content-disposition”,“attachment;filename=...”)等以實現檔案下載;BeetlRender就會呼叫載入模板和繫結屬性哪些方法(見以下分析)。
關於自動掃描classpath和jar包中的AutoBindRoutes的機制:
首先JFinalConfig中的configRoute(Routes me)方法中呼叫me.add(new AutoBindRoutes());其原始碼為
public Routes add(Routes routes) {
if (routes != null) {
routes.config();// very important!!!
map.putAll(routes.map);
viewPathMap.putAll(routes.viewPathMap);
}
return this;
}
使得Routes的map和viewPathMap中添加了AutoBindRoutes的map和viewPathMap,這個方法中,呼叫了routes.config方法,這個方法就要求你自己配置你的map和viewPathMap,這個是典型的模板方法模式。AutoBindRoutes繼承於Routes,其config方法中,
public void config()
{
List controllerClasses = ClassSearcher.of(Controller.class).includeAllJarsInLib(this.includeAllJarsInLib).injars(this.includeJars).search();
ControllerBind controllerBind = null;
for (Class controller : controllerClasses)
if (!this.excludeClasses.contains(controller))
{
controllerBind = (ControllerBind)controller.getAnnotation(ControllerBind.class);
if (controllerBind == null) {
if (this.autoScan)
{
add(controllerKey(controller), controller);
} } else if (StrKit.isBlank(controllerBind.viewPath())) {
add(controllerBind.controllerKey(), controller);
} else {
add(controllerBind.controllerKey(), controller, controllerBind.viewPath());
}
}
}
首先委託ClassSearcher去ClassPath和Jar包中去掃描Controller的子類(要求以Controller結尾,是COC原則),然後檢查該類上是否含有ControllerBind(強制修改路徑的)註解,有的話就按照ControllerBind的路徑執行,否則按照預設的規則執行。ClassSearcher.search方法就自己想吧,程式碼不是很複雜。
至此,AutoBindRoutes中含有了Controller的資訊,在JFinalFilter的init方法中
if (jfinal.init(jfinalConfig, filterConfig.getServletContext()) == false)
throw new RuntimeException("JFinal init error!");
init方法裡面
boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {
this.servletContext = servletContext;
this.contextPath = servletContext.getContextPath();
initPathUtil();
Config.configJFinal(jfinalConfig);// start plugin and init logger factory in this method
constants = Config.getConstants();
initActionMapping();
initHandler();
initRender();
initOreillyCos();
initTokenManager();
return true;
}
configJFinal方法中
static void configJFinal(JFinalConfig jfinalConfig) {
jfinalConfig.configConstant(constants);initLoggerFactory();
jfinalConfig.configRoute(routes);
jfinalConfig.configPlugin(plugins);startPlugins();// very important!!!
jfinalConfig.configInterceptor(interceptors);
jfinalConfig.configHandler(handlers);
}
這個方法中呼叫JFinalConfig的configRoutes就會呼叫前面說的那些方法。此時Config類中就保留了Routes資訊。
initActionMapping方法中
private void initActionMapping() {
actionMapping = new ActionMapping(Config.getRoutes(), Config.getInterceptors());
actionMapping.buildActionMapping();
}
就用Config的getRoutes獲取Routes構造出actionMapping,然後呼叫buildActionMapping
void buildActionMapping() {
mapping.clear();
Set<String> excludedMethodName = buildExcludedMethodName();
ActionInterceptorBuilder interceptorBuilder = new ActionInterceptorBuilder();
Interceptor[] globalInters = interceptors.getGlobalActionInterceptor();
interceptorBuilder.addToInterceptorsMap(globalInters);
for (Entry<String, Class<? extends Controller>> entry : routes.getEntrySet()) {
Class<? extends Controller> controllerClass = entry.getValue();
Interceptor[] controllerInters = interceptorBuilder.buildControllerInterceptors(controllerClass);
boolean sonOfController = (controllerClass.getSuperclass() == Controller.class);
Method[] methods = (sonOfController ? controllerClass.getDeclaredMethods() : controllerClass.getMethods());
for (Method method : methods) {
String methodName = method.getName();
if (excludedMethodName.contains(methodName) || method.getParameterTypes().length != 0)
continue ;
if (sonOfController && !Modifier.isPublic(method.getModifiers()))
continue ;
Interceptor[] methodInters = interceptorBuilder.buildMethodInterceptors(method);
Interceptor[] actionInters = interceptorBuilder.buildActionInterceptors(globalInters, controllerInters, methodInters, method);
String controllerKey = entry.getKey();
ActionKey ak = method.getAnnotation(ActionKey.class);
String actionKey;
if (ak != null) {
actionKey = ak.value().trim();
if ("".equals(actionKey))
throw new IllegalArgumentException(controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank.");
if (!actionKey.startsWith(SLASH))
actionKey = SLASH + actionKey;
}
else if (methodName.equals("index")) {
actionKey = controllerKey;
}
else {
actionKey = controllerKey.equals(SLASH) ? SLASH + methodName : controllerKey + SLASH + methodName;
}
Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
if (mapping.put(actionKey, action) != null)
throw new RuntimeException(buildMsg(actionKey, controllerClass, method));
}
}
// support url = controllerKey + urlParas with "/" of controllerKey
Action actoin = mapping.get("/");
if (actoin != null)
mapping.put("", actoin);
}
這裡面就涉及Before、Clear、ActionKey的執行邏輯(略)。
AmazeUI是一個前端框架,主要提供一些元件和佈局。
beetl是新一代Java模板引擎,在後端執行,通過ResoureLoader和Configeration獲取模板,編譯後通過繫結資料渲染出需要的頁面。與JFinal的整合就是通過註冊一個BeetlRenderFactory(me.setMainRenderFactory(new BeetlRenderFactory());),如此在渲染的時候就生成BeetlRender進行渲染,當然也會執行beetl的一些步驟。通過看原始碼知道,BeetlRenderFactory.getRender方法返回一個BeetlRender,他繼承於Render,在render方法中
this.response.setContentType(contentType);
WebRender webRender = new WebRender(this.gt);
webRender.render(this.view, this.request, this.response, new Object[0]);
這個render方法中
Enumeration attrs = request.getAttributeNames();
while (attrs.hasMoreElements())
{
String attrName = (String)attrs.nextElement();
template.binding(attrName, request.getAttribute(attrName));
}
WebVariable webVariable = new WebVariable();
webVariable.setRequest(request);
webVariable.setResponse(response);
template.binding("session", new SessionWrapper(request.getSession(false)));
template.binding("servlet", webVariable);
template.binding("request", request);
template.binding("ctxPath", request.getContextPath());
這就是在頁面中能夠使用request中的資料的奧祕。
layer是一個效果很好的彈出層。
shiro是一個可以認證、授權、加密、會話管理、與Web整合、快取的Java安全框架。目前還沒研究透徹。
poi用於生成Excel表格。
restful主要是控制程式碼風格的。
handlebars是一個網頁前端js的模板技術,在瀏覽器view source的時候還能看見其特有的語法{{}},說明是在瀏覽器中執行的。基本的使用步驟是
1:用script標籤放入模板程式碼:
<script id="entry-template" type="text/x-handlebars-template">
template content
</script>
2:編譯模板
var source = $("#entry-template").html();
var template = Handlebars.compile(source);
3:引入資料,當然這個資料的來源就不定了,可以是本地的,也可以是伺服器來的
var context = {title: "My New Post", body: "This is my first post!"}
var html = template(context);
得到下面的HTML
<div class="entry">
<h1>My New Post</h1>
<div class="body">
This is my first post!
</div>
</div>
還可以通過註冊函式實現自己的邏輯
Handlebars.registerHelper('list', function(items, options) {
var out = "<ul>";
for(var i=0, l=items.length; i<l; i++) {
out = out + "<li>" + options.fn(items[i]) + "</li>";
}
return out + "</ul>";
});
{{#list people}}{{firstName}} {{lastName}}{{/list}}使用一下資料
{
people: [
{firstName: "Yehuda", lastName: "Katz"},
{firstName: "Carl", lastName: "Lerche"},
{firstName: "Alan", lastName: "Johnson"}
]
}
就能渲染出以下效果
<ul>
<li>Yehuda Katz</li>
<li>Carl Lerche</li>
<li>Alan Johnson</li>
</ul>
以上是對這些框架的一個初步認識,隨著時間的推移和我的堅持,應該能啃下他們。
相關推薦
JFinal+amazeUI+beetl+layer+shiro+poi+restful+handlebars初認識
剛入職公司,其用的框架為JFinal+amazeUI+beetl+layer+shiro+poi+restful+handlebars。這些一個都不熟悉,沒辦法,只能硬著頭皮上。 經過一週的琢磨,初步搞明白了這些框架的使用場景和基本用法。 JFinal的橫空出世,印證了那一
springboot2.0---02、beetl整合shiro
第一步、Maven <dependency> <groupId>com.ibeetl</groupId> <artifactId>beetl-framework-starter</artifa
jfinal 配置beetl模板引擎
新建屬性功能檔案“beetl.properties” # To change this license header, choose License Headers in Project Properties. # To change this template file
談談你對restful規範的認識?
#首先restful是一種軟體架構風格或者說是一種設計風格,並不是標準,它只是提供了一組設計#原則和約束條件,主要用於客戶端和伺服器互動類的軟體。 #就像設計模式一樣,並不是一定要遵循這些原則,而是基於這個風格設計的軟體可以更簡潔,更#有層次,我們可以根據開發的實際情況,做相應的改變。 #
RESTful 的基本認識
在很早之前接觸 Spring MVC 的時候,都知道 Spring MVC 支援 RESTful 風格API的開發,但對於 RESTful 只是有個模糊的認識,以至於甚至在開發寫出來的介面其實不符合 RESTful 的要求。 定義 REST 的全稱是 R
SSM組合+ springmvc+mybatis+shiro+restful+bootstrap
讀寫 安全 commons 核心 cit 支持 服務 編碼 數據 平臺簡介 Jeesz是一個分布式的框架,提供項目模塊化、服務化、熱插拔的思想,高度封裝安全性的Java EE快速開發平臺。 Jeesz本身集成Dubbo服務管控、Zookeep
分布式框架簡介SSM組合+ springmvc+mybatis+shiro+restful+bootstrap
dubbo+springmvc+mybatis+ehcache+redis J2ee分布式架構 restful kafka shiro 摘要: 核心框架:spring framework 安全框架:Apache Shiro 1.2 視圖框
Spring Cloud + Spring Boot + Mybatis + shiro + RestFul + 微服務 技術分享
trap 企業 緩存 瓶頸 定位 spa comm 功能 中心 1. 介紹 Commonservice-system是一個大型分布式、微服務、面向企業的JavaEE體系快速研發平臺,基於模塊化、服務化、原子化、熱插拔的設計思想,使用成熟領先的無商業限制的主流開源技術構建
企業分布式微服務雲架構技術分享 Spring Cloud + Spring Boot + Mybatis + shiro + RestFul + 微服務
行數 進行 互聯網產品 strong 日誌管理 平臺 bootstra work oot 1. 介紹 Commonservice-system是一個大型分布式、微服務、面向企業的JavaEE體系快速研發平臺,基於模塊化、服務化、原子化、熱插拔的設計思想,使用成熟領先的無
SpringBoot+JWT+Shiro+MybatisPlus實現Restful快速開發後端腳手架
防火 算法 錯誤 模塊 mys 管理員 pro 其他 col 一、背景前後端分離已經成為互聯網項目開發標準,它會為以後的大型分布式架構打下基礎。SpringBoot使編碼配置部署都變得簡單,越來越多的互聯網公司已經選擇SpringBoot作為微服務的入門級微框架。 Myba
jfinal整合shiro樣例
之前看了一篇部落格介紹的jfinal2.0整合shiro的,我仿照那個寫了一個jfinal3.4整合shiro的,簡單整合,樣例 目錄結構圖: jar包目錄: web.xml <?
jfinal 整合shiro的使用
meaven 專案轉化為 web 專案並在 tomcat 釋出過程:http://www.cnblogs.com/zhanggl/p/4733654.html shiro 筆記 1.shiro jar匯入 <dependency&g
Jfinal配合Shiro進行許可權控制
web專案總免不了使用者的管理與註冊,需求稍微再多一點兒,就涉及使用者的角色及許可權管理了,下面根據自己專案的實際經驗,介紹如何在Jfinal專案中使用Shiro來進行簡單的登陸及許可權管理。 主角簡介 Jfinal 位居開源中國年度熱門開源專案前列,簡單
Jfinal與shiro整合實現動態URL鑑權,不裝外掛只需要一個類
Jfinal與Shiro整合,有瑪雅牛和dreamip兩個Jfinal外掛,但還是想以簡單的方式實現動態URL鑑權。 本人的實現思路是,利用Shiro本身的過濾器擴充套件來實現動態通過資料庫URL授權。方法如下: 1. 新建一個JFinal Maven專案 2. pom.x
jfinal+poi匯出excel
廢話不說了,開始了! 方案一:JFinal的renderFile("路徑")功能 先說說我的邏輯: 前臺頁面點選請求傳送到後臺Controller,然後Controller層主要根據所需條件進行表格的組裝,組裝好上傳到伺服器後,然後跳轉到前臺直接顯示下載框,下載即可。 前臺jsp部分: <
給JFinal新增Shiro外掛功能,支援Shiro所有註解-使用篇
基於JDK1.6打包好的包括原始碼的Shiro外掛在以下地址: http://git.oschina.net/myaniu/jfinalshiroplugin/blob/master/dist/JFinalShiroPlugin-1.0.jar Shiro共有5個註解,
RESTful API 設計指南
head 簡單 option eat set 取出 tro 其他 first 網絡應用程序,分為前端和後端兩個部分。當前的發展趨勢,就是前端設備層出不窮(手機、平板、桌面電腦、其他專用設備……)。 因此,必須有一種統一的機制,方便不同的前端設備與後端進行通信。這
POI操作Excel詳解,讀取xls和xlsx格式的文件
shee xss split 類型 後綴 .sh lan xls lin package org.ian.webutil; import java.io.File; import java.io.FileInputStream; import java.io.FileN
Yii2 Restful Api 401
原因 數據 app -s style font code ont ram 采用Yii2 Restful Api方式為APP提供數據,默認你已經做好了所有的編碼和配置工作。采用Postman測試接口: 出現這個畫面的一個可能原因是:access_token的寫法有誤,如果你
使用POI操作Excel時new XSSFWorkbook ()報錯java.lang.NoSuchMethodError解決方式
lin line java sts factor 出現 class padding test 使用最新的POI3.11時,在執行 Workbook workBook = new XSSFWorkbook ();這段代碼時出現錯誤: java.lang.NoSu