关闭

java中过滤器的使用

标签: filter跨域
907人阅读 评论(0) 收藏 举报
分类:
public final class EntranceFilter implements Filter {

	private static final String JSONP_CALLBACK = "callback";
	private static final String JSONP_UPLOAD_CALLBACK = "uploadcallback";
	private static final String HTTP_AJAX_TYPE = "ajax";

	@SuppressWarnings("unchecked")
	public void doFilter(ServletRequest req, ServletResponse respon, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) respon;
		
		//请求类型  如果是ajax请求响应头会有,x-requested-with;
		if (request.getHeader("x-requested-with") != null
				&& request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
			TempleConfigContext.setCurrentRequestType(TempleConfigContext.AJAX_REQUEST_TYPE);
		}
		
		//跨域请求
		if(request.getParameter(JSONP_CALLBACK) != null || request.getParameter(JSONP_UPLOAD_CALLBACK) != null){
			TempleConfigContext.setCurrentRequestType(TempleConfigContext.AJAX_REQUEST_TYPE);
		}
		
		if(request.getParameter(HTTP_AJAX_TYPE) != null){
			TempleConfigContext.setCurrentRequestType(TempleConfigContext.AJAX_REQUEST_TYPE);
		}
		
		//请求是ajax请求
		if(TempleConfigContext.getCurrentRequestType() == TempleConfigContext.AJAX_REQUEST_TYPE){
			ByteResponseWrapper brw = new ByteResponseWrapper(response);
			chain.doFilter(request, brw);
			String out = new String(brw.getBytes());
			
			//ajax矫正
			if(TempleConfigContext.getCurrentRequestType() == TempleConfigContext.AJAX_REQUEST_TYPE){
				Map<String, Object> map = null;
				try {
					map = JsonTool.getMap4Json(out);
				} catch (JSONException ex) {
					map = new HashMap<String, Object>();
					map.put(Constant.MESSAGE, out);
				}
				
				int status = brw.getStatus();
				response.setStatus(HttpStatus.OK.value());
				if (status >= 200 && status < 300 || status == 304) {
					if (status == 304) {
						response.setStatus(HttpStatus.NOT_MODIFIED.value());
					}
					map.put(Constant.STATUS, Constant.SUCCESS);
				} else {
					map.put(Constant.STATUS, Constant.FAILURE);
				}
				out = JSONObject.fromObject(map).toString();
			}
			
//			System.out.println(out);
			if (request.getParameter(JSONP_CALLBACK) != null) {
				out = request.getParameter(JSONP_CALLBACK) + "(" + out + ");";
				response.setCharacterEncoding("utf8");
				response.setContentType("application/json;charset=" + Constant.ENCODING);
				response.setContentLength(out.getBytes().length);
				response.getOutputStream().write(out.getBytes());
				response.getOutputStream().flush();
			}else if(request.getParameter(JSONP_UPLOAD_CALLBACK) != null){
				out = URLEncoder.encode(out, Constant.ENCODING); 
				response.setCharacterEncoding(Constant.ENCODING);
				response.setContentType("text/html;charset=" + Constant.ENCODING);
				response.setHeader("Cache-Control", "no-cache");
				response.addHeader("Access-Control-Allow-Origin", "*");
				response.addHeader("Access-Control-Allow-Headers", "x-requested-with");
				response.addHeader("Location", Constant.FRONT_DOMAIN_NAME + "/deal_callback.html?" + request.getParameter(JSONP_UPLOAD_CALLBACK) + "(" + out + ")");
				response.sendRedirect(Constant.FRONT_DOMAIN_NAME + "/deal_callback.html?" + request.getParameter(JSONP_UPLOAD_CALLBACK) + "(" + out + ")");
			}else {
				response.getOutputStream().write(out.getBytes());
				response.getOutputStream().flush();
			}
		}else {
			chain.doFilter(request, respon);
		}
		
		TempleConfigContext.removeContext();
	}

	public void destroy() {
		
	}

	public void init(FilterConfig filterConfig) {

	}

	static class ByteResponseWrapper extends HttpServletResponseWrapper {
		private PrintWriter writer;
		private ByteOutputStream output;
		private int code = 200;

		public byte[] getBytes() {
			writer.flush();
			return output.getBytes();
		}

		public ByteResponseWrapper(HttpServletResponse response) {
			super(response);
			output = new ByteOutputStream();
			writer = new PrintWriter(output);
		}

		@Override
		public PrintWriter getWriter() {
			return writer;
		}

		@Override
		public ServletOutputStream getOutputStream() throws IOException {
			return output;
		}

		public int getStatus() {
			return code;
		}

		public void sendRedirect(String location) throws IOException {
			code = HttpStatus.MOVED_TEMPORARILY.value();
			super.sendRedirect(location);
		}

		@Override
		public void setStatus(int sc) {
			this.code = sc;
		}

		@Override
		public void setStatus(int sc, String message) {
			this.code = sc;
		}

		@Override
		public void sendError(int sc) throws IOException {
			this.code = sc;
		}

		@Override
		public void sendError(int sc, String msg) throws IOException {
			this.code = sc;
		}
	}

	static class ByteOutputStream extends ServletOutputStream {
		private ByteArrayOutputStream bos = new ByteArrayOutputStream();

		@Override
		public void write(int b) throws IOException {
			bos.write(b);
		}

		public byte[] getBytes() {
			return bos.toByteArray();
		}
	}

	private static class JsonTool {
		@SuppressWarnings({ "unchecked", "rawtypes" })
		public static Map getMap4Json(String jsonString) {
			JSONObject jsonObject = JSONObject.fromObject(jsonString);
			Iterator keyIter = jsonObject.keys();
			String key;
			Object value;
			Map valueMap = new HashMap();

			while (keyIter.hasNext()) {
				key = (String) keyIter.next();
				value = jsonObject.get(key);
				valueMap.put(key, value);
			}

			return valueMap;
		}
	}
}

如果请求是跨域的则请求会带一个callback的参数 进入过滤器并设置请求类型是AJAX_REQUEST_TYPE

当准备响应给浏览器时 再次进入过滤器将返回的字符串转化为JSON对象 这里controller的返回类型必须是对象类型 比如Map<String, Object>或者bean 不能是JSONArray对象或者直接是List对象 因为JsonTool.getMap4Json转化json的时候JSONObject.fromObject()这句的限制只能转化Object


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:186870次
    • 积分:2393
    • 等级:
    • 排名:第15658名
    • 原创:45篇
    • 转载:95篇
    • 译文:0篇
    • 评论:16条
    最新评论