教程集 www.jiaochengji.com
教程集 >  脚本编程  >  java  >  正文 nutz框架中如何实现登录验证

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

发布时间:2016-10-18   编辑:jiaochengji.com
教程集为您提供nutz框架中如何实现登录验证等资源,欢迎您收藏本站,我们将为您提供最新的nutz框架中如何实现登录验证资源
Nutz是一个java开发的优秀的国产开源项目,它是一组轻便小型的框架的集合,被称作是“除了SSH之外的另一个选择”,本文来看看我们用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 对象,并可以对其进行显示等相关处理啦。

您可能感兴趣的文章:
nutz框架中如何实现登录验证
PHP 登录完成跳转上一访问页面
JS的location.href跳出框架并打开新页面的方法
php实例之基于文件的登录验证
php图片验证码的例子
php点击验证码实时刷新的实现代码
c# WinForm登录的三种实现方法
session cookie实现自动登录(下次自动登录)
php单点登录是如何实现的
php session共享与登录验证的例子

[关闭]
~ ~