为什么jfinal 访问静态资源业务层全是静态方法

JFinal Handler源码解析——从配置到工作原理 - JFinal,nodejs博客dreamlu.net
2015年 09月 30日
&&>>&& JFinal Handler源码解析——从配置到工作原理
JFinal Handler源码解析——从配置到工作原理
JFinal顶层是一个Handler链是责任链模式的一个变种,会拦截到所有请求,包括静态资源请求。首先、我们来看看Handler的配置,我们在JFinal的Config中可用来配置自定义的Handler。@Override
public&void&configHandler(Handlers&me)&{
&&&&me.add(new&FakeStaticHandler());
}在这个添加JFinal内置或者我们自己的Handler,在Handlers中有一个ArrayList来存储她们。final&public&class&Handlers&{
&&&&private&final&List&handlerList&=&new&ArrayList();
&&&&public&Handlers&add(Handler&handler)&{
&&&&&&&&if&(handler&!=&null)
&&&&&&&&&&&&handlerList.add(handler);
&&&&&&&&return&
&&&&public&List&getHandlerList()&{
&&&&&&&&return&handlerL
}下面、是Handler的初始化,在项目启动JFinalFilter.init初始化时执行了jfinal.init完成了对整个框架的初始化!我们的Handler也是在这里完成初始化的。boolean&init(JFinalConfig&jfinalConfig,&ServletContext&servletContext)&{
&&&&this.servletContext&=&servletC
&&&&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&
//&初始化Handler
private&void&initHandler()&{
&&&&Handler&actionHandler&=&new&ActionHandler(actionMapping,&constants);
&&&&handler&=&HandlerFactory.getHandler(Config.getHandlers().getHandlerList(),&actionHandler);
}大家再来看看HandlerFactory,在这里从ArrayList的尾部向头部循环,完成对每个Handler中的nextHandler参数赋值。下面是Handler的结构,她是一个单向的链表。/**
&*&Handler.
&*&&*&You&can&config&Handler&in&JFinalConfig.configHandler()&method,
&*&Handler&can&do&anything&under&the&jfinal&action.
public&abstract&class&Handler&{
&&&&protected&Handler&nextH
&&&&&*&Handle&target
&&&&&*&@param&target&url&target&of&this&web&http&request
&&&&&*&@param&request&HttpServletRequest&of&this&http&request
&&&&&*&@param&response&HttpServletRequest&of&this&http&request
&&&&&*&@param&isHandled&JFinalFilter&will&invoke&doFilter()&method&if&isHandled[0]&==&false,
&&&&&*&&&&&&&&&&&&&it&is&usually&to&tell&Filter&should&handle&the&static&resource.
&&&&public&abstract&void&handle(String&target,&HttpServletRequest&request,&HttpServletResponse&response,&boolean[]&isHandled);
}再来、看看HandlerFactory中的getHandler方法。Handler链条的末端是ActionHandler,是专门处理action动态请求的地方。/**
&*&Build&handler&chain
public&static&Handler&getHandler(List&handlerList,&Handler&actionHandler)&{
&&&&Handler&result&=&actionH
&&&&for&(int&i=handlerList.size()-1;&i&=0;&i--)&{
&&&&&&&&Handler&temp&=&handlerList.get(i);
&&&&&&&&temp.nextHandler&=&
&&&&&&&&result&=&
&&&&return&
}最后、我们来看看Handler是怎么工作的上图描述了JFinal中的一个请求的完整过程JFinalFilter-&Handler-&Action,请求到达Handler中之后有三种结局。① 直接跳出链条,执行下一个Filter(如果web.xml中有配置)tomcat、jetty容器对静态资源请求处理。如果都不满足,将返回容器级别的404,可在web.xml中配置404页。*此处的404不受JFinal配置的404页控制。静态资源进入到ActionHandler时会被直接跳出,执行同上。请求不会到达Action。(示例代码:JFinal/ActionHandler.java)if&(target.indexOf('.')&!=&-1)&{
&&&&return&;
}② 请求已经在Handler完成了该有的使命。在Handler执行了render或者在response中返回了我们想要的数据。该请求也不会到达Action,这里设置isHandled[0] =请求到此为止,也不会去执行后面的Filter。(示例代码:jnode/XmlHandler.java)if&(target.endsWith(&.xml&))&{
&&&&String&view&=&target.replace(&.xml&,&&.vm&);
&&&&RenderFactory.me().getRender(&/xml&.concat(view)).setContext(request,&response).render();
&&&&//&跳出
&&&&isHandled[0]&=&
}③ 酒肉穿肠过,佛祖心中留。请求会依次经过各个Handler,抵达Action。nextHandler.handle(target,&request,&response,&isHandled);参考:jfinal处理请求的流程问题:JFinal2.0极速开发视频教程:如梦技术JFinalQQ交流群:本文首发于开源中国我的博客中:
版权声明:若无特殊注明,本文皆为原创,转载请保留文章出处。
人生就象愤怒的小鸟,你失败了,最起码还有几只猪在笑。MVC\JFinal初学----iframe每个jsp页面都要对应一个controller吗
[问题点数:40分,结帖人lyx]
MVC\JFinal初学----iframe每个jsp页面都要对应一个controller吗
[问题点数:40分,结帖人lyx]
只显示楼主
取消只显示楼主
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。关于jfinal推送消息的通过websocket实现的分享
&o&11个月前
&o&2467 次浏览
之前一直遇到一个问题就是发送websocket请求的时候要么是404或者是与服务建立不起连接,经过一上午的折腾终于有所结果了!!主要原因由于jfinal在web.xml配置com.jfinal.core.JFinalFilter
,所以所有的请求都会交给jfinal处理。 造成找不到我们的websocket服务。所以我们需要弄个WebSocketHandler,将过滤掉websocket的请求。具体代码
public class WebSocketHandler extends Handler {
public void handle(String target, HttpServletRequest request,
HttpServletResponse response, boolean[] isHandled) {
//对于websocket 不交予 jfinal 处理
int index = target.indexOf(&/socket&);
if (index == -1) {
nextHandler.handle(target, request, response, isHandled);
添加上面的类就可以了。这样就可以过滤掉socket请求了!!
然后在config类里面加载这个自定义handler就好
* 配置处理器
public void configHandler(Handlers me) {
me.add(new WebSocketHandler());
下面是websocket的实现: java类
package com.socket.firstS
import java.io.IOE
import java.util.concurrent.CopyOnWriteArrayS
import javax.websocket.OnC
import javax.websocket.OnE
import javax.websocket.OnM
import javax.websocket.OnO
import javax.websocket.S
import javax.websocket.server.ServerE
//该注解用来指定一个URI,客户端可以通过这个URI来连接到WebSocket。类似Servlet的注解mapping
@ServerEndpoint(&/websocket&)
public class MyWebSocket {
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
private static int onlineCount = 0;
//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
private static CopyOnWriteArraySet&MyWebSocket& webSocketSet = new CopyOnWriteArraySet&MyWebSocket&();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
* 连接建立成功调用的方法
* @param session
可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
public void onOpen(Session session){
this.session =
webSocketSet.add(this);
//加入set中
addOnlineCount();
//在线数加1
System.out.println(&有新连接加入!当前在线人数为& + getOnlineCount());
* 连接关闭调用的方法
public void onClose(){
webSocketSet.remove(this);
//从set中删除
subOnlineCount();
//在线数减1
System.out.println(&有一连接关闭!当前在线人数为& + getOnlineCount());
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
@OnMessage
public void onMessage(String message, Session session) {
System.out.println(&来自客户端的消息:& + message);
//群发消息
for(MyWebSocket item: webSocketSet){
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
* 发生错误时调用
* @param session
* @param error
public void onError(Session session, Throwable error){
System.out.println(&发生错误&);
error.printStackTrace();
* 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
* @param message
* @throws IOException
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
public static synchronized int getOnlineCount() {
return onlineC
public static synchronized void addOnlineCount() {
MyWebSocket.onlineCount++;
public static synchronized void subOnlineCount() {
MyWebSocket.onlineCount--;
&!DOCTYPE HTML PUBLIC &-//W3C//DTD HTML 4.01 Transitional//EN&&
&title&MyWebSocket&/title&
&meta http-equiv=&pragma& content=&no-cache&&
&meta http-equiv=&cache-control& content=&no-cache&&
&meta http-equiv=&expires& content=&0&&
&meta http-equiv=&keywords& content=&keyword1,keyword2,keyword3&&
&meta http-equiv=&description& content=&This is my page&&
&link rel=&stylesheet& type=&text/css& href=&styles.css&&
Welcome&br/&
&input id=&text& type=&text& /&&button onclick=&send()&&Send&/button&
&button onclick=&closeWebSocket()&&Close&/button&
&div id=&message&&
&script type=&text/javascript&&
var websocket =
//判断当前浏览器是否支持WebSocket
//ws://echo.websocket.org
if('WebSocket' in window){
websocket = new WebSocket(&ws://localhost:80/ijiami_pro/websocket&);
alert('不支持websocket');
//连接发生错误的回调方法
websocket.onerror = function(){
setMessageInnerHTML(&error&);
//连接成功建立的回调方法
websocket.onopen = function(){
setMessageInnerHTML(&websocket握手成功!&);
//接收到消息的回调方法
websocket.onmessage = function(event){
setMessageInnerHTML(event.data);
//连接关闭的回调方法
websocket.onclose = function(){
setMessageInnerHTML(&close&);
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
websocket.close();
//将消息显示在网页上
function setMessageInnerHTML(innerHTML){
document.getElementById('message').innerHTML += innerHTML + '&br/&';
//关闭连接
function closeWebSocket(){
websocket.close();
//发送消息
function send(){
var message = document.getElementById('text').
websocket.send(message);
速度还真快呀。
没事把你这篇博客在编辑一下吧!
这个咋成这样了。。。
之前是用百度的ue,保存到数据库里的数据都是格式化好的html代码,现在不是换成md了吗,没有对html代码进行解析了(其实解析效果也不好),就变成这样了!!就麻烦再编辑一下吧
额.....以前的博客怎么都成这个样子了~~
之前是用百度的ue,保存到数据库里的数据都是格式化好的html代码,现在不是换成md了吗,没有对html代码进行解析了(其实解析效果也不好),就变成这样了!!
handler代码有点问题
正确的应该是
public class WebSocketHandler extends Handler {
public void handle(String target, HttpServletRequest request,
HttpServletResponse response, boolean[] isHandled) {
//对于websocket 不交予 jfinal 处理
int index = target.indexOf(&/websocket&);
if (index == -1) {
nextHandler.handle(target, request, response, isHandled);
我按照上面的做了,怎么建立不起来通讯呢?报错404
int index = target.indexOf("/websocket");
if (index == -1) {
nextHandler.handle(target, request, response, isHandled);
}看进入这里没有。页面是否有js错误、对应包是否加入等等。
&2015 Powered byC圈套与缺陷之语法陷阱_iOS开发-Xcode5创办静态库详解(Cocoa Touch Static Library)_jfinal上超爽的freemarker自定义标签,web开发的利器__脚本百事通
稍等,加载中……
^_^请注意,有可能下面的2篇文章才是您想要的内容:
C圈套与缺陷之语法陷阱
iOS开发-Xcode5创办静态库详解(Cocoa Touch Static Library)
jfinal上超爽的freemarker自定义标签,web开发的利器
C圈套与缺陷之语法陷阱
C陷阱与缺陷之语法陷阱
2.1理解函数声明
任何C变量的声明都由两部分组成:类型以及一组类似表达式的声明符号。例如
这个声明的含义是:当对其求值时,表达式f和g的类型为浮点数类。因为声
明符与表达式的相似,所以我们也可以在声明符中任意使用括号:
float ((f))
这个声明的含义是:当对其求值时,W)的类型为浮点类型,由此可以推知,f也是浮点类型。类似的,
float *g(),(*h)();
表示*g()与(*h)()是浮点表达式。因为()结合优先级高于*,*g()也就是*(g()):g是一个函数,该函数的返回值类型为指向浮点数的指针。同理,可以得出h是一个函数指针,h所指向函数的返回值为浮点类型。
理解了上面的知识后,我们就可以分析signal函数了,signal函数的原型为:
#include &signal.h&
void ( *signal ( int signo ,void (*func)(int) ) ) ( int );
signal函数原型说明该函数需要两个参数,返回一个函数指针,而该指针所指向的函数需要一个整型参数,无返回值。第一个参数signo是一个整数,第二个参数是函数指针,它所指向的函数需要一个整型参数,无返回值。用自然语言描述也就是要向信号处理程序传递一个整型参数,而它却无返回值,当调用signal设置信号处理程序时,第二个参数是指向该函数(也就是信号处理程序)的指针。signal的返回值则是指向之前的信号处理程序的指针。
2.2运算符的优先级问题
优先级最高者其实并不是真正意义上的运算符,包括:数组下标、函数调用操作符各结构成员选择操作符。它们都是白左于右结合,因此a.b.c的含义是(a.b).c,而不是a.(b.c)。
单目运算符的优先级仅次于前述运算符。在所有的真正意义上的运算符中,它们的优先级最高。因为函数调用的优先级要高于单目运算符的优先级,所以如果p是一个函数指针,要调用p所指向的函数,必须这样写:(*p)()。如果写成*p(),编译器会解释成*(p())。类型转换也是单目运算符,它的优先级和其他单目运算符的优先级一样。单目运算符是白右至左
结合,因此*p++会被编译器解释成*(p++),即取指针p所指向的对象,然后将p递增1:而不是(*p)++,即取指针p所指向的对象,然后将该对象递增1。
优先级比单目运算符要低的,接下来就是双目运算符。在双目运算符中,算术运算符的优先级最高,移位运算符次之,关系运算符再次之,接着是逻辑运算符,赋值运算符,最后是条件运算符(为三目运算符)。
我们需要记住的最重要的两点是:
1.任何一个逻辑运算符的优先级低于任何一个关系运算符。
2.移位运算符的优先级比算术运算符要低,但是比关系运算符要高。
在所有的运算符中,逗号运算符的优先级最低。这一点很容易记住,因为逗号运算符常用于在需要一个表达式而不是一条语句的情形下替换作为语句结束标志的分号。
2.3注意作为语句结束标志的分号
在C程序中如果不小心多写了一个分号可能不会造成什么不良后果:这个分号也许会被视作一个不会产生任何实际效果的空语句;或者编译器会因为这个多余的分号而产生一条警告信息,根据警告信息的提示能够很容易去掉这个分号。一个重要的例外情形是在if或者while语句之后需要紧跟一条语句时,如果此时多了一个分号,那么原来紧跟在if或者while了句之后的语句就是一条单独的语句,与条件判断部分没有了任何关系。考虑下面的
if(x [i]&big);
2.4 switch语句
switch语句中要注意case后面加break,这样才能起到控制的作用。当然有些时候,故意不加break以达到某种效果。
2.5悬挂else引发的问题
C语言中if else配对规则:else始终同一对括号内最近的为匹配的if结合。
例如这样就可能和违背编程者的本意:
if(y==0) error();
缩进后,成这样
if(x == 0)
if(y == 0)
为了避免这种情况,在if和else后面都要加花括号
iOS开发-Xcode5创办静态库详解(Cocoa Touch Static Library)
iOS开发-Xcode5创建静态库详解(Cocoa Touch Static Library)科普---&什么是iOS静态库?
如果你作为iOS开发者已经有一段时间,可能会有一套属于自己的类和工具函数,它们在你的大多数项目中被重用。重用代码的最简单方法是简单的 拷贝/粘贴 源文件。然而,这种方法很快就会成为维护时的噩梦。因为每个app都有自己的一份代码副本,你很难在修复bug或者升级时保证所有副本的同步。这就是静态库要拯救你的。一个静态库是若干个类,函数,定义和资源的包装,你可以将其打包并很容易的在项目之间共享。
程序编译一般需经预处理、编译、汇编和链接几个步骤。对于我们项目中的一些公共代码,如果想要对其进行复用,可以把这些代码编译成一个静态库文件。在链接步骤中,链接器会从库文件中取得对应的代码并生成可执行文件。静态库的执行文件中包含了库中的完整代码,但是多次使用会产生多份冗余拷贝。
静态库和动态库的区别在于静态库在链接阶段被复制,与程序的运行阶段无关;动态库在程序运行时由系统动态加载到内存中供程序调用,这样可以大大节省内存。
创建静态库可能出于以下几个理由:
1.你想将一些你和你团队中的同事们经常使用的类打包并轻松的分享给周围其他人。
2.你想让一些通用代码处于自己的掌控之下,以便于修复和升级。
3.你想将库共享给其他人,但不想让他们看到你的源代码。
如果, 你还想继续创建一个静态库, 那就接着往下看吧。
Xcode5创建静态库详解(Cocoa Touch Static Library)
一。创建静态库文件
1.新建工程。
打开Xcode, 选择File ----& New ---& Project。 新建工程。
选择iOS ----& Framework & Library ---& Cocoa Touch Static Library。
点击Next。创建工程。 这里我取名为LibTest。
2.在LibTest.h中添加方法声明
Created by Colin on 14-4-6.
Copyright (c) 2014年 icephone. All rights reserved.
#import &Foundation/Foundation.h&
@interface LibTest : NSObject
-(void)LibPrintT
3.在LibTest.m中实现方法
Created by Colin on 14-4-6.
Copyright (c) 2014年 icephone. All rights reserved.
#import "LibTest.h"
@implementation LibTest
-(void)LibPrintTest
NSLog(@"This is my first static library");
4.在 iOS Device(设备)中编译。
如图所示。选择完毕后,进行编译。(可以通过快捷键command+B, 也可以Product ----& Build )
编译完成后, 可以看到Products目录下的 libLibTest.a 由红变黑, 说明用于设备使用的静态库已经生成成功了。
如图所示。
5.在 iOS Simulator(模拟器)中编译
同样, 选择相应的模拟器。 比如iPhone Retina(4-inch 64-bit)进行编译, 编译后会生成用于模拟器的静态库文件。
6.查看静态库。
右键选择libLibTest.a ---& Show In Finder。
可以看到生成了两份静态库, 一份用于设备, 一份用于模拟器。
二。在模拟器中使用静态库
1.导入静态库和头文件
在你需要加入静态库的工程中, 导入相应的导入静态库和头文件。
如图所示。
2.添加头文件以及调用方法。
在需要使用的地方, 添加头文件, 并且调用。如下所示。
ViewController.m
Created by Colin on 14-4-5.
Copyright (c) 2014年 icephone. All rights reserved.
#import "ViewController.h"
#import "LibTest.h"
@interface ViewController ()
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
LibTest *myTest = [[LibTest alloc]init];
[myTest LibPrintTest];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
好了, 这个时候你运行的话, 会看到控制台输出
This is my first static library
这表面我们的静态库调用成功。
三。在设备中使用静态库文件
这个过程与上述模拟器中使用静态库文件的过程一样,唯一的区别就是需要使用用于设备的静态库文件!
模拟器静态库只能运行在模拟器上而真机静态库也只能运行在真机上,这样就比较麻烦,通过下面的步骤将两个静态库合成一个,这样在模拟器和真机上都能用了。
*四。合并.a文件,制作通用静态库
这一步在终端进行(Finder---&应用程序----&实用工具打开终端)
命令如下:
lipo -create /Users/apple/Library/Developer/Xcode/DerivedData/LibTest-ezgewgrmngvyymexmouyvqiwyizd/Build/Products/Debug-iphoneos/libLibTest.a/Users/apple/Library/Developer/Xcode/DerivedData/LibTest-ezgewgrmngvyymexmouyvqiwyizd/Build/Products/Debug-iphonesimulator/libLibTest.a
-output/Users/apple/Desktop/myLibTest.a
将/Users/apple/Library/Developer/Xcode/DerivedData/LibTest-ezgewgrmngvyymexmouyvqiwyizd/Build/Products/Debug-iphoneos/libLibTest.a/Users/apple/Library/Developer/Xcode/DerivedData/LibTest-ezgewgrmngvyymexmouyvqiwyizd/Build/Products/Debug-iphonesimulator/libLibTest.a替换成你的路径。
将/Users/apple/Desktop/myLibTest.a替换成合并后的路径。
如图所示。
这样合并后的静态库就可以在模拟器和真机上运行了。
学习的路上,与君共勉。
jfinal上超爽的freemarker自定义标签,web开发的利器
jfinal下超爽的freemarker自定义标签,web开发的利器
为什么采用freemarker?
1、模板技术,不依附于语言和框架,前端和后端解耦,便于分工协作,更好的协同。
2、页面相应速度快
3、前端非常的灵活,采用自定义标签可以在不更改后端的基础上很容易的构造前端逻辑,可适应多变的网站。
为什么要自定义标签?
答案在第一个问题的第三点,我们需要一个前端灵活的架构,在不更改后端逻辑的基础上,很容易的改造前端逻辑。
在SSH的架构中,自定义标签已经可以方便的实现(struts2的标签也是基于freemarker的自定义标签),但是用起来还是不够爽,需要大量的配置,繁琐的依赖注入等。用了jfinal以后,发现自定义freemarker标签在该框架中用起来极爽,寥寥几个类,几行代码就能将自定义标签应用起来。废话不多说了,上代码吧。
第一步:实现标签类
分类标签&br&
参数:{parent_id:上级主键}
返回值:{list:分类列表}
@author yongtree
public class CategoryListDirective implements TemplateDirectiveModel
public void execute(Environment
env, Map params, TemplateModel[] loopVars,
TemplateDirectiveBody
body) throws TemplateException,
IOException {
<tbody style="padding:0px! margin:0px! border:0px! outline:0px! float:none! vertical-align:baseline! position:static!i
如果您想提高自己的技术水平,欢迎加入本站官方1号QQ群:&&,&&2号QQ群:,在群里结识技术精英和交流技术^_^
本站联系邮箱:当前访客身份:游客 [
当前位置:
你好,想跟你请教个问题:
JFinal 建议的项目结构:
1:总体划分规则:先分模块,然后在模块中分层。
2:模块划分:中小型项目,每个领域模型划分为一个模块,如 jfinal demo 给出的 blog就是一个模块。大型项目可以在模块下面划分子模块。
3:层次划分:中小型项目可以在模块下面直接以类文件命名来约定层次,如Controller层为BlogController,Model层为Blog,业务层为BlogService。大型项目可以为层分配子包,如在模块下面创建service、controller、model包,然后在包中再创建该层次的相关类文件。
4:为了极速开发,中小型项目,可以不使用Service层,而且业务全部放入Model,称之为充血领域模型。
==============================================================
我想问下:我在 service 层写了业务逻辑代码,在 model层也写了一些访问代码功能。
1、然后 在 controller 层可以调用 service层,也可以调用 model层代码吧?还是说:在controller层只能调用 service层的内容?
2、几个层之间的 调用关系 有什么要求?
共有2个答案
<span class="a_vote_num" id="a_vote_num_
& & &1:有Service 层时,通常是 controller 层中直接调用 Service 方法,返回的结果可能是 Model或者Model集合。Model 中的方法并不是只有 Service 中可以调用,在 controller 中也可以,只不过更多还是调用 Serivce,有了 service 层以后,model 主要用来承载数据,以及添加一点与具体 model 对象有关的方法,例如 Account.isActivate() 用来判断该账户是否已激活,代码为: return getInt("activate" == ACTIVATE_YES);
& &2:调用关系要求:controller 获取请求参数,再以这些参数为参数调用 service 层,获取到 service 返回的结果,再 render。至于 model 见 1 中的说明。
<span class="a_vote_num" id="a_vote_num_
有service层的话,建议使用后面,只调service,特别是事务级别的
更多开发者职位上
有什么技术问题吗?
richlin...的其它问题
类似的话题

我要回帖

更多关于 jfinal 静态化 的文章

 

随机推荐