Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
endmsg系統(tǒng)調(diào)用,主要工作是將用戶空間的消息頭復(fù)制到內(nèi)核空間中,對(duì)消息頭進(jìn)行檢查。最后逐級(jí)調(diào)用發(fā)包接口發(fā)送數(shù)據(jù)。
https://www.cnblogs.com/wanpengcoder/p/11749313.html
send、sendto、sendmsg區(qū)別:
https://www.cnblogs.com/hnrainll/archive/2011/08/16/2141483.html
send只可用于基于連接的套接字,send 和 write唯一的不同點(diǎn)是標(biāo)志的存在,當(dāng)標(biāo)志為0時(shí),send等同于write。sendto 和 sendmsg既可用于無(wú)連接的套接字,也可用于基于連接的套接字。
SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
E:\linux-4.1.45\linux-4.1.45\net\socket.c
SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags)
{
if (flags & MSG_CMSG_COMPAT)
return -EINVAL;
return __sys_sendmsg(fd, msg, flags);
}
/*
* BSD sendmsg interface
*/
long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned flags)
{
int fput_needed, err;
struct msghdr msg_sys;
struct socket *sock;
sock=sockfd_lookup_light(fd, &err, &fput_needed);//根據(jù)fd找到對(duì)應(yīng)socket
if (!sock)
goto out;
//發(fā)送數(shù)據(jù)
err=___sys_sendmsg(sock, msg, &msg_sys, flags, NULL);
fput_light(sock->file, fput_needed);
out:
return err;
}
static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
struct msghdr *msg_sys, unsigned int flags,
struct used_address *used_address)
{
struct compat_msghdr __user *msg_compat=(struct compat_msghdr __user *)msg;
struct sockaddr_storage address;
struct iovec iovstack[UIO_FASTIOV], *iov=iovstack;
unsigned char ctl[sizeof(struct cmsghdr) + 20]
__attribute__ ((aligned(sizeof(__kernel_size_t))));
/* 20 is size of ipv6_pktinfo */
unsigned char *ctl_buf=ctl;
int ctl_len;
ssize_t err;
msg_sys->msg_name=&address;
if (MSG_CMSG_COMPAT & flags)
/* 從64位消息頭拷貝數(shù)據(jù)到32位消息頭 */
err=get_compat_msghdr(msg_sys, msg_compat, NULL, &iov);
else
err=copy_msghdr_from_user(msg_sys, msg, NULL, &iov);
if (err < 0)
return err;
err=-ENOBUFS;
/* 控制信息長(zhǎng)度錯(cuò)誤 */
if (msg_sys->msg_controllen > INT_MAX)
goto out_freeiov;
/* 拷貝控制信息 */
ctl_len=msg_sys->msg_controllen;
if ((MSG_CMSG_COMPAT & flags) && ctl_len) {
err=cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl,
sizeof(ctl));
if (err)
goto out_freeiov;
ctl_buf=msg_sys->msg_control;
ctl_len=msg_sys->msg_controllen;
} else if (ctl_len) {
if (ctl_len > sizeof(ctl)) {
ctl_buf=sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL);
if (ctl_buf==NULL)
goto out_freeiov;
}
err=-EFAULT;
/*
* Careful! Before this, msg_sys->msg_control contains a user pointer.
* Afterwards, it will be a kernel pointer. Thus the compiler-assisted
* checking falls down on this.
*/
if (copy_from_user(ctl_buf,
(void __user __force *)msg_sys->msg_control,
ctl_len))
goto out_freectl;
msg_sys->msg_control=ctl_buf;
}
/* 設(shè)置發(fā)送標(biāo)記 */
msg_sys->msg_flags=flags;
/* 設(shè)置非阻塞標(biāo)記 */
if (sock->file->f_flags & O_NONBLOCK)
msg_sys->msg_flags |=MSG_DONTWAIT;
/* 如果這次發(fā)送的地址跟上次成功發(fā)送的一致 */
/*
* If this is sendmmsg() and current destination address is same as
* previously succeeded address, omit asking LSM's decision.
* used_address->name_len is initialized to UINT_MAX so that the first
* destination address never matches.
*/
if (used_address && msg_sys->msg_name &&
used_address->name_len==msg_sys->msg_namelen &&
!memcmp(&used_address->name, msg_sys->msg_name,
used_address->name_len)) {
/* 無(wú)需進(jìn)行檢查,直接發(fā)送 */
err=sock_sendmsg_nosec(sock, msg_sys);
goto out_freectl;
}
/* 進(jìn)行安全模塊檢查后發(fā)送 */
err=sock_sendmsg(sock, msg_sys);
/* 發(fā)送成功需要更新成功地址記錄 */
/*
* If this is sendmmsg() and sending to current destination address was
* successful, remember it.
*/
if (used_address && err >=0) {
used_address->name_len=msg_sys->msg_namelen;
if (msg_sys->msg_name)
memcpy(&used_address->name, msg_sys->msg_name,
used_address->name_len);
}
out_freectl:
if (ctl_buf !=ctl)
sock_kfree_s(sock->sk, ctl_buf, ctl_len);
out_freeiov:
kfree(iov);
return err;
}
在項(xiàng)目中測(cè)試發(fā)現(xiàn),沒有定義CONFIG_COMPAT宏, 用的是#define compat_msghdr msghdr
E:\linux-4.1.45\linux-4.1.45\include\net\compat.h
#if defined(CONFIG_COMPAT)
#include <linux/compat.h>
struct compat_msghdr {
compat_uptr_t msg_name; /* void * */
compat_int_t msg_namelen;
compat_uptr_t msg_iov; /* struct compat_iovec * */
compat_size_t msg_iovlen;
compat_uptr_t msg_control; /* void * */
compat_size_t msg_controllen;
compat_uint_t msg_flags;
};
...
#else /* defined(CONFIG_COMPAT) */
/*
* To avoid compiler warnings:
*/
#define compat_msghdr msghdr
#define compat_mmsghdr mmsghdr
#endif /* defined(CONFIG_COMPAT) */
int sock_sendmsg(struct socket *sock, struct msghdr *msg)
{
int err=security_socket_sendmsg(sock, msg,
msg_data_left(msg));
return err ?: sock_sendmsg_nosec(sock, msg);
}
static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg)
{
int ret=sock->ops->sendmsg(sock, msg, msg_data_left(msg));
BUG_ON(ret==-EIOCBQUEUED);
return ret;
}
對(duì)表單的驗(yàn)證,自己寫大量的js畢竟不是一個(gè)明智的做法。不僅僅是代碼很長(zhǎng)而且不便于梳理。Validform就是一款開源的第三方驗(yàn)證js的控件,通過添加相應(yīng)的js以及css能夠有效的驗(yàn)證表單,維護(hù)起來(lái)也很方便。
1、js和css的引用:
這里引用官網(wǎng)下載中的一下css:
(文件里這個(gè)注釋 "/*==========以下部分是Validform必須的===========*/" 之后的部分是必須的)
畢竟validform是基于jquery編寫的,所以這個(gè)地方也需要引用Jquery腳本;
<script type="text/javascript" src="http://validform.rjboy.cn/wp-content/themes/validform/js/jquery-1.6.2.min.js"></script> <script type="text/javascript" src="http://validform.rjboy.cn/Validform/v5.1/Validform_v5.1_min.js"></script>
2、表單元素的屬性綁定:
表單元素的屬性主要有:datatype、nullmsg、sucmsg、errormsg、ignore、recheck、tip、altercss、ajaxurl 和 plugin;
2.1:datatype:
內(nèi)置基本的datatype類型有: * | *6-16 | n | n6-16 | s | s6-18 | p | m | e | url
*:檢測(cè)是否有輸入,可以輸入任何字符,不留空即可通過驗(yàn)證;
*6-16:檢測(cè)是否為6到16位任意字符;
n:數(shù)字類型;
n6-16:6到16位數(shù)字;
s:字符串類型;
s6-18:6到18位字符串;
p:驗(yàn)證是否為郵政編碼;
m:手機(jī)號(hào)碼格式;
e:email格式;
url:驗(yàn)證字符串是否為網(wǎng)址。
自定義datatype的名稱,可以由字母、數(shù)字、下劃線、中劃線和*號(hào)組成。
形如"*6-16"的datatype,Validform會(huì)自動(dòng)擴(kuò)展,可以指定任意的數(shù)值范圍。如內(nèi)置基本類型有"*6-16",那么你綁定datatype="*4-12"就表示4到12位任意字符。如果你自定義了一個(gè)datatype="zh2-4",表示2到4位中文字符,那么datatype="zh2-6"就表示2到6位中文字符。
5.2版本之后,datatype支持規(guī)則累加或單選。用","分隔表示規(guī)則累加;用"|"分隔表示規(guī)則多選一,即只要符合其中一個(gè)規(guī)則就可以通過驗(yàn)證,綁定的規(guī)則會(huì)依次驗(yàn)證,只要驗(yàn)證通過,后面的規(guī)則就會(huì)忽略不再比較。如綁定datatype="m|e",表示既可以填寫手機(jī)號(hào)碼,也能填寫郵箱地址,如果知道填入的是手機(jī)號(hào)碼,那么就不會(huì)再檢測(cè)他是不是郵箱地址;datatype="zh,s2-4",表示要符合自定義類型"zh",也要符合規(guī)則"s2-4"。
注:
5.2.1版本之后,datatype支持:
直接綁定正則:如可用這樣寫datatype="/\w{3,6}/i",要求是3到6位的字母,不區(qū)分大小寫;
支持簡(jiǎn)單的邏輯運(yùn)算:如datatype="m | e, *4-18 | /\w{3,6}/i | /^validform\.rjboy\.cn$/",
這個(gè)表達(dá)式的意思是:可以是手機(jī)號(hào)碼;或者是郵箱地址,但字符長(zhǎng)度必須在4到18位;或者是3到6位的字母,不區(qū)分大小寫;或者輸入validform.rjboy.cn,區(qū)分大小寫。這里","分隔相當(dāng)于邏輯運(yùn)算里的"&&"; "|"分隔相當(dāng)于邏輯運(yùn)算里的"||";不支持括號(hào)運(yùn)算。
2.2、nullmsg:
當(dāng)表單元素值為空時(shí)的提示信息,不綁定,默認(rèn)提示"請(qǐng)?zhí)钊胄畔ⅲ?。如:nullmsg="請(qǐng)?zhí)顚懹脩裘?
2.3、sucmsg :
當(dāng)表單元素通過驗(yàn)證時(shí)的提示信息,不綁定,默認(rèn)提示"通過信息驗(yàn)證!"。如:sucmsg="用戶名還未被使用,可以注冊(cè)!"
2.4、errormsg:
輸入內(nèi)容不能通過驗(yàn)證時(shí)的提示信息,默認(rèn)提示"請(qǐng)輸入正確信息!"。如:errormsg="用戶名必須是2到4位中文字符!"
2.5、ignore:
綁定了ignore="ignore"的表單元素,在有輸入時(shí),會(huì)驗(yàn)證所填數(shù)據(jù)是否符合datatype所指定數(shù)據(jù)類型,沒有填寫內(nèi)容時(shí)則會(huì)忽略對(duì)它的驗(yàn)證;
2.6、rechec:
表單里面經(jīng)常需要檢查兩次密碼輸入是否一致,recheck就是用來(lái)指定需要比較的另外一個(gè)表單元素。如:recheck="password1",那么它就會(huì)拿當(dāng)前元素的值跟該表單下,name為"password1"的元素比較。
2.7、tip:
表單里經(jīng)常有些文本框需要默認(rèn)就顯示一個(gè)灰色的提示文字,當(dāng)獲得焦點(diǎn)時(shí)提示文字消失,失去焦點(diǎn)時(shí)提示文字顯示。tip屬性就是用來(lái)實(shí)現(xiàn)這個(gè)效果。它通常和altercss搭配使用。如<input type="text" value="默認(rèn)提示文字" class="gray intxt" tip="默認(rèn)提示文字" altercss="gray" />
2.8、altercss:
它需要和tip屬性配合使用,altercss指定的樣式名,會(huì)在文本框獲得焦點(diǎn)時(shí)被刪除,沒有輸入內(nèi)容而失去焦點(diǎn)時(shí)重新加上。
2.9、ajaxurl:
指定ajax實(shí)時(shí)驗(yàn)證的后臺(tái)文件的地址。后臺(tái)頁(yè)面如valid.php文件中可以用 $_POST["param"] 接收到值,Ajax中會(huì)POST過來(lái)變量param和name。param是文本框的值,name是文本框的name屬性。
2.10、plugin:
指定需要使用的插件。5.3版開始,對(duì)于日期、swfupload和密碼強(qiáng)度檢測(cè)這三個(gè)插件,綁定了plugin屬性即可以初始化對(duì)應(yīng)的插件,可以不用在validform初始化時(shí)傳入空的usePlugi了。
舉例如下:
<!--ajax實(shí)時(shí)驗(yàn)證用戶名--> <input type="text" value="" name="name" datatype="e" ajaxurl="valid.php?myparam1=value1&myparam2=value2" sucmsg="用戶名驗(yàn)證通過!" nullmsg="請(qǐng)輸入用戶名!" errormsg="請(qǐng)用郵箱或手機(jī)號(hào)碼注冊(cè)!" /> <!--密碼--> <input type="password" value="" name="userpassword" datatype="*6-15" errormsg="密碼范圍在6~15位之間!" /> <!--確認(rèn)密碼--> <input type="password" value="" name="userpassword2" datatype="*" recheck="userpassword" errormsg="您兩次輸入的賬號(hào)密碼不一致!" /> <!--默認(rèn)提示文字--> <textarea tip="請(qǐng)?jiān)谶@里輸入您的意見。" errormsg="很感謝您花費(fèi)寶貴時(shí)間給我們提供反饋,請(qǐng)?zhí)顚懹行?nèi)容!" datatype="s" altercss="gray" class="gray" name="msg" value="">請(qǐng)?jiān)谶@里輸入您的意見。</textarea> <!--使用swfupload插件--> <input type="text" plugin="swfupload" class="inputxt" disabled="disabled" value=""> <input type="hidden" value="" pluginhidden="swfupload"> <!--使用passwordStrength插件--> <input type="password" errormsg="密碼至少6個(gè)字符,最多18個(gè)字符!" datatype="*6-18" plugin="passwordStrength" class="inputxt" name="password" value=""> <div class="passwordStrength" style="display:none;"><b>密碼強(qiáng)度:</b> <span>弱</span><span>中</span><span class="last">強(qiáng)</span></div> <!--使用DatePicker插件--> <input type="text" plugin="datepicker" class="inputxt" name="birthday" value="">
初始化參數(shù)說明:
參數(shù)說明:【所有參數(shù)均為可選項(xiàng)】
tiptype:function(msg,o,cssctl){ //msg:提示信息; //o:{obj:*,type:*,curform:*}, //obj指向的是當(dāng)前驗(yàn)證的表單元素(或表單對(duì)象,驗(yàn)證全部驗(yàn)證通過,提交表單時(shí)o.obj為該表單對(duì)象), //type指示提示的狀態(tài),值為1、2、3、4, 1:正在檢測(cè)/提交數(shù)據(jù),2:通過驗(yàn)證,3:驗(yàn)證失敗,4:提示ignore狀態(tài), //curform為當(dāng)前form對(duì)象; //cssctl:內(nèi)置的提示信息樣式控制函數(shù),該函數(shù)需傳入兩個(gè)參數(shù):顯示提示信息的對(duì)象 和 當(dāng)前提示的狀態(tài)(既形參o中的type); } 具體參見demo頁(yè)。
datatyp:{ "zh2-4":/^[\u4E00-\u9FA5\uf900-\ufa2d]{2,4}$/, "phone":function(gets,obj,curform,regxp){ //參數(shù)gets是獲取到的表單元素值, //obj為當(dāng)前表單元素, //curform為當(dāng)前驗(yàn)證的表單, //regxp為內(nèi)置的一些正則表達(dá)式的引用。 //return false表示驗(yàn)證出錯(cuò),沒有return或者return true表示驗(yàn)證通過。 } }
初始化舉例代碼如下:
$(".demoform").Validform({ btnSubmit:"#btn_sub", btnReset:".btn_reset", tiptype:1, ignoreHidden:false, dragonfly:false, tipSweep:true, label:".label", showAllError:false, postonce:true, ajaxPost:true, datatype:{ "*6-20": /^[^\s]{6,20}$/, "z2-4" : /^[\u4E00-\u9FA5\uf900-\ufa2d]{2,4}$/, "username":function(gets,obj,curform,regxp){ //參數(shù)gets是獲取到的表單元素值,obj為當(dāng)前表單元素,curform為當(dāng)前驗(yàn)證的表單,regxp為內(nèi)置的一些正則表達(dá)式的引用; var reg1=/^[\w\.]{4,16}$/, reg2=/^[\u4E00-\u9FA5\uf900-\ufa2d]{2,8}$/; if(reg1.test(gets)){return true;} if(reg2.test(gets)){return true;} return false; //注意return可以返回true 或 false 或 字符串文字,true表示驗(yàn)證通過,返回字符串表示驗(yàn)證失敗,字符串作為錯(cuò)誤提示顯示,返回false則用errmsg或默認(rèn)的錯(cuò)誤提示; }, "phone":function(){ // 5.0 版本之后,要實(shí)現(xiàn)二選一的驗(yàn)證效果,datatype 的名稱 不 需要以 "option_" 開頭; } }, usePlugin:{ swfupload:{}, datepicker:{}, passwordstrength:{}, jqtransform:{ selector:"select,input" } }, beforeCheck:function(curform){ //在表單提交執(zhí)行驗(yàn)證之前執(zhí)行的函數(shù),curform參數(shù)是當(dāng)前表單對(duì)象。 //這里明確return false的話將不會(huì)繼續(xù)執(zhí)行驗(yàn)證操作; }, beforeSubmit:function(curform){ //在驗(yàn)證成功后,表單提交前執(zhí)行的函數(shù),curform參數(shù)是當(dāng)前表單對(duì)象。 //這里明確return false的話表單將不會(huì)提交; }, callback:function(data){ //返回?cái)?shù)據(jù)data是json對(duì)象,{"info":"demo info","status":"y"} //info: 輸出提示信息; //status: 返回提交數(shù)據(jù)的狀態(tài),是否提交成功。如可以用"y"表示提交成功,"n"表示提交失敗,在ajax_post.php文件返回?cái)?shù)據(jù)里自定字符,主要用在callback函數(shù)里根據(jù)該值執(zhí)行相應(yīng)的回調(diào)操作; //你也可以在ajax_post.php文件返回更多信息在這里獲取,進(jìn)行相應(yīng)操作; //ajax遇到服務(wù)端錯(cuò)誤時(shí)也會(huì)執(zhí)行回調(diào),這時(shí)的data是{ status:**, statusText:**, readyState:**, responseText:** }; //這里執(zhí)行回調(diào)操作; //注意:如果不是ajax方式提交表單,傳入callback,這時(shí)data參數(shù)是當(dāng)前表單對(duì)象,回調(diào)函數(shù)會(huì)在表單驗(yàn)證全部通過后執(zhí)行,然后判斷是否提交表單,如果callback里明確return false,則表單不會(huì)提交,如果return true或沒有return,則會(huì)提交表單。 } });
Validform對(duì)象:
如示例 var demo=$(".formsub").Validform(),那么demo對(duì)象會(huì)有以下屬性和方法可以調(diào)用:
tipmsg【object】
如:demo.tipmsg.s="error! no message inputed.";
通過該對(duì)象可以修改除 tit 以外的其他提示文字,這樣可以實(shí)現(xiàn)同一個(gè)頁(yè)面的不同表單使用不同的提示文字。
具體可修改的提示文字 $.Tipmsg={//默認(rèn)提示文字; tit:"提示信息", w:{ "*":"不能為空!", "*6-16":"請(qǐng)?zhí)顚?到16位任意字符!", "n":"請(qǐng)?zhí)顚憯?shù)字!", "n6-16":"請(qǐng)?zhí)顚?到16位數(shù)字!", "s":"不能輸入特殊字符!", "s6-18":"請(qǐng)?zhí)顚?到18位字符!", "p":"請(qǐng)?zhí)顚戉]政編碼!", "m":"請(qǐng)?zhí)顚懯謾C(jī)號(hào)碼!", "e":"郵箱地址格式不對(duì)!", "url":"請(qǐng)?zhí)顚懢W(wǎng)址!" }, def:"請(qǐng)?zhí)顚懻_信息!", undef:"datatype未定義!", reck:"兩次輸入的內(nèi)容不一致!", r:"通過信息驗(yàn)證!", c:"正在檢測(cè)信息…", s:"請(qǐng){填寫|選擇}{0|信息}!", v:"所填信息沒有經(jīng)過驗(yàn)證,請(qǐng)稍后…", p:"正在提交數(shù)據(jù)…" };
要修改tit(彈出框的標(biāo)題文字)的話,可以這樣:$.Tipmsg.tit="Message Box",則彈出框的標(biāo)題文字會(huì)換成"Message Box"
注:5.3.2+
$.Tipmsg.w里,形如"*6-16"的提示文字,里面的數(shù)字是會(huì)被替換的。如綁定datatype="*2-18",那它默認(rèn)的出錯(cuò)信息就會(huì)是"請(qǐng)?zhí)顚?到18位任意字符!",可以通過$.Tipmsg.w或Validform對(duì)象的tipmsg屬性修改和擴(kuò)展默認(rèn)錯(cuò)誤信息,如果你已經(jīng)設(shè)置了"zh2-4"的提示信息是"2-4位中文",那么"zh2-8"出錯(cuò)的信息就自動(dòng)會(huì)是:"2-8位中文"。對(duì)于自定義的datatype,在擴(kuò)展默認(rèn)信息時(shí),注意錯(cuò)誤信息的名字要跟datatype名字一樣,如上面示例是:$.Tipmsg.w["zh2-4"]="2-4位中文"。對(duì)于多頁(yè)面或一個(gè)頁(yè)面多表單有相同datatype來(lái)說,在$.Tipmsg.w或Validform對(duì)象的tipmsg屬性中擴(kuò)展默認(rèn)提示信息是個(gè)很好的選擇。
5.3.1+
$.Tipmsg.s是用來(lái)指定在沒有綁定nullmsg時(shí)的默認(rèn)提示信息。"{0}"是會(huì)被找到的label參數(shù)指定的對(duì)象或Validform_label里的文字替換掉的,"{填寫|選擇}"里的文字在綁定了"recheck"屬性的表單元素上檢測(cè)時(shí)是會(huì)不顯示的,當(dāng)前驗(yàn)證對(duì)象是radio、checkbox或select時(shí),會(huì)輸出"選擇",是其他類型的元素時(shí)會(huì)輸出"填寫"和后面的"信息"。
具體示例請(qǐng)參見demo頁(yè)。
dataType【object】
獲取內(nèi)置的一些正則:
{ "match":/^(.+?)(\d+)-(\d+)$/, "*":/[\w\W]+/, "*6-16":/^[\w\W]{6,16}$/, "n":/^\d+$/, "n6-16":/^\d{6,16}$/, "s":/^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]+$/, "s6-18":/^[\u4E00-\u9FA5\uf900-\ufa2d\w\.\s]{6,18}$/, "p":/^[0-9]{6}$/, "m":/^13[0-9]{9}$|14[0-9]{9}|15[0-9]{9}$|18[0-9]{9}$/, "e":/^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/, "url":/^(\w+:\/\/)?\w+(\.\w+)+.*$/ }
addRule(rule)【返回值:Validform】
可以通過Validform對(duì)象的這個(gè)方法來(lái)給表單元素綁定驗(yàn)證規(guī)則,綁定驗(yàn)證類型中列出的附加屬性都可以通過這個(gè)方法綁定。
demo.addRule([ { ele:"#name", datatype:"s6-18", ajaxurl:"valid.php", nullmsg:"請(qǐng)輸入昵稱!", errormsg:"昵稱至少6個(gè)字符,最多18個(gè)字符!" }, { ele:"#userpassword", datatype:"*6-16", nullmsg:"請(qǐng)?jiān)O(shè)置密碼!", errormsg:"密碼范圍在6~16位之間!" }, { ele:"#userpassword2", datatype:"*", recheck:"userpassword", nullmsg:"請(qǐng)?jiān)佥斎胍淮蚊艽a!", errormsg:"您兩次輸入的賬號(hào)密碼不一致!" } ]);
其中ele是指定要綁定規(guī)則的對(duì)象,會(huì)在Validform對(duì)象下查找這些對(duì)象。
eq(n)【返回值:Validform】
獲取Validform對(duì)象的第n個(gè)元素。
如你頁(yè)面上有多個(gè)form的class都是formsub,執(zhí)行上面的驗(yàn)證綁定,得到的demo對(duì)象就可以操作所有這些表單,如果你要對(duì)其中某個(gè)表單執(zhí)行某些操作,那么就可以使用這個(gè)方法。
如demo.eq(0).resetForm(),重置第一個(gè)表單。
ajaxPost(flag,sync,url)【返回值:Validform】
以ajax方式提交表單。flag為true時(shí),跳過驗(yàn)證直接提交,sync為true時(shí)將以同步的方式進(jìn)行ajax提交。
參數(shù)url是5.3版新增,傳入了url地址時(shí),表單會(huì)提交到這個(gè)地址
如demo.ajaxPost(true),不做驗(yàn)證直接ajax提交表單。
abort()【返回值:Validform】
終止ajax的提交。
如執(zhí)行上面的ajaxPost()之后,發(fā)現(xiàn)某些項(xiàng)填寫不對(duì),想取消表單提交,那么就可以執(zhí)行這個(gè)操作:demo.abort()
submitForm(flag,url)【返回值:Validform】
以初始化時(shí)傳入?yún)?shù)的設(shè)置方式提交表單,flag為true時(shí),跳過驗(yàn)證直接提交。
參數(shù)url是5.3版新增,傳入了url地址時(shí),表單會(huì)提交到這個(gè)地址
如demo.submitForm(true),不做驗(yàn)證直接提交表單。
resetForm()【返回值:Validform】
重置表單。
如demo.resetForm(),重置表單到初始狀態(tài)。
resetStatus()【返回值:Validform】
重置表單的提交狀態(tài)。傳入了postonce參數(shù)的話,表單成功提交后狀態(tài)會(huì)設(shè)置為"posted",重置提交狀態(tài)可以讓表單繼續(xù)可以提交。
如demo.resetStatus()
getStatus()【返回值:String】
獲取表單的提交狀態(tài),normal:未提交,posting:正在提交,posted:已成功提交過。
如demo.getStatus()
setStatus(status)【返回值:Validform】
設(shè)置表單的提交狀態(tài),可以設(shè)置normal,posting,posted三種狀態(tài),不傳參則設(shè)置狀態(tài)為posting,這個(gè)狀態(tài)表單可以驗(yàn)證,但不能提交。
如demo.setStatus("posted")
ignore(selector)【返回值:Validform】
忽略對(duì)所選擇對(duì)象的驗(yàn)證,不傳入selector則忽略所有表單元素。
如demo.ignore("select,textarea,#name"),忽略Validform對(duì)象下所有select,textarea及一個(gè)id為"name"元素的驗(yàn)證。
unignore(selector)【返回值:Validform】
將ignore方法所忽略驗(yàn)證的對(duì)象重新獲取驗(yàn)證效果,不傳入selector則恢復(fù)驗(yàn)證所有表單元素。
如demo.unignore("select,textarea,#name"),恢復(fù)Validform對(duì)象下所有select,textarea及一個(gè)id為"name"元素的驗(yàn)證。
check(bool,selector)【返回值:Boolean】
bool為true時(shí)則只驗(yàn)證不顯示提示信息
對(duì)指定對(duì)象進(jìn)行驗(yàn)證(默認(rèn)驗(yàn)證當(dāng)前整個(gè)表單),通過返回true,否則返回false(綁定實(shí)時(shí)驗(yàn)證的對(duì)象,格式符合要求時(shí)返回true,而不會(huì)等ajax的返回結(jié)果)
如demo.check(),驗(yàn)證當(dāng)前整個(gè)表單,且只驗(yàn)證但不顯示對(duì)錯(cuò)信息。
config(setup) 5.3+ 【返回值:Validform】
setup參數(shù)是一個(gè)對(duì)象。
介
JeeWeb是一款基于SpringBoot 2+Spring+Mybatis+Hibernate的敏捷開發(fā)系統(tǒng);它是一款具有代碼生成功能的智能快速開發(fā)平臺(tái);是以Spring Framework為核心容器,Spring MVC為模型視圖控制器,Hibernate為數(shù)據(jù)訪問層, Apache Shiro為權(quán)限授權(quán)層,Ehcahe對(duì)常用數(shù)據(jù)進(jìn)行緩存,Disruptor作為并發(fā)框架,Bootstrap作為前端框架的優(yōu)秀 開源 系統(tǒng)。
JeeWeb是一款 全開源開發(fā)平臺(tái) ,特別 代碼生成器模塊也采用開源模式 ,各位開發(fā)者可以根據(jù)自己的需要改造出更加適合自己的代碼生成器,不管是做項(xiàng)目、學(xué)習(xí)、接私活它都將是你的最佳拍檔;
JeeWeb主要定位于企業(yè)快速開發(fā)平臺(tái)建設(shè),已內(nèi)置很多優(yōu)秀的基礎(chǔ)功能和高效的 代碼生成 工具,包括:系統(tǒng)權(quán)限組件、數(shù)據(jù)權(quán)限組件、數(shù)據(jù)字典組件、核心工具組件、視圖操作組件、代碼生成、 UI模版標(biāo)簽 庫(kù)等。前端界面風(fēng)格采用了結(jié)構(gòu)簡(jiǎn)單、性能優(yōu)良、頁(yè)面美觀大氣的Twitter Bootstrap頁(yè)面展示框架。采用分層設(shè)計(jì)、提交數(shù)據(jù)安全編碼、密碼加密、訪問驗(yàn)證、數(shù)據(jù)權(quán)限驗(yàn)證。使用Maven做項(xiàng)目管理,提高項(xiàng)目的易開發(fā)性、擴(kuò)展性。
目前功能模塊代碼生成器、權(quán)限框架、數(shù)據(jù)字典、數(shù)據(jù)緩存、并發(fā)框架、數(shù)據(jù)監(jiān)控、計(jì)劃任務(wù)、多數(shù)據(jù)源管理、附件管理、類似mybatis動(dòng)態(tài)SQL、UI模板標(biāo)簽、短信發(fā)送、郵件發(fā)送、統(tǒng)計(jì)功能等功能。
JeeWeb的開發(fā)方式采用( 代碼生成器快速設(shè)計(jì)生成代碼->手工完善邏輯->豐富模板標(biāo)簽快速前端開發(fā) ),可以快速協(xié)助java開發(fā)人員解決60%的重復(fù)工作,讓開發(fā)人員更多關(guān)注業(yè)務(wù)邏輯的實(shí)現(xiàn),框架使用前端模板標(biāo)簽,解放JAVA開發(fā)人員的開發(fā)壓力,提高開發(fā)效率,為企業(yè)節(jié)省項(xiàng)目研發(fā)成本,減少開發(fā)周期。
后臺(tái)框架演示(支持兩種前端樣式自由切換)
論壇演示
前后端分離演示
JeeWeb 技術(shù)特點(diǎn)
JeeWeb使用目前流程的WEB開發(fā)架構(gòu)技術(shù),如 SpringBoot,Mybatis, Hibernate,Apache Shiro, Disruptor , ehcache, Jquery ,BootStrap等等,支持多種數(shù)據(jù)庫(kù)MySQL, Oracle, sqlserver等。 分層設(shè)計(jì):使用分層設(shè)計(jì),分為dao,service,Controller,view層,層次清楚,低耦合,高內(nèi)聚。
安全考慮:嚴(yán)格遵循了web安全的規(guī)范,前后臺(tái)雙重驗(yàn)證,參數(shù)編碼傳輸,密碼md5加密存儲(chǔ),shiro權(quán)限驗(yàn)證,從根本上避免了SQL注入,XSS攻擊,CSRF攻擊等常見的web攻擊手段。
JeeWeb 功能特點(diǎn)
1、后端
2、前端
簡(jiǎn)單使用說明
平臺(tái)目錄結(jié)構(gòu)說明
jeeweb ├─jeeweb-common 公共模塊 │ ├─jeeweb-common-base 公用基礎(chǔ)模塊 │ │ │ ├─jeeweb-common-email 郵件基礎(chǔ)模塊 │ │ │ ├─jeeweb-common-hibernatemvc hibernate公用模塊 │ │ │ ├─jeeweb-common-mybatismvc mybatis公用模塊 │ │ │ ├─jeeweb-common-oss 數(shù)據(jù)存儲(chǔ)公用模塊 │ │ │ ├─jeeweb-common-quartz quartz公用模塊 │ │ │ ├─jeeweb-common-query 查詢封裝模塊 │ │ │ ├─jeeweb-common-security 安全公用模塊 │ │ │ ├─jeeweb-common-sms 短信公用模塊 │ │ │ └─jeeweb-common-utils 公用工具模塊 │ ├─jeeweb-ui UI模塊 │ ├─jeeweb-beetl-tag 基于beetl的類似spring form的模板標(biāo)簽 │ │ │ ├─jeeweb-ui-static 公用靜態(tài)資源模塊 │ │ │ └─jeeweb-ui-tag 基于靜態(tài)資源模塊的標(biāo)簽 │ ├─jeeweb-web 業(yè)務(wù)模塊 │ ├─jeeweb-admin 后臺(tái)案例模塊 │ │ │ ├─jeeweb-bbs Jeeweb官方論壇代碼模塊 │ │ │ ├─jeeweb-vue 前后端分離后端模塊 │ │ │ └─jeeweb-generator 代碼生成器模塊 │
代碼示例
[1].GRID列表
<#grid:grid id="onlineGrid" datatype="local" datas="${onlineSessionList}" sortname="startTimestamp" sortorder="desc"> <#grid:column label="sys.common.key" hidden="true" name="id" width="100"/> <#grid:column label="用戶" name="username" /> <#grid:column label="用戶主機(jī)IP" name="host" /> <#grid:column label="系統(tǒng)主機(jī)IP" name="systemHost" /> <#grid:column label="登錄時(shí)間" name="startTimestamp" width="140" queryMode="date" condition="between" /> <#grid:column label="最后訪問時(shí)間" name="lastAccessTime" width="140"/> <#grid:column label="狀態(tài)" name="status" dict="onlinestatus" /> <#grid:column label="User-Agent" name="userAgent" /> <#grid:column label="用戶會(huì)話ID" name="id" /> <#grid:toolbar title="強(qiáng)制退出" btnclass="btn-danger" icon="fa-trash-o" function="toolbarSelectConfirm" url="${adminPath}/sys/online/forceLogout" tipMsg="您確定要強(qiáng)制退出這些信息么,請(qǐng)謹(jǐn)慎操作!"/> </#grid:grid>
[2].TREEGRID列表
<#grid:grid id="organizationGrid" async="true" treeGrid="true" expandColumn="name" url="${adminPath}/sys/organization/ajaxTreeList"> <#grid:column label="sys.common.key" hidden="true" name="id" width="100"/> <#grid:column label="sys.organization.name" name="name" query="true" condition="like" /> <#grid:column label="sys.organization.remarks" name="remarks" /> <#grid:column label="sys.common.opt" name="opt" formatter="button" width="100"/> <#grid:button groupname="opt" function="delete" /> <#grid:toolbar function="add"/> <#grid:toolbar function="update"/> <#grid:toolbar function="delete"/> <#grid:toolbar function="search"/> <#grid:toolbar function="reset"/> </#grid:grid>
[3].表單代碼
<% layout('/layouts/form.html', {title: @MessageUtils.getMessage('sys.user.updateuser',''), formId: 'userForm', bodyClass: 'white-bg', libs: 'bootstrap-fileinput'}){ %> <#form:form id="userForm" modelAttribute="data" method="post" class="form-horizontal"> <#form:hidden path="id" /> <table class="table table-bordered table-condensed dataTables-example dataTable no-footer"> <tbody> <tr> <td class="width-15 active text-right"> <label>用戶名:</label></td> <td class="width-35">${data.username}</td> <td class="width-15 active text-right"> <label> <font color="red">*</font>姓名:</label></td> <td class="width-35"> <#form:input path="realname" class="form-control " datatype="*" nullmsg="請(qǐng)輸入姓名!" htmlEscape="false" /> <label class="Validform_checktip"></label> </td> </tr> <tr> <td class="width-15 active text-right"> <label> <font color="red">*</font>郵箱:</label></td> <td class="width-35"> <#form:input path="email" class="form-control" datatype="e" nullmsg="請(qǐng)輸入姓名!" htmlEscape="false" /> <label class="Validform_checktip"></label> </td> <td class="width-15 active text-right"> <label> <font color="red">*</font>聯(lián)系電話:</label></td> <td class="width-35"> <#form:input path="phone" class="form-control" htmlEscape="false" datatype="m" nullmsg="請(qǐng)輸入用戶名!" /> <label class="Validform_checktip"></label> </td> </tr> <tr> <td class="active"> <label class="pull-right"> <font color="red">*</font>用戶角色:</label></td> <td colspan="3"> <#form:checkboxes path="roleIdList" nested="false" items="${allRoles}" defaultValue="${roleIdList}" itemLabel="name" itemValue="id" htmlEscape="false" cssClass="i-checks required" /></td> </tr> <tr> <td class="width-15 active"> <label class="pull-right">組織機(jī)構(gòu):</label></td> <td colspan="3"> <#form:treeselect title="請(qǐng)選擇組織機(jī)構(gòu)" path="organizationIds" nested="false" dataUrl="${adminPath}/sys/organization/treeData" chkboxType="" labelName="parentname" labelValue="${organizationNames}" multiselect="true" /></td> </tr> </tbody> </table> </#form:form> <% } %>
git地址:https://gitee.com/dataact/jeeweb
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。