HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
1.configPlugin DruidPlugin druidPlugin = new DruidPlugin(getProperty("jdbcUrl"), getProperty("user"), getProperty("password")); druidPlugin.setFilters("stat,log4j"); me.add(druidPlugin); me.add(new EhCachePlugin()); // 配置ActiveRecord插件 AutoTableBindPlugin arp = new AutoTableBindPlugin(druidPlugin,TableNameStyle.LOWER);//table是實(shí)體的小寫(xiě) me.add(arp); arp.setShowSql(true);
2.實(shí)體類(lèi) @TableBind(tableName="table") public class table extends Model
{ private static final long serialVersionUID = 1L; public static String tableName = "table"; public static final AdminUser table = new table(); public AdminUser getByName(String username){ return dao.findFirst("select * from table where username=" + username); }
3.報(bào)錯(cuò): java.lang.NullPointerException at com.jfinal.plugin.activerecord.Model.find(Model.java:529) at com.jfinal.plugin.activerecord.Model.findFrist(Model.java:546) 來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2019-01-10 15:02:01
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
添加了出不來(lái)啊,在哪里調(diào)用那個(gè)接口
/** * 查詢(xún)菜單 */ MenuApi . getMenu (); /** * 創(chuàng)建菜單 */ MenuApi . createMenu ( String jsonStr ); 看網(wǎng)上寫(xiě)的下面這樣不好用啊
me.add("/msg", WeixinMsgController.class,"/msg");
me.add("/api", WeixinApiController.class, "/api");
me.add("/menu",MenuController.class);
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2016-01-16 18:20:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
@JFinal 你好,想跟你請(qǐng)教個(gè)問(wèn)題:JFinal Weixin怎么創(chuàng)建自定義菜單啊,沒(méi)看懂
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2015-01-30 19:18:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
在處理菜單點(diǎn)擊事件的方法里 WeixinMsgController.processInMenuEvent ,調(diào)用CustomServiceApi.sendMpNews,發(fā)送圖文消息報(bào)下面的錯(cuò)誤,信息能正常接收到,什么原因
SEVERE: /jwx/msg?signature=d8e707c605aa05633ae508908527749f2e65e180×tamp=1537689035&nonce=1093934862&openid=o6fbwt0kWHoj4qYaq8I8YsP5ACI8
java.lang.RuntimeException: File not found : /var/www/ryj/tomcat7/webapps/ROOT/jwx/msg/index.html
at com.jfinal.template.source.FileSource.getContent(FileSource.java:70)
at com.jfinal.template.Engine.buildTemplateBySourceFactory(Engine.java:154)
at com.jfinal.template.Engine.getTemplate(Engine.java:139)
at com.jfinal.render.TemplateRender.render(TemplateRender.java:61)
at com.jfinal.core.ActionHandler.handle(ActionHandler.java:103)
at com.jfinal.core.JFinalFilter.doFilter(JFinalFilter.java:73)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Sep 23, 2018 3:50:35 PM com.jfinal.core.JFinalFilter error
SEVERE: /jwx/msg?signature=d8e707c605aa05633ae508908527749f2e65e180×tamp=1537689035&nonce=1093934862&openid=o6fbwt0kWHoj4qYaq8I8YsP5ACI8
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:636)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:213)
at com.jfinal.render.ErrorRender.render(ErrorRender.java:59)
at com.jfinal.core.ActionHandler.handle(ActionHandler.java:141)
at com.jfinal.core.JFinalFilter.doFilter(JFinalFilter.java:73)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2018-09-23 20:06:02
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>> demo代碼中沒(méi)有給出如何接入微信
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2015-01-14 17:20:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>> 在微信公眾號(hào)開(kāi)發(fā)中,當(dāng)完成某個(gè)任務(wù)后如何在聊天界面推送一條消息,讓用戶(hù)知曉?并在消息中嵌入某個(gè)h5頁(yè)面的鏈接。新手求指點(diǎn)。。。。
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2015-07-07 16:39:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>> JFinal 微信所處理的消息類(lèi)型是不是還不包括以下幾種:scancode_push:掃碼推事件
scancode_waitmsg:掃碼推事件且彈出“消息接收中”提示框pic_sysphoto:彈出系統(tǒng)拍照發(fā)圖pic_photo_or_album:彈出拍照或者相冊(cè)發(fā)圖pic_weixin:彈出微信相冊(cè)發(fā)圖器location_select:彈出地理位置選擇器如果需要擴(kuò)展以上幾種事件類(lèi)型的話(huà)需要在InMsgParaser 類(lèi)中進(jìn)行擴(kuò)展?
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2014-12-18 00:36:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
@JFINAL 波總您好,想請(qǐng)教你一個(gè)問(wèn)題,我參考jfinal-weixin里面的WeixinMsgController的MsgController的MsgInterceptor寫(xiě)了個(gè)攔截器,主要是用來(lái)判斷是否能獲取到參數(shù)code的,如果沒(méi)有這個(gè)參數(shù),我就調(diào)用微信那邊的授權(quán)接口,現(xiàn)在code是能獲取得到,但是用兩個(gè)微信號(hào)訪(fǎng)問(wèn)時(shí),獲取OPENID時(shí)都獲取了第一個(gè)微信號(hào)訪(fǎng)問(wèn)的OPENID,就是只能獲取第一個(gè)微信號(hào)的OPENID,請(qǐng)問(wèn)這個(gè)是什么情況呢?
下面是攔截器代碼
public class BindInterceptor implements Interceptor {
public void intercept(Invocation inv) {
Controller controller = inv.getController();
if (controller instanceof BindController == false)
throw new RuntimeException("控制器需要繼承 BindController");
try {
// 將 ApiConfig 對(duì)象與當(dāng)前線(xiàn)程綁定,以便在后續(xù)操作中方便獲取該對(duì)象: ApiConfigKit.getApiConfig();
ApiConfigKit.setThreadLocalApiConfig(((BindController) controller).getApiConfig());
// 判斷請(qǐng)求的controller是否帶有微信返回的code參數(shù),如果沒(méi)有就調(diào)用微信授權(quán)接口獲取code參數(shù)
if (controller.isParaBlank("code")) {
final String scope = "snsapi_base";
//當(dāng)前正在訪(fǎng)問(wèn)的路徑地址
final StringBuffer requestPath = controller.getRequest().getRequestURL();
//組裝成微信接口調(diào)用地址
String resultUrl = SnsAccessCodeApi.getCoode(requestPath.toString(), scope);
try {
//請(qǐng)求微信接口地址
controller.getResponse().sendRedirect(resultUrl);
} catch (IOException e) {
e.printStackTrace();
}
}
inv.invoke();
} finally {
ApiConfigKit.removeThreadLocalApiConfig();
}
}
}
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2015-09-28 10:23:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
@JFinal 你好,想跟你請(qǐng)教個(gè)問(wèn)題:
使用退款refund API時(shí), 報(bào)這個(gè)錯(cuò)誤,證書(shū)是從微信上下載的。
Caused by: java.io.IOException: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: Given final block not properly padded
at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1317)
at java.security.KeyStore.load(KeyStore.java:1226)
at com.jfinal.weixin.sdk.utils.HttpUtils$OkHttp3Delegate.postSSL(HttpUtils.java:345)
... 19 more
Caused by: javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.PKCS12PBECipherCore.implDoFinal(PKCS12PBECipherCore.java:355)
at com.sun.crypto.provider.PKCS12PBECipherCore$PBEWithSHA1AndRC2_40.engineDoFinal(PKCS12PBECipherCore.java:462)
at javax.crypto.Cipher.doFinal(Cipher.java:1966)
at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1308)
... 21 more
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2016-08-18 11:19:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
JFinal weixin是否還沒(méi)支持企業(yè)號(hào)?近期有支持企業(yè)號(hào)的開(kāi)發(fā)計(jì)劃嗎?
謝謝!
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2016-02-02 21:26:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
需求:因?yàn)榭头畔⒔涌谛枰J(rèn)證后才有權(quán)限調(diào)用,而認(rèn)證又需要300大洋。我只需要普通公眾號(hào)加客服信息接口,因?yàn)橛袝r(shí)候用戶(hù)發(fā)了命令后,后臺(tái)處理業(yè)務(wù)的時(shí)候5秒內(nèi)處理不完,可能會(huì)30秒才有結(jié)果。
場(chǎng)景:免費(fèi)的普通個(gè)人訂閱號(hào)可以直接登錄網(wǎng)頁(yè)版后,和48小時(shí)內(nèi)有互動(dòng)的人主動(dòng)發(fā)送信息,并且每天可以群發(fā)一條信息。然后微信并沒(méi)有開(kāi)放API,所以我今天做了程序模擬微信的http網(wǎng)頁(yè)登錄。
問(wèn)題:程序模擬最后一步的時(shí)候 https://mp.weixin.qq.com/cgi-bin/bizlogin?action=login&token=&lang=zh_CN post后一直返回 {"base_resp":{"err_msg":"default","ret":-14}} 檢查了N編cookie和header 都沒(méi)有找到問(wèn)題。
有沒(méi)有同樣需求的朋友一起研究一下?
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2017-02-28 23:40:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
@JFinal 你好,想跟你請(qǐng)教個(gè)問(wèn)題:jfinal_weixin 配置測(cè)試用號(hào)總是顯示配置失敗,后臺(tái)打印結(jié)果 ,求告知
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2015-03-03 20:57:09
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
最近需要在 Sublime Text 3 下使用 Less( 什么是Less ),但是發(fā)現(xiàn)無(wú)法即時(shí)編譯,很不方便。 于是到 github 上搜索,發(fā)現(xiàn)了一款 Sublime Text2 的即時(shí)編譯插件 ,但是該插件的py腳本是基于 python2.x寫(xiě)的,無(wú)法在 Sublime Text 3 的 Python3 環(huán)境下運(yùn)行,同時(shí)發(fā)現(xiàn)使用的less.js文件是1.3.3版本的。
為了能在我的SublimeText3下運(yùn)行,即時(shí)半學(xué)了Python的語(yǔ)法,然后修改了該插件,并將less.js升級(jí)到less-1.7.5 版本(中間很多苦難啊,特別是第一次接觸Python的格式化語(yǔ)言,遇到了好多的tab縮進(jìn)和空格不一致的問(wèn)題 )。
現(xiàn)在將該插件分享給大家: http://git.oschina.net/yswang/lessc
亮點(diǎn)噢: 該插件是完全獨(dú)立的,只要放到 SublimeText3\Data\Packages下即可使用,不需要安裝什么額外的Nodejs環(huán)境啦、lessjs-window 環(huán)境啦等(本人最討厭這樣的依賴(lài))
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2015-02-03 16:22:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
之前用的ST2 最近才下了個(gè)ST3.
再使用過(guò)程中發(fā)現(xiàn)了我所說(shuō)問(wèn)題。
比如,我再HTML文檔中輸入個(gè), "enter"
后(我沒(méi)有開(kāi)代碼補(bǔ)全),然后按Ctrl+Shift+Enter后是會(huì)自動(dòng)跳到上一行,并且也會(huì)自動(dòng)向右縮進(jìn)一個(gè)Tab,但是只要在接著輸入的話(huà)就又自動(dòng)往左后退一個(gè)Tab了?這是什么問(wèn)題呢?
不知道我描述的大家能不能明白。。。
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2014-04-05 14:57:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
我的sublime安裝了emmet,還是沒(méi)有代碼提示。比如html:5,h1+h2,css和js也是沒(méi)有代碼提示。ps:我的sublime3可以打開(kāi)emmet這個(gè)文件,請(qǐng)問(wèn)是我應(yīng)該設(shè)置什么嗎?在線(xiàn)等,挺急的
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2016-05-13 15:00:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
@vczero 你好,想跟你請(qǐng)教個(gè)問(wèn)題:
最近在看你的書(shū)《React Native入門(mén)與實(shí)戰(zhàn)》,碰到這樣一個(gè)問(wèn)題,一直搞不明白,總是報(bào)路徑錯(cuò)誤,但是我反復(fù)檢查了路徑?jīng)]有錯(cuò),我想請(qǐng)教一下這里邊是不是還有什么蹊蹺?
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2016-04-01 11:54:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
最近對(duì)sublime 愛(ài)不釋手了.我用的最新版本的.
而且我喜歡傾向于白色主題.個(gè)人喜歡吧.感覺(jué)黑色的累眼.
那么問(wèn)題來(lái)了,我看這個(gè)地方尤為不順眼,誰(shuí)知道在哪里改呢?我在論壇上看了兩個(gè)小時(shí),也沒(méi)有找到解決方案.是不是夠笨的了..
每次敲尖括號(hào)的時(shí)候,這個(gè)重重的顏色慌瞎我的雙眼啊.我是不是有強(qiáng)迫癥啊,我想改變這個(gè)這個(gè)顏色!!
誰(shuí)知道,忙嗎解答一下.十分感謝!
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2016-03-26 19:23:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
基于NodeJS的前后端分離 ( 此文章來(lái)自淘寶 )
前言
為了解決傳統(tǒng)Web開(kāi)發(fā)模式帶來(lái)的各種問(wèn)題,我們進(jìn)行了許多嘗試,但由于前/后端的物理鴻溝,嘗試的方案都大同小異。痛定思痛,今天我們重新思考了“前后端”的定義,引入前端同學(xué)都熟悉的NodeJS,試圖探索一條全新的前后端分離模式。
隨著不同終端(Pad/Mobile/PC)的興起,對(duì)開(kāi)發(fā)人員的要求越來(lái)越高,純?yōu)g覽器端的響應(yīng)式已經(jīng)不能滿(mǎn)足用戶(hù)體驗(yàn)的高要求,我們往往需要針對(duì)不同的終端開(kāi)發(fā)定制的版本。為了提升開(kāi)發(fā)效率,前后端分離的需求越來(lái)越被重視,后端負(fù)責(zé)業(yè)務(wù)/數(shù)據(jù)接口,前端負(fù)責(zé)展現(xiàn)/交互邏輯,同一份數(shù)據(jù)接口,我們可以定制開(kāi)發(fā)多個(gè)版本。
這個(gè)話(huà)題最近被討論得比較多,阿里有些BU也在進(jìn)行一些嘗試。討論了很久之后,我們團(tuán)隊(duì)決定探索一套基于NodeJS的前后端分離方案,過(guò)程中有一些不斷變化的認(rèn)識(shí)以及思考,記錄在這里,也希望看到的同學(xué)參與討論,幫我們完善。
一、什么是前后端分離?
最開(kāi)始組內(nèi)討論的過(guò)程中我發(fā)現(xiàn),每個(gè)人對(duì)前后端分離的理解不一樣,為了保證能在同一個(gè)頻道討論,先就什么是”前后端分離”達(dá)成一致。
大家一致認(rèn)同的前后端分離的例子就是SPA(Single-page application),所有用到的展現(xiàn)數(shù)據(jù)都是后端通過(guò)異步接口(AJAX/JSONP)的方式提供的,前端只管展現(xiàn)。
從某種意義上來(lái)說(shuō),SPA確實(shí)做到了前后端分離,但這種方式存在兩個(gè)問(wèn)題: WEB服務(wù)中,SPA類(lèi)占的比例很少。很多場(chǎng)景下還有同步/同步+異步混合的模式,SPA不能作為一種通用的解決方案。 現(xiàn)階段的SPA開(kāi)發(fā)模式,接口通常是按照展現(xiàn)邏輯來(lái)提供的,有時(shí)候?yàn)榱颂岣咝?,后端?huì)幫我們處理一些展現(xiàn)邏輯,這就意味著后端還是涉足了View層的工作,不是真正的前后端分離。
SPA式的前后端分離,是從物理層做區(qū)分(認(rèn)為只要是客戶(hù)端的就是前端,服務(wù)器端的就是后端),這種分法已經(jīng)無(wú)法滿(mǎn)足我們前后端分離的需求,我們認(rèn)為從職責(zé)上劃分才能滿(mǎn)足目前我們的使用場(chǎng)景: 前端:負(fù)責(zé)View和Controller層。 后端:只負(fù)責(zé)Model層,業(yè)務(wù)處理/數(shù)據(jù)等。
為什么去做這種職責(zé)的劃分,后面會(huì)繼續(xù)探討。
二、為什么要前后端分離?
關(guān)于這個(gè)問(wèn)題,玉伯的文章 Web研發(fā)模式演變 中解釋得非常全面,我們?cè)俅蟾爬硪幌拢?
2.1 現(xiàn)有開(kāi)發(fā)模式的適用場(chǎng)景
玉伯提到的幾種開(kāi)發(fā)模式,各有各的適用場(chǎng)景,沒(méi)有哪一種完全取代另外一種。 比如后端為主的MVC,做一些同步展現(xiàn)的業(yè)務(wù)效率很高,但是遇到同步異步結(jié)合的頁(yè)面,與后端開(kāi)發(fā)溝通起來(lái)就會(huì)比較麻煩。 Ajax為主SPA型開(kāi)發(fā)模式,比較適合開(kāi)發(fā)APP類(lèi)型的場(chǎng)景,但是只適合做APP,因?yàn)镾EO等問(wèn)題不好解決,對(duì)于很多類(lèi)型的系統(tǒng),這種開(kāi)發(fā)方式也過(guò)重。
2.2 前后端職責(zé)不清
在業(yè)務(wù)邏輯復(fù)雜的系統(tǒng)里,我們最怕維護(hù)前后端混雜在一起的代碼,因?yàn)闆](méi)有約束,M-V-C每一層都可能出現(xiàn)別的層的代碼,日積月累,完全沒(méi)有維護(hù)性可言。
雖然前后端分離沒(méi)辦法完全解決這種問(wèn)題,但是可以大大緩解。因?yàn)閺奈锢韺哟紊媳WC了你不可能這么做。
2.3 開(kāi)發(fā)效率問(wèn)題
淘寶的Web基本上都是基于MVC框架webx,架構(gòu)決定了前端只能依賴(lài)后端。
所以我們的開(kāi)發(fā)模式依然是,前端寫(xiě)好靜態(tài)demo,后端翻譯成VM模版,這種模式的問(wèn)題就不說(shuō)了,被吐槽了很久。
直接基于后端環(huán)境開(kāi)發(fā)也很痛苦,配置安裝使用都很麻煩。為了解決這個(gè)問(wèn)題,我們發(fā)明了各種工具,比如 VMarket ,但是前端還是要寫(xiě)VM,而且依賴(lài)后端數(shù)據(jù),效率依然不高。
另外,后端也沒(méi)法擺脫對(duì)展現(xiàn)的強(qiáng)關(guān)注,從而專(zhuān)心于業(yè)務(wù)邏輯層的開(kāi)發(fā)。
2.4 對(duì)前端發(fā)揮的局限
性能優(yōu)化如果只在前端做空間非常有限,于是我們經(jīng)常需要后端合作才能碰撞出火花,但由于后端框架限制,我們很難使用Comet、Bigpipe等技術(shù)方案來(lái)優(yōu)化性能。
為了解決以上提到的一些問(wèn)題,我們進(jìn)行了很多嘗試,開(kāi)發(fā)了各種工具,但始終沒(méi)有太多起色,主要是因?yàn)槲覀冎荒茉诤蠖私o我們劃分的那一小塊空間去發(fā)揮。只有真正做到前后端分離,我們才能徹底解決以上問(wèn)題。
三、怎么做前后端分離?
怎么做前后端分離,其實(shí)第一節(jié)中已經(jīng)有了答案: 前端:負(fù)責(zé)View和Controller層。 后端:負(fù)責(zé)Model層,業(yè)務(wù)處理/數(shù)據(jù)等。
試想一下,如果前端掌握了Controller,我們可以做url design,我們可以根據(jù)場(chǎng)景決定在服務(wù)端同步渲染,還是根據(jù)view層數(shù)據(jù)輸出json數(shù)據(jù),我們還可以根據(jù)表現(xiàn)層需求很容易的做Bigpipe,Comet,Socket等等,完全是需求決定使用方式。
3.1 基于NodeJS“全?!笔介_(kāi)發(fā)
如果想實(shí)現(xiàn)上圖的分層,就必然需要一種web服務(wù)幫我們實(shí)現(xiàn)以前后端做的事情,于是就有了標(biāo)題提到的“基于NodeJS的全棧式開(kāi)發(fā)”
這張圖看起來(lái)簡(jiǎn)單而且很好理解,但沒(méi)嘗試過(guò),會(huì)有很多疑問(wèn)。 SPA模式中,后端已供了所需的數(shù)據(jù)接口,view前端已經(jīng)可以控制,為什么要多加NodeJS這一層? 多加一層,性能怎么樣? 多加一層,前端的工作量是不是增加了? 多加一層就多一層風(fēng)險(xiǎn),怎么破? NodeJS什么都能做,為什么還要JAVA?
這些問(wèn)題要說(shuō)清楚不容易,下面說(shuō)下我的認(rèn)識(shí)過(guò)程。
3.2 為什么要增加一層NodeJS?
現(xiàn)階段我們主要以后端MVC的模式進(jìn)行開(kāi)發(fā),這種模式嚴(yán)重阻礙了前端開(kāi)發(fā)效率,也讓后端不能專(zhuān)注于業(yè)務(wù)開(kāi)發(fā)。
解決方案是讓前端能控制Controller層,但是如果在現(xiàn)有技術(shù)體系下很難做到,因?yàn)椴豢赡茏屗星岸硕紝W(xué)java,安裝后端的開(kāi)發(fā)環(huán)境,寫(xiě)VM。
NodeJS就能很好的解決這個(gè)問(wèn)題,我們無(wú)需學(xué)習(xí)一門(mén)新的語(yǔ)言,就能做到以前開(kāi)發(fā)幫我們做的事情,一切都顯得那么自然。
3.3 性能問(wèn)題
分層就涉及每層之間的通訊,肯定會(huì)有一定的性能損耗。但是合理的分層能讓職責(zé)清晰、也方便協(xié)作,會(huì)大大提高開(kāi)發(fā)效率。分層帶來(lái)的損失,一定能在其他方面的收益彌補(bǔ)回來(lái)。
另外,一旦決定分層,我們可以通過(guò)優(yōu)化通訊方式、通訊協(xié)議,盡可能把損耗降到最低。
舉個(gè)例子:
淘寶寶貝詳情頁(yè)靜態(tài)化之后,還是有不少需要實(shí)時(shí)獲取的信息,比如物流、促銷(xiāo)等等,因?yàn)檫@些信息在不同業(yè)務(wù)系統(tǒng)中,所以需要前端發(fā)送5,6個(gè)異步請(qǐng)求來(lái)回填這些內(nèi)容。
有了NodeJS之后,前端可以在NodeJS中去代理這5個(gè)異步請(qǐng)求,還能很容易的做Bigpipe,這塊的優(yōu)化能讓整個(gè)渲染效率提升很多。
可能在PC上你覺(jué)得發(fā)5,6個(gè)異步請(qǐng)求也沒(méi)什么,但是在無(wú)線(xiàn)端,在客戶(hù)手機(jī)上建立一個(gè)HTTP請(qǐng)求開(kāi)銷(xiāo)很大,有了這個(gè)優(yōu)化,性能一下提升好幾倍。
淘寶詳情基于NodeJS的優(yōu)化我們正在進(jìn)行中,上線(xiàn)之后我會(huì)分享一下優(yōu)化的過(guò)程。
3.4 前端的工作量是否增加了?
相對(duì)于只切頁(yè)面/做demo,肯定是增加了一點(diǎn),但是當(dāng)前模式下有聯(lián)調(diào)、溝通環(huán)節(jié),這個(gè)過(guò)程非常花時(shí)間,也容易出bug,還很難維護(hù)。
所以,雖然工作量會(huì)增加一點(diǎn),但是總體開(kāi)發(fā)效率會(huì)提升很多。
另外,測(cè)試成本可以節(jié)省很多。以前開(kāi)發(fā)的接口都是針對(duì)表現(xiàn)層的,很難寫(xiě)測(cè)試用例。如果做了前后端分離,甚至測(cè)試都可以分開(kāi),一撥人專(zhuān)門(mén)測(cè)試接口,一撥人專(zhuān)注測(cè)試UI(這部分工作甚至可以用工具代替)。
3.5 增加Node層帶來(lái)的風(fēng)險(xiǎn)怎么控制?
隨著Node大規(guī)模使用,系統(tǒng)/運(yùn)維/安全部門(mén)的同學(xué)也一定會(huì)加入到基礎(chǔ)建設(shè)中,他們會(huì)幫助我們?nèi)ネ晟聘鱾€(gè)環(huán)節(jié)可能出現(xiàn)的問(wèn)題,保障系的穩(wěn)定性。
3.6 Node什么都能做,為什么還要JAVA?
我們的初衷是做前后端分離,如果考慮這個(gè)問(wèn)題就有點(diǎn)違背我們的初衷了。即使用Node替代Java,我們也沒(méi)辦法保證不出現(xiàn)今天遇到的種種問(wèn)題,比如職責(zé)不清。我們的目的是分層開(kāi)發(fā),專(zhuān)業(yè)的人,專(zhuān)注做專(zhuān)業(yè)的事?;贘AVA的基礎(chǔ)架構(gòu)已經(jīng)非常強(qiáng)大而且穩(wěn)定,而且更適合做現(xiàn)在架構(gòu)的事情。
四、淘寶基于Node的前后端分離
上圖是我理解的淘寶基于Node的前后端分離分層,以及Node的職責(zé)范圍。簡(jiǎn)單解釋下: 最上端是服務(wù)端,就是我們常說(shuō)的后端。后端對(duì)于我們來(lái)說(shuō),就是一個(gè)接口的集合,服務(wù)端提供各種各樣的接口供我們使用。因?yàn)橛蠳ode層,也不用局限是什么形式的服務(wù)。對(duì)于后端開(kāi)發(fā)來(lái)說(shuō),他們只用關(guān)心業(yè)務(wù)代碼的接口實(shí)現(xiàn)。 服務(wù)端下面是Node應(yīng)用。 Node應(yīng)用中有一層Model Proxy與服務(wù)端進(jìn)行通訊。這一層主要目前是抹平我們對(duì)不同接口的調(diào)用方式,封裝一些view層需要的Model。 Node層還能輕松實(shí)現(xiàn)原來(lái)vmcommon,tms(引用淘寶內(nèi)容管理系統(tǒng))等需求。 Node層要使用什么框架由開(kāi)發(fā)者自己決定。不過(guò)推薦使用express+xTemplate的組合,xTemplate能做到前后端公用。 怎么用Node大家自己決定,但是令人興奮的是,我們終于可以使用Node輕松實(shí)現(xiàn)我們想要的輸出方式:JSON/JSONP/RESTful/HTML/BigPipe/Comet/Socket/同步、異步,想怎么整就怎么整,完全根據(jù)你的場(chǎng)景決定。 瀏覽器層在我們這個(gè)架構(gòu)中沒(méi)有變化,也不希望因?yàn)橐隢ode改變你以前在瀏覽器中開(kāi)發(fā)的認(rèn)知。 引入Node,只是把本該就前端控制的部分交由前端掌控。
這種模式我們已經(jīng)有兩個(gè)項(xiàng)目在開(kāi)發(fā)中,雖然還沒(méi)上線(xiàn),但是無(wú)論是在開(kāi)發(fā)效率,還是在性能優(yōu)化方面,我們都已經(jīng)嘗到了甜頭。
五、我們還需要要做什么? 把Node的開(kāi)發(fā)流程集成到淘寶現(xiàn)有的SCM流程中。 基礎(chǔ)設(shè)施建設(shè),比如session,logger等通用模塊。 最佳開(kāi)發(fā)實(shí)踐 線(xiàn)上成功案例 大家對(duì)Node前后端分離概念的認(rèn)識(shí) 安全 性能 …
技術(shù)上不會(huì)有太多需要去創(chuàng)新和研究的,已經(jīng)有非常多現(xiàn)成的積累。其實(shí)關(guān)鍵是一些流程的打通和通用解決方案的積累,相信隨著更多的項(xiàng)目實(shí)踐,這塊慢慢會(huì)變成一個(gè)穩(wěn)定的流程。
六、“中途島”
雖然“基于NodeJS的全棧式開(kāi)發(fā)”模式很讓人興奮,但是把基于Node的全棧開(kāi)發(fā)變成一個(gè)穩(wěn)定,讓大家都能接受的東西還有很多路要走,我們正在進(jìn)行的“中途島”項(xiàng)目就是為了解決這個(gè)問(wèn)題。雖然我們起步不久,但是離目標(biāo)已經(jīng)越來(lái)越近!!
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2014-05-26 12:02:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
我 用的是AllInOne版本的64位eclipse,使用插件生成的項(xiàng)目,編譯ROOT時(shí)出現(xiàn)一個(gè)異常。我貼出異常部分的日志,描述是plexus的interpolation路徑不對(duì)。但我不清楚項(xiàng)目找的不是org\codehaus\plexus\plexus-interpolation而是org\codehaus\plexus\interpolation 目錄。麻煩幫看看是哪里的原因,非常感謝!下面是異常日志:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-jar-plugin:2.3.2:jar (default-jar) on project koala_demo-infra: Execution default-jar of goal org.apache.maven.plugins:maven-jar-plugin:2.3.2:jar failed: A required class was missing while executing org.apache.maven.plugins:maven-jar-plugin:2.3.2?? org/codehaus/plexus/interpolation/InterpolationException
[ERROR] -----------------------------------------------------
[ERROR] realm = plugin>org.apache.maven.plugins:maven-jar-plugin:2.3.2
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/d:/work/Java/Lib/Common/org/apache/maven/plugins/maven-jar-plugin/2.3.2/maven-jar-plugin-2.3.2.jar
[ERROR] urls[1] = file:/d:/work/Java/Lib/Common/junit/junit/3.8.1/junit-3.8.1.jar
[ERROR] urls[2] = file:/d:/work/Java/Lib/Common/org/apache/maven/maven-archiver/2.4.2/maven-archiver-2.4.2.jar
[ERROR] urls[3] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-archiver/2.0.1/plexus-archiver-2.0.1.jar
[ERROR] urls[4] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-io/2.0.1/plexus-io-2.0.1.jar
[ERROR] urls[5] = file:/d:/work/Java/Lib/Common/commons-lang/commons-lang/2.1/commons-lang-2.1.jar
[ERROR] urls[6] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import from realm ClassRealm[maven.api, parent: null]]
[ERROR]
[ERROR] -----------------------------------------------------: org.codehaus.plexus.interpolation.InterpolationException
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-jar-plugin:2.3.2:jar (default-jar) on project koala_demo-infra: Execution default-jar of goal org.apache.maven.plugins:maven-jar-plugin:2.3.2:jar failed: A required class was missing while executing org.apache.maven.plugins:maven-jar-plugin:2.3.2?? org/codehaus/plexus/interpolation/InterpolationException
-----------------------------------------------------
realm = plugin>org.apache.maven.plugins:maven-jar-plugin:2.3.2
strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
urls[0] = file:/d:/work/Java/Lib/Common/org/apache/maven/plugins/maven-jar-plugin/2.3.2/maven-jar-plugin-2.3.2.jar
urls[1] = file:/d:/work/Java/Lib/Common/junit/junit/3.8.1/junit-3.8.1.jar
urls[2] = file:/d:/work/Java/Lib/Common/org/apache/maven/maven-archiver/2.4.2/maven-archiver-2.4.2.jar
urls[3] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-archiver/2.0.1/plexus-archiver-2.0.1.jar
urls[4] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-io/2.0.1/plexus-io-2.0.1.jar
urls[5] = file:/d:/work/Java/Lib/Common/commons-lang/commons-lang/2.1/commons-lang-2.1.jar
urls[6] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar
Number of foreign imports: 1
import: Entry[import from realm ClassRealm[maven.api, parent: null]]
-----------------------------------------------------
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:225)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution default-jar of goal org.apache.maven.plugins:maven-jar-plugin:2.3.2:jar failed: A required class was missing while executing org.apache.maven.plugins:maven-jar-plugin:2.3.2?? org/codehaus/plexus/interpolation/InterpolationException
-----------------------------------------------------
realm = plugin>org.apache.maven.plugins:maven-jar-plugin:2.3.2
strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
urls[0] = file:/d:/work/Java/Lib/Common/org/apache/maven/plugins/maven-jar-plugin/2.3.2/maven-jar-plugin-2.3.2.jar
urls[1] = file:/d:/work/Java/Lib/Common/junit/junit/3.8.1/junit-3.8.1.jar
urls[2] = file:/d:/work/Java/Lib/Common/org/apache/maven/maven-archiver/2.4.2/maven-archiver-2.4.2.jar
urls[3] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-archiver/2.0.1/plexus-archiver-2.0.1.jar
urls[4] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-io/2.0.1/plexus-io-2.0.1.jar
urls[5] = file:/d:/work/Java/Lib/Common/commons-lang/commons-lang/2.1/commons-lang-2.1.jar
urls[6] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar
Number of foreign imports: 1
import: Entry[import from realm ClassRealm[maven.api, parent: null]]
-----------------------------------------------------
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:127)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
... 19 more
Caused by: org.apache.maven.plugin.PluginContainerException: A required class was missing while executing org.apache.maven.plugins:maven-jar-plugin:2.3.2?? org/codehaus/plexus/interpolation/InterpolationException
-----------------------------------------------------
realm = plugin>org.apache.maven.plugins:maven-jar-plugin:2.3.2
strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
urls[0] = file:/d:/work/Java/Lib/Common/org/apache/maven/plugins/maven-jar-plugin/2.3.2/maven-jar-plugin-2.3.2.jar
urls[1] = file:/d:/work/Java/Lib/Common/junit/junit/3.8.1/junit-3.8.1.jar
urls[2] = file:/d:/work/Java/Lib/Common/org/apache/maven/maven-archiver/2.4.2/maven-archiver-2.4.2.jar
urls[3] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-archiver/2.0.1/plexus-archiver-2.0.1.jar
urls[4] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-io/2.0.1/plexus-io-2.0.1.jar
urls[5] = file:/d:/work/Java/Lib/Common/commons-lang/commons-lang/2.1/commons-lang-2.1.jar
urls[6] = file:/d:/work/Java/Lib/Common/org/codehaus/plexus/plexus-utils/3.0/plexus-utils-3.0.jar
Number of foreign imports: 1
import: Entry[import from realm ClassRealm[maven.api, parent: null]]
-----------------------------------------------------
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:125)
... 20 more
Caused by: java.lang.NoClassDefFoundError: org/codehaus/plexus/interpolation/InterpolationException
at org.apache.maven.plugin.jar.AbstractJarMojo.createArchive(AbstractJarMojo.java:188)
at org.apache.maven.plugin.jar.AbstractJarMojo.execute(AbstractJarMojo.java:235)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
... 20 more
Caused by: java.lang.ClassNotFoundException: org.codehaus.plexus.interpolation.InterpolationException
at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244)
at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
... 23 more
[ERROR]
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginContainerException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn -rf :koala_demo-infra
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2013-09-12 10:19:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>>
Koala (考拉) 是一款應(yīng)用在 Java EE 企業(yè)級(jí)應(yīng)用開(kāi)發(fā)領(lǐng)域,用于幫助架構(gòu)師簡(jiǎn)化系統(tǒng)設(shè)計(jì),降低框架耦合度,提高系統(tǒng)靈活性,提供開(kāi)發(fā)工程師工作效率,降低成本的平臺(tái)工具。
Koala 的下載和安裝請(qǐng)看 這里 。
下面是使用 Koala 創(chuàng)建一個(gè)最基礎(chǔ)項(xiàng)目的完整過(guò)程:
自定義生成項(xiàng)目
打開(kāi)eclipse的新建項(xiàng)目向?qū)?duì)話(huà)框,選擇Koala->Koala Project。
點(diǎn)擊Next按鈕,出現(xiàn)Koala的新建項(xiàng)目向?qū)?,如圖:
在“Project name”處填寫(xiě)項(xiàng)目名稱(chēng),在“Location”處選擇項(xiàng)目路徑,在“Working sets”處選擇working set。如果其他使用默認(rèn),可只填項(xiàng)目名稱(chēng)。點(diǎn)擊Next按鈕,進(jìn)入下一步,進(jìn)入maven信息填寫(xiě)的向?qū)ы?yè)。
填寫(xiě)Group Id,Artifact Id,Version和Description等信息,除了Description外其他均為必填項(xiàng)。點(diǎn)擊Next按鈕,進(jìn)入添加模塊的向?qū)ы?yè)。
如圖:中間顯示的當(dāng)前項(xiàng)目的子模塊,右邊是相應(yīng)的子模塊的操作,包括新增,修改以及刪除等操作
另外,你可以選擇JPA或Mybatis做為數(shù)據(jù)庫(kù)實(shí)現(xiàn),Koala支持這兩種方式
你也可以使用SpringMVC或Struts2MVC做為前臺(tái)MVC實(shí)現(xiàn)
選擇Use Default Modules會(huì)根據(jù)DDD領(lǐng)域思想自動(dòng)生成五層模型的項(xiàng)目
其中應(yīng)用層分為接口和實(shí)現(xiàn)兩個(gè)模塊。
“demo-infra”為基礎(chǔ)設(shè)施層的模塊,
“demo-core”為領(lǐng)域?qū)拥哪K,
“demo-application”為應(yīng)用層接口模塊,
“demo-applicationImpl”為應(yīng)用層實(shí)現(xiàn)模塊,
“demo-web”為展現(xiàn)層模,
demo-conf為配置模塊。
開(kāi)發(fā)這可以根據(jù)項(xiàng)目需要,添加模塊,并對(duì)已有模塊配置進(jìn)行編輯或者刪除操作。
下面介紹項(xiàng)目模塊配置的操作。
點(diǎn)擊右邊add按鈕,進(jìn)入模塊信息編輯頁(yè)面。
在編輯模塊信息頁(yè)面中,填寫(xiě)模塊名稱(chēng),選擇模塊類(lèi)型(即根據(jù)DDD分層思想,選擇該模塊所在層,如基礎(chǔ)設(shè)施層,領(lǐng)域?qū)?,?yīng)用層,展現(xiàn)層等)
功能依賴(lài)是指當(dāng)前子模塊中加入一些常用的功能,如FTP,緩存等。加入這些功能是開(kāi)箱即用的。
模塊依賴(lài)是指定義模塊之間的依賴(lài)關(guān)系。定義模塊依賴(lài)前最好對(duì)DDD思想有一定的了解
點(diǎn)擊確認(rèn)便新增加了一個(gè)子模塊
你還可以編輯模塊或刪除它們
根據(jù)項(xiàng)目情況,添加完所需的模塊之后,點(diǎn)擊Next按鈕,進(jìn)入下一步。如果所添加的模塊中有視圖層的模塊,將會(huì)進(jìn)入子系統(tǒng)集成的配置界面。
Koala為你的項(xiàng)目提供了三個(gè)子系統(tǒng)集成,包括權(quán)限子系統(tǒng),監(jiān)控子系統(tǒng)以及通用查詢(xún)子系統(tǒng)
選中復(fù)選框,以集成你需要集成的子系統(tǒng),點(diǎn)擊每個(gè)子系統(tǒng)右邊的config可以進(jìn)行更為詳細(xì)的配置,具體參考各子系統(tǒng)的相關(guān)教程。
完成選擇之后,點(diǎn)擊Next按鈕,進(jìn)入最后的項(xiàng)目信息匯總展示頁(yè)面。
該 頁(yè)面展示了之前所填寫(xiě)的項(xiàng)目極其各模塊的所有信息供用戶(hù)核對(duì)。Project中顯示了所填寫(xiě)的項(xiàng)目名稱(chēng),Maven中顯示了所填寫(xiě)的項(xiàng)目的maven信 息,包括Group Id,Artifact Id,Version和Description等內(nèi)容。Modules中顯示了所填寫(xiě)的各個(gè)模塊的詳細(xì)信息,包括模塊類(lèi)型,模塊名稱(chēng),模塊間的依賴(lài)等內(nèi) 容。如果發(fā)現(xiàn)信息有誤,可點(diǎn)擊Back按鈕回到對(duì)應(yīng)的向?qū)ы?yè)面去做修改。如果核對(duì)無(wú)誤,點(diǎn)擊Finish按鈕完成項(xiàng)目信息的填寫(xiě)并根據(jù)所填信息開(kāi)始生成項(xiàng) 目。
在生成項(xiàng)目完成之后會(huì)彈出導(dǎo)入項(xiàng)目的對(duì)話(huà)框。
選擇要導(dǎo)入的項(xiàng)目和模塊,點(diǎn)擊Next按鈕進(jìn)入查看項(xiàng)目導(dǎo)入信息頁(yè)面或直接點(diǎn)擊Finish按鈕開(kāi)始項(xiàng)目和模塊的導(dǎo)入。
點(diǎn)擊Finish按鈕開(kāi)始導(dǎo)入項(xiàng)目和模塊。
這樣便完成了一個(gè)項(xiàng)目的創(chuàng)建,這是一個(gè)可運(yùn)行的項(xiàng)目,默認(rèn)集成了jetty服務(wù)器以支持開(kāi)發(fā)
使用maven clean install編譯這些項(xiàng)目,再運(yùn)行它們
訪(fǎng)問(wèn)http://localhost:8080以查看效果
從現(xiàn)在開(kāi)始,在生成的項(xiàng)目的基礎(chǔ)上開(kāi)發(fā)吧。
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2013-09-05 08:20:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>> Koala這個(gè)項(xiàng)目停止維護(hù)了嗎?為什么都找不到人?群也加入不了
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2016-05-26 12:20:00
HDC調(diào)試需求開(kāi)發(fā)(15萬(wàn)預(yù)算),能者速來(lái)!>>> [INFO] ------------------------------------------------------------------------[INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 20:14 min [INFO] Finished at: 2015-03-02T10:14:08+08:00 [INFO] Final Memory: 9M/121M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal on project HRTWeb-web: Could not resolve dependencies for project org.hrt:HRTWeb-web:war:1.0.0-SNAPSHOT: The following artifacts could not be resolved: org.hrt:HRTWeb-facade??1.0.0-SNAPSHOT, commons-lang:commons-lang??2.6, org.hrt:HRTWeb-conf??1.0.0-SNAPSHOT, org.hrt:HRTWeb-infra??1.0.0-SNAPSHOT, org.hrt:HRTWeb-facade-impl??1.0.0-SNAPSHOT, com.google.guava:guava??18.0, proxool:proxool??0.9.1: Could not find artifact org.hrt:HRTWeb-facade??1.0.0-SNAPSHOT in nexus-osc (http://maven.oschina.net/content/groups/public/) -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/DependencyResolutionException
來(lái)源:開(kāi)源中國(guó)
發(fā)布時(shí)間:2015-03-02 10:15:00