ajax 登陆 spring acegi

 如果希望用ajax登录,也是通过acegi认证的方式处理,但认证结果不要求刷新跳转,而是通过ajax只刷新原登录页面上的部分信息就行,如何处理?下面讲解一下处理步骤:

第一步:增加AcegiAjaxFilter,用于截获登录表单的提交

public class AcegiAjaxFilter extends OncePerRequestFilter {

privatestaticfinalLoglogger=LogFactory.getLog(AcegiAjaxFilter.class);

protectedvoiddoFilterInternal(HttpServletRequestrequest,

HttpServletResponseresponse,

                                    FilterChain filterChain) throws ServletException, IOException {

        //检查提交的变量中是否有ajax变量,没有就直接交给acegi默认处理

if(request.getParameter("ajax")==null;){

filterChain.doFilter(request,response);

return;

}

        RedirectResponseWrapper redirectResponseWrapper = new RedirectResponseWrapper(response);

        //acegi的filter chain处理认证,redirectResponseWrapper用于获取acegi认证处理后的跳转路径

        filterChain.doFilter(request, redirectResponseWrapper);

if(redirectResponseWrapper.getRedirect()!=null){

request.setCharacterEncoding("UTF-8");

response.setContentType("text/plain;charset=utf-8");

response.setHeader("Cache-Control","no-cache");

response.setDateHeader("Expires",0);

response.setHeader("Pragma","no-cache");

            String redirectURL = redirectResponseWrapper.getRedirect();

            //创建JSONObject对象,用于返回认证结果,便于ajax页面局部刷新

            JSONObject json=new JSONObject();            try{

                //在acegi认证失败跳转的url加上login_error=1

                //此外判断是否成功

if(redirectURL.indexOf("login_error=1")==-1){

json.put("success",true);

//获取用户登录信息

LoginUseruser=(User)request.getSession().getAttribute(Constant.ACEGI_SESSION_USER);

if(user!=null){

json.put("name",user.getName());

json.put("lastIp",user.getLastLoginIP());

json.put("lastTime",user.getLastLoginTime());

json.put("currIp",user.getCurrentIP());

}

}else{//登录失败

json.put("success",false);

StringerrorMsg=((AuthenticationException)request.getSession().getAttribute(AbstractProcessingFilter.ACEGI_SECURITY_LAST_EXCEPTION_KEY)).getMessage();

json.put("errorMsg",errorMsg);

}

}catch(JSONExceptione){

logger.error("AcegiAjaxFilterJSONException");

logger.error("message:"+e.getMessage());

}catch(Exceptione){

logger.error("AcegiAjaxFilterException");

logger.error("message:"+e.getMessage());

}

//把json数据写入response返回到页面

response.getOutputStream().write(json.toString().getBytes("UTF-8"));

}

}

}

第二步:配置web.xml,确保acegiAjaxFilter的mapping在acegi filter的前面,mapping是有匹配顺序的

     <filter>

<filter-name>acegiAjaxFilter</filter-name>

<filter-class>com.aiplay.portal.web.filter.AcegiAjaxFilter</filter-class>

    </filter>

    <filter-mapping>

<filter-name>acegiAjaxFilter</filter-name>

<url-pattern>/j_acegi_security_check</url-pattern>

    </filter-mapping>

   ....

  <filter-mapping>

<filter-name>AcegiFilterChainProxy</filter-name>

<url-pattern>/*</url-pattern>

    </filter-mapping>

第三步:修改acegi的配置文件

     authenticationProcessingFilter中的authenticationFailureUrl属性,在原来设定的url后面加上login_error=1,便于ajaxFilter捕获到;

   authenticationProcessingFilter中的filterProcessesUrl属性,要确保和acegiAjaxFilter的<filter-mapping>中设定的url-pattern,以及登录表单的action中的关键字符一样。

第四步:登录页面上利用jQuery和ajax进行处理

记得页面上要加载jquery.form.js库。

//用户登录 ajax实现

functionajaxLogin(){

varoptions={

target:'#loginMessage',//targetelement(s)tobeupdatedwithserverresponse

beforeSubmit:showWaitting,//pre-submitcallback

success:successHandler,//post-submitcallback

dataType:'json',//'xml','script',or'json'(expectedserverresponsetype)

clearForm:true//clearallformfieldsaftersuccessfulsubmit

//url:'j_acegi_security_check'//overrideforform's'action'attribute

//type:'post',//'get'or'post',overrideforform's'method'attribute

//resetForm:true//resettheformaftersuccessfulsubmit

//timeout:3000//$.ajaxoptionscanbeusedheretoo,forexample:

};

$('#loginForm').ajaxSubmit(options);

}

//提交之前执行,可以设定页面上出现等待符号

function showWaitting(formData, jqForm, options) {

....

returntrue;

}

function successHandler(responseText, statusText, xhr, $form)  {

    //responseText是json object    if(responseText.success){

        //登录成功处理

        ...

$("#info1").html(responseText.name);

$("#info2").html(responseText.lastIp);

        $("#info3").html(responseText.lastTime);

        $("#info3").html(responseText.currIp);

    }else{

       //登录失败处理

....

}

}

第五步:登录表单中的配置

action中的url最后要包含和authenticationProcessingFilter中的filterProcessesUrl属性以及acegiAjaxFilter的<filter-mapping>中设定的url-pattern一样的字符,

这里假如设成:j_acegi_security_check

在表单中添加<input type="hidden" name="ajax"/>,上面第一步的AcegiAjaxFilter代码中有一段

if (request.getParameter("ajax") == null;) {

filterChain.doFilter(request,response);

return;

}

相关推荐