nutz框架中如何实现登录验证

一、nutz介绍

     Nutz是对于Java程序员来说,除SSH之外的另一个选择。当然,它是开源的,并且是完全免费的。同时也是商业友好的(Licensed under the Apache License, Version 2.0)。主页如下:http://www.nutzam.com/

二、session简单介绍

     大家都知道http是无状态的,即:同一个浏览器发送多个请求,服务端并不知道这些请求是来自于同一个浏览器。所以为了使服务端知道这些请求都是来自于同 一个浏览器,用到了session技术。即浏览器第一次发送请求给服务端时,服务端会生成一个sessionId,将该sessionId返回给浏览器, 浏览器将sessionId以cookie的形式保存在客户端,下一次请求该服务器的时候,会将sessionId带过去,服务端可以根据该 sessionId找到在这个session保存的值,并使用该session中保存的值进行一系列的操作。

三、nutz中登录验证的实现方式

1、准备工作

    需要有以下准备:/toLogin指向登录页面;/login点击登录后处理登录的方法;/logout指向登出;/test指向一般的业务处理方法。/home指向登录成功后跳转的主页面。

    其中:/toLogin和/login是不需要进行登录验证的。

            /logout、/test、/home是需要进行登录验证的。

    要实现的结果如下:

            点击登录/login时,根据用户名/密码进行验证,若登录成功,则将该user保存到session中,并跳转到/home主页;若登录失败,则跳转到/toLogin。

            会为其他进行登录验证的方法,实现一个过滤器,在该过滤器中根据session中的user对象是否存在,进行验证,若存在,跳转到/home主页,否则跳转/toLogin页面。

    负责登录、登出、及登录主页的类代码如下:

 

package xxx.xxx.module;
import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.nutz.ioc.loader.annotation.IocBean;import org.nutz.mvc.annotation.At;import org.nutz.mvc.annotation.Filters;import org.nutz.mvc.annotation.Ok;

@IocBeanpublic class LoginDemo {

    /**
     * 该方法指向登录页面
     */
    @Filters //配置Filters之后该方法将不执行过滤器
    @At("/toLogin")
    @Ok("")//此处配置登录页面的路径
    public void toLogin(){
    }
   
    /**
     * 该方法为登录时的处理方法
     * 结果以重定向的方式来跳转。
     * 若登录成功,跳转到/home。若登录失败,跳转到/toLogin
     * @param req
     * @param session
     * @return
     */
    @At("/login")
    @Ok("redirect:${obj==true?'/home':'/toLogin'}")
    @Filters
    public boolean login(HttpServletRequest req,HttpSession session){
        String userName=req.getParameter("name");
        String pwd=req.getParameter("pwd");
        boolean result=false;//登录成功与否的结果。默认为false
       
        if(!isBlank(userName) && !isBlank(pwd)){
            /**
             * 此处根据输入的用户名和密码进行数据库查询验证,查看该用户是否存在。
             * 一般在用户注册或者新增用户时,都会将密码进行加密。或者将用户名为salt,对密码进行加密并保存到数据库。
             * 此时需要对用户名和密码进行相同的加密。并以用户名,加密后的密码为条件,从数据库中查询该用户。
             * 若存在,则登录成功。
             */
           
            /**
             * 此处user模拟从数据库中查询出的对象
             */
            User user=new User();
           
            if(user!=null){
                result=true;//此时登录成功
                session.setAttribute("user", user);//将该user保存到session中。            }
        }
       
        return result;
    }
   
   
    /**
     * 登出
     * @param session
     */
    @At("/logout")
    @Ok("redirect:/toLogin")
    public void logout(HttpSession session){
        session.invalidate();//将该session销毁    }
   
   
    /**
     * 判断str是否为空或"" 若是,返回true。 否则返回false
     * @param str
     * @return
     */
    private  boolean isBlank(String str){
        if(str==null || "".equals(str.trim())){
            return true;
        }else{
            return false;
        }
    }
}

2、使用自带的CheckSession.class过滤器

     需要在indexModule主入口类中配置过滤器,如下所示:

 

package xxx.xxx.module;
import org.nutz.mvc.annotation.By;
import org.nutz.mvc.annotation.Filters;
import org.nutz.mvc.filter.CheckSession;
//其中:"user"为session中的属性名。"/toLogin"为若该属性不存在时的处理。此处为跳转到登录页面。
@Filters(@By(type = CheckSession.class,args={"user","/toLogin"}))public class InitModule {

}

     nutz中的CheckSession.class源代码如下:

 

package org.nutz.mvc.filter;import javax.servlet.http.HttpSession;import org.nutz.mvc.ActionContext;import org.nutz.mvc.ActionFilter;import org.nutz.mvc.Mvcs;import org.nutz.mvc.View;import org.nutz.mvc.view.ServerRedirectView;/**
 * 检查当前 Session,如果存在某一属性,并且不为 null,则通过 <br>
 * 否则,返回一个 ServerRecirectView 到对应 path
 * <p>
 * 构造函数需要两个参数
 * <ul>
 * <li>第一个是, 需要检查的属性名称。如果 session 里存在这个属性,则表示通过检查
 * <li>第二个是,如果未通过检查,将当前请求转向何处。 一个类似 /yourpath/xxx.xx 的路径
 * </ul>
 *
 * @author zozoh(zozohtnt@gmail.com)
 */public class CheckSession implements ActionFilter {

    private String name;
    private String path;

    public CheckSession(String name, String path) {
        this.name = name;
        this.path = path;
    }

    public View match(ActionContext context) {
        HttpSession session = Mvcs.getHttpSession(false);
        if (session == null || null == session.getAttribute(name))
            return new ServerRedirectView(path);
        return null;
    }

}

3、自定义过滤器

    以下为自定义过滤器MyFilter的代码实现:

 

package xxx.xxx.filters;import javax.servlet.http.HttpSession;import org.nutz.ioc.loader.annotation.IocBean;import org.nutz.mvc.ActionContext;import org.nutz.mvc.ActionFilter;import org.nutz.mvc.View;import org.nutz.mvc.view.ServerRedirectView;
/**
 * 自定义的登录验证!
 * @author
 *
 */
@IocBeanpublic class MyFilter implements ActionFilter{

    @Override
    public View match(ActionContext actionContext) {
       
        HttpSession session=actionContext.getRequest().getSession();
        if(session.getAttribute("user")!=null){
            return null;//执行方法        }
       
        //验证不通过时跳转到别的页面!
        return new ServerRedirectView("/toLogin.html");
    }

}

   其实和CheckSession的实现是很类似的。

   自定义Filter的配置和内置的CheckSession.class配置类似,配置如下:

 

@Filters(@By(type = MyFilter.class ,args={"ioc:myFilter"}))

 

四、注意事项与参考资料

1、 注意事项

      被IOC管理的类,均需在类名前添加@IocBean。

      如果在登录时需在session中保存多个属性,需把"user",user 用于登录验证的属性放在最后,以防止各种空指针的问题。参考资料:http://wendal.net/399.html

2、参考资料

     过滤器相关:http://www.nutzam.com/core/mvc/action_filter.html

     入口函数返回的View相关:http://www.nutzam.com/core/mvc/view.html 

 

 

在Nutz框架中提供Pojo校验(验证)功能的支持

作为java程序员,往往对于spring、struts、Hibernate、iBatis 等国外的开源框架都比较熟悉。它们的确经典,的确强大,的确好用。但是随着时间的发展,这些框架越来越庞大!Hibernate的核心包已经超过2M, spring呢,它现在已经被拆分为 18 个子项目,而且还有继续扩大的趋势。为了一个小小的功能,引入那么一大堆lib包,任谁都得考虑一下吧。

……

这个问题一直存在,直到 Nutz 框架的出现。

一个不到 900K 的开源框架,不仅包含了 ioc、aop、dao、mvc、log,还整合了很多好用的工具类,基本上我们做一个项目需要用到的功能都提供了。

还有要说明的是,它可是国人的开源项目哦,提供全套中文文档,及大量的中文注释。国内的开发人员应该会感到比较亲切吧。

 

更详细的信息,请参看Nutz的官方网站: http://code.google.com/p/nutz/

Nutz框架虽然提供了很多功能,却独独拉了校验功能的支持。我们知道,一个程序,尤其是Web程序,如果没有服务器端验证,那么将非常容易受到攻击的。

“自己动手,丰衣足食”。既然官方没有提供,那就自己搞一套吧。还好基于Nutz现有的工具类,实现起来并不太复杂。

 

整个验证框架提供了12种常见的验证形式,且支持自定义正则表达式,基本上可以满足实际的需要。对于有特殊要求的字段验证,允许用户自己定义验证的方法。

校验不仅可以用于Web层,你可以把它用于程序的任何层面(如入库前对pojo 字段值进行验证)。

目前验证框架基于注解,因为对于字段的验证需求一般比较固定,所以同代码一块管理比较方便。当然你也可以扩展它,提供其它形式的验证。如果你有更好的改动,请也一并发我邮箱一份哈。

废话不多说,直接上代码吧。

    /**
     * 验证支持注解
     * 
     * @author QinerG(QinerG@gmail.com)
     */ 
    @Retention(RetentionPolicy.RUNTIME) 
    @Target( { ElementType.PARAMETER, ElementType.FIELD }) 
    public @interface Validations { 
     
        /**
         * 必填字段验证规则
         */ 
        public boolean required() default false; 
     
        /**
         * 手机号验证规则
         */ 
        public boolean mobile() default false; 
     
        /**
         * 帐号验证规则(字母开头,允许字母数字下划线),常与字串长度验证规则混合使用
         */ 
        public boolean account() default false; 
     
        /**
         * Email 验证规则
         */ 
        public boolean email() default false; 
     
        /**
         * QQ 号验证规则
         */ 
        public boolean qq() default false; 
     
        /**
         * 字串必须为中文验证规则
         */ 
        public boolean chinese() default false; 
     
        /**
         * 邮政编码验证规则
         */ 
        public boolean post() default false; 
     
        /**
         * 正则表达式验证规则
         */ 
        public String regex() default ""; 
     
        /**
         * 重复性验证规则。请放置待比较的字段名
         */ 
        public String repeat() default ""; 
     
        /**
         * 字符串最大、最小长度验证规则
         */ 
        public int[] strLen() default {}; 
     
        /**
         * 数值型数据取值范围区间验证规则,兼容 int、long、float、double
         */ 
        public double[] limit() default {}; 
     
        /**
         * 自定义效验规则,可以自行指定验证的方法名称 <br/> 该方法必须是public的,且没有参数返回值为boolean型
         */ 
        public String custom() default ""; 
     
        /**
         * 错误提示语
         */ 
        public String errorMsg(); 
    } 

 

这就是注解类的全部代码。该注解是字段(FIELD)级别的,所以你可以把它声明在pojo的属性上。

比如:

    //账号验证规则,与字符串长度区间验证共同作用 
    @Validations(account = true, strLen = { 3, 16 }, errorMsg = "account") 
    private String account; 

 

允许多种验证同时声明,errorMsg 是错误提示语,必填。

 

当pojo需要验证的时候,可以这样写:

 
Java代码  收藏代码

    AnnotationValidation av = new AnnotationValidation(); 
    Errors ers = av.validate(pojo); 

       验证错误的信息都存放在 Errors 对象中了,你可以调用 getErrorsList() 返回错误列表,或者调用 getErrorsMap() 字段与错误提示语的对应关系。

这时也许你会说,这种调用方法很麻烦。每次验证的时候,都需要创建 AnnotationValidation 的实例,有没有更简单的方法呢?

没错,Nutz提供了 AOP 的支持,这样我们就可以很方便的用它来进行拦截验证了。

下面是拦截器的全部代码:

    /**
     * 基于注解的验证用拦截器
     * <p>
     * 该拦截器主要用于方法参数的验证,要求该方法中必须有一个 Errors 类型的参数(允许为空),当验证完成后会向这个参数赋值
     * 
     * @author QinerG(QinerG@gmail.com)
     */ 
    @IocBean(name = "validationInterceptor") 
    public class ValidationInterceptor extends AbstractMethodInterceptor { 
     
        private static AnnotationValidation av = new AnnotationValidation(); 
     
        /**
         * 方法调用前进行拦截,遍历参数进行验证
         */ 
        public boolean beforeInvoke(Object obj, Method method, Object... args) { 
            Errors es = ValidationUtils.checkArgs(method.getParameterTypes(), args); 
            if (null != es) { 
                for (Object argsObj : args) { 
                    if (argsObj instanceof Errors) 
                        continue; 
                    av.validate(argsObj, es); 
                } 
            } 
            return true; 
        } 
    } 

 

注意:该拦截器主要用于方法参数的验证,要求该方法中必须有一个 Errors 类型的参数(允许为空),当验证完成后会向这个参数赋值。

有了这个拦截器,就方便多了。只需要在需要提供验证功能的方法前使用 @Aop("validationInterceptor") 声明,例如:

    @Aop("validationInterceptor") 
        public Errors test(Bean bean, Errors es) { 
            System.out.println(es.errorCount()); 
            return es; 
        } 

之后在调用这个方法的时候,拦截器就会自动执行,并将验证结果注入到参数 Errors 中。下面是 junit测试用例:

    @Test 
        public void testAop() {      
            Ioc ioc = new NutIoc(new AnnotationIocLoader("org.nutz.validation")); 
             
            ServiceDemo sd = ioc.get(ServiceDemo.class); 
            Bean b = new Bean(); 
            Errors ers = sd.test(b, null); 
            assertEquals(10, ers.errorCount()); 
        } 

 

这样是不就方便了很多?

应用程序可以用 aop 的方式验证,那么 web 程序呢,也可以这样用吗?那是当然了。在 action 前声明拦截器:

    @At("/test") 
        @Ok("json") 
        @Aop("validationInterceptor") 
        public int test(@Param("bean")Bean bean, Errors es) { 
            System.out.println(Dumps.obj(bean)); 
            if (es != null) { 
                return es.errorCount(); 
            } 
            return -99; 
        } 

 

action 里即可以取到 Errors 对象,并可以对其进行显示等相关处理啦。

时间: 2024-09-17 03:32:07

nutz框架中如何实现登录验证的相关文章

Yii框架中jquery表单验证插件用法示例_php实例

本文实例讲述了Yii框架中jquery表单验证插件用法.分享给大家供大家参考,具体如下: 运行效果图如下: 视图层: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtm

tapestry 框架中 客户端表单验证后 如何判断是否验证成功 并当验证成功后调用我自己写的一个js函数

问题描述 tapestry框架中客户端表单验证后如何判断是否验证成功并当验证成功后调用我自己写的一个js函数谢谢

Yii框架中jquery表单验证插件用法示例

本文实例讲述了Yii框架中jquery表单验证插件用法.分享给大家供大家参考,具体如下: 运行效果图如下: 视图层: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtm

Shiro安全框架入门篇(登录验证实例详解与源码)

版权声明:本文为博主原创文章,转载注明出处http://blog.csdn.net/u013142781 目录(?)[+] 一.Shiro框架简单介绍 Apache Shiro是Java的一个安全框架,旨在简化身份验证和授权.Shiro在JavaSE和JavaEE项目中都可以使用.它主要用来处理身份认证,授权,企业会话管理和加密等.Shiro的具体功能点如下: (1)身份认证/登录,验证用户是不是拥有相应的身份:  (2)授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户是否能做

java中servlet实现登录验证的方法_java

login.java: 复制代码 代码如下: package com.ncu;import java.io.PrintWriter; import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class login extends HttpServlet{ public void do

Python的Flask框架中实现简单的登录功能的教程

  Python的Flask框架中实现简单的登录功能的教程,登录是各个web框架中的基础功能,需要的朋友可以参考下 回顾 在前面的系列章节中,我们创建了一个数据库并且学着用用户和邮件来填充,但是到现在我们还没能够植入到我们的程序中. 两章之前,我们已经看到怎么去创建网络表单并且留下了一个实现完全的登陆表单. 在这篇文章中,我们将基于我门所学的网络表单和数据库来构建并实现我们自己的用户登录系统.教程的最后我们小程序会实现新用户注册,登陆和退出的功能. 为了能跟上这章节,你需要前一章节最后部分,我们

利用Python的装饰器解决Bottle框架中用户验证问题

  这篇文章主要介绍了Python的Bottle框架中解决用户验证问题,代码基于Python2.x版本,需要的朋友可以参考下 首先来分析下需求,web程序后台需要认证,后台页面包含多个页面,最普通的方法就是为每个url添加认证,但是这样就需要每个每个绑定url的后台函数都需要添加类似或者相同的代码,但是这样做代码就过度冗余,而且不利于扩展. 接下来我们先不谈及装饰器,我们都知道Python是个很强大的语言,她可以将函数当做参数传递给函数,最简单的: ? 1 2 3 4 5 6 7 8 9 10

《ASP.NET MVC验证框架中关于属性标记的通用扩展方法》之继续扩展

首先需要对xVal有点熟悉: http://www.codeplex.com/xval 建议下载最新源码而不是编译版本 再看两篇文章: http://goneale.com/2009/03/04/using-metadatatype-attribute-with-aspnet-mvc-xval- validation-framework/ 深山老林将之翻译为:<ASP.NET MVC验证框架中关于属性标记的通用扩展方法> http://www.cnblogs.com/wlb/archive/2

ASP.NET MVC验证框架中关于属性标记的通用扩展方法

之前写过一篇文章<ASP.NET MVC中的验证>,唯一的遗憾就是在使用Data Annotation Validators方式验证的时候,如果数据库是Entityframework等自动生成的文件,就没有办法使用扩展属性标记进行标记.现在已经开始有了一些其它的Asp.net MVC 验证框架,使用上跟Data Annotation Validators差不太多,但是普遍有这样的问题,如果数据库是Entityframework生成的edm文件,没有办法进行扩展属性标记. 今天在网上发现了另外一