1. 程式人生 > >Shiro結合攔截所有的ajax並對其請求響應進行統一處理的辦法

Shiro結合攔截所有的ajax並對其請求響應進行統一處理的辦法

1. spring-mvc.xml中 給shiro的配置增加一條屬性:

<property name="filters">
			<map>
				<entry key="authc">
					<bean class="com.abc.realm.LoginAdviceFilter" />
				</entry>
			</map>
		</property>

2.編寫LoginAdviceFilter.java 類

package com.abc.realm;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.AdviceFilter;

import com.abc.entity.Result;
import com.abc.entity.User;

import net.sf.json.JSONObject;

/**
 * shiro Filter,判定登入狀態是否失效
 *
 * @author DaiHaijiao
 *
 */
public class LoginAdviceFilter extends AdviceFilter {
	/**
	 * 在訪問controller前判斷是否登入,返回json,不進行重定向
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		HttpServletResponse httpServletResponse = (HttpServletResponse) response;

		User sysUser = getUser();
		if (null == sysUser && !StringUtils.contains(httpServletRequest.getRequestURI(), "/login")) {
			String requestedWith = httpServletRequest.getHeader("X-Requested-With");
			if (StringUtils.isNotEmpty(requestedWith) && StringUtils.equals(requestedWith, "XMLHttpRequest")) {// 如果是ajax返回指定資料
				httpServletResponse.setCharacterEncoding("UTF-8");
				httpServletResponse.setContentType("application/json");
				httpServletResponse.getWriter().write(JSONObject.fromObject(Result.genResult(Result.LOGIN_TO_OPERATE)) + "");
				return false;
			} else {// 不是ajax
				return true;
			}
		}
		return true;
	}

	/**
	 * 獲取當前登入使用者
	 * 
	 * @return
	 */
	protected User getUser() {
		Subject subject = SecurityUtils.getSubject();
		if (subject.isAuthenticated()) {
			return (User) subject.getPrincipal();
		}
		return null;
	}
}

2. jsp頁面引入ajaxhook.min.js 和 3.裡面自己寫的那個js

Ajax-hook其實就是實現了一個代理模式而已,實現的整體思路是實現一個XMLHttpRequest的代理物件,然後覆蓋全域性的XMLHttpRequest,這樣一但上層呼叫 new XMLHttpRequest這樣的程式碼時,其實建立的是Ajax-hook的代理物件例項。

!function(t){function r(i){if(n[i])return n[i].exports;var o=n[i]={exports:{},id:i,loaded:!1};return t[i].call(o.exports,o,o.exports,r),o.loaded=!0,o.exports}var n={};return r.m=t,r.c=n,r.p="",r(0)}([function(t,r,n){n(1)(window)},function(t,r){t.exports=function(t){t.hookAjax=function(t){function r(t){return function(){return this.hasOwnProperty(t+"_")?this[t+"_"]:this.xhr[t]}}function n(r){return function(n){var i=this.xhr,o=this;return 0!=r.indexOf("on")?void(this[r+"_"]=n):void(t[r]?i[r]=function(){t[r](o)||n.apply(i,arguments)}:i[r]=n)}}function i(r){return function(){var n=[].slice.call(arguments);if(!t[r]||!t[r].call(this,n,this.xhr))return this.xhr[r].apply(this.xhr,n)}}return window._ahrealxhr=window._ahrealxhr||XMLHttpRequest,XMLHttpRequest=function(){this.xhr=new window._ahrealxhr;for(var t in this.xhr){var o="";try{o=typeof this.xhr[t]}catch(t){}"function"===o?this[t]=i(t):Object.defineProperty(this,t,{get:r(t),set:n(t)})}},window._ahrealxhr},t.unHookAjax=function(){window._ahrealxhr&&(XMLHttpRequest=window._ahrealxhr),window._ahrealxhr=void 0},t.default=t}}]);

3. 再自定義一個js,新增攔截ajax後處理的公共方法<人為新增,可修改成自己想改的樣子>

hookAjax({
	// 攔截回撥
	onreadystatechange : function(xhr) {
		// console.log("onreadystatechange called: %O", xhr)
	},
	onload : function(xhr) {
		// console.log("onload called: %O", xhr)
		// 此處的code是LoginAdviceFilter.java返回的json裡的一個欄位
		if (JSON.parse(xhr.response).code == 2) {
			try {
				// TODO something...
			} catch (Exception) {
				// TODO something...
			}
		}
	},
	// 攔截函式
	open : function(arg) {
		// console.log("open called: method:%s,url:%s,async:%s", arg[0], arg[1], arg[2])
		// arg[1]+="?hook_tag=123456";
	},
	send : function(arg, xhr) {
		// console.log("send called: %O", arg[0])
		// xhr.setRequestHeader:function("_custom_header_","ajaxhook")
	},
	setRequestHeader : function(arg, xhr) {
		// console.log("setRequestHeader called!", arg)
	}
})