Package com.quickwebframework.bridge

Source Code of com.quickwebframework.bridge.ServletFilterBridge$ArrayFilterChain

package com.quickwebframework.bridge;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
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.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.quickwebframework.framework.WebContext;
import com.quickwebframework.servlet.support.DefaultRootServlet;
import com.quickwebframework.stereotype.FilterSetting;
import com.quickwebframework.util.WebResourceUtils;

public class ServletFilterBridge implements javax.servlet.Filter {

  private static Log log = LogFactory.getLog(ServletFilterBridge.class
      .getName());

  public class ArrayFilterChain implements FilterChain {
    private Filter[] filters;
    private int filterIndex = -1;
    private int filterCount = 0;

    public Filter lastFilter;

    public boolean isContinueFilterChain() {
      return filterIndex >= filterCount;
    }

    public ArrayFilterChain(Filter[] filters) {
      if (filters == null)
        return;
      this.filters = filters;
      filterCount = filters.length;
    }

    public void doFilter(ServletRequest arg0, ServletResponse arg1)
        throws IOException, ServletException {
      if (filters == null)
        return;

      filterIndex++;

      // 如果过滤器已使用完
      if (filterIndex >= filterCount)
        return;

      lastFilter = filters[filterIndex];
      lastFilter.doFilter(arg0, arg1, this);
    }
  }

  // 执行过滤

  public void doFilter(ServletRequest arg0, ServletResponse arg1,
      FilterChain filterChain) throws IOException, ServletException {
    // 判断是不是Http的Servlet请求
    if (!arg0.getScheme().equals("http")) {
      log.warn("ServletRequest的Scheme不是http!");
      return;
    }

    // 先执行过滤器
    ArrayFilterChain arrayFilterChain = new ArrayFilterChain(
        WebContext.getFilters());
    arrayFilterChain.doFilter(arg0, arg1);

    // 然后判断是否执行Servlet
    HttpServletRequest request = (HttpServletRequest) arg0;
    HttpServletResponse response = (HttpServletResponse) arg1;

    // 是否应该发送给Servlet
    boolean shouldPostToServlet = false;

    if (arrayFilterChain.isContinueFilterChain())
      shouldPostToServlet = true;
    else {
      Filter lastFilter = arrayFilterChain.lastFilter;
      Class<?> lastFilterClass = lastFilter.getClass();
      FilterSetting lastFilterSetting = lastFilterClass
          .getAnnotation(FilterSetting.class);
      if (lastFilterSetting != null
          && lastFilterSetting.returnToController()) {
        shouldPostToServlet = true;
      } else {
        shouldPostToServlet = false;
        log.info("过滤器链未全部执行完成,在执行完过滤器[" + arrayFilterChain.lastFilter
            + "]后断开。");
      }
    }
    if (!shouldPostToServlet) {
      return;
    }

    // 根据URL分发到相应的Servlet
    String requestUri = request.getRequestURI();
    String contextPath = request.getContextPath();
    String requestUriWithoutContextPath = requestUri.substring(contextPath
        .length());
    if (StringUtils.isEmpty(requestUriWithoutContextPath)) {
      requestUriWithoutContextPath = "/";
    }
    while (requestUriWithoutContextPath.contains("//")) {
      requestUriWithoutContextPath = requestUriWithoutContextPath
          .replace("//", "/");
    }

    // 保护WEB-INF中的文件
    if (requestUriWithoutContextPath.startsWith("/WEB-INF/")) {
      response.sendError(400, "/WEB-INF目录拒绝访问!");
      return;
    }

    // 如果此路径有映射的Servlet,则交由此Servlet去处理
    Servlet pathServlet = WebContext
        .getServletByPath(requestUriWithoutContextPath);
    if (pathServlet != null) {
      pathServlet.service(request, response);
      return;
    }
    // 如果是根路径
    if ("/".equals(requestUriWithoutContextPath)) {
      DefaultRootServlet.getInstance().service(arg0, arg1);
      return;
    }

    String[] splitResult = StringUtils.split(requestUriWithoutContextPath,
        "/");
    if (splitResult.length == 0) {
      response.sendError(404, "URL not found:"
          + requestUriWithoutContextPath);
      return;
    }
    // 如果URL包含后缀名
    if (splitResult[splitResult.length - 1].contains(".")) {
      String fullFilePath = WebContext
          .getRealPath(requestUriWithoutContextPath);
      File tmpFile = new File(fullFilePath);
      // 如果文件存在,则输出资源
      if (tmpFile.exists()) {
        WebResourceUtils.outputResource(response,
            requestUriWithoutContextPath, new FileInputStream(
                tmpFile));
        return;
      }
    }
    // 如果是映射到本地的文件资源

    // 如果根据/切分出来的字符串段数小于3,则不合法,返回404错误
    // 正确的插件的URL构成为: [插件名]/[视图类型名]/[路径]
    if (splitResult.length < 3) {
      response.sendError(404, "URL " + requestUriWithoutContextPath
          + " not found!");
      return;
    }
    String pluginName = splitResult[0];
    String viewTypeName = splitResult[1];
    String pathName = StringUtils.join(splitResult, "/", 2,
        splitResult.length);

    // 设置插件名称与路径到request的属性中
    request.setAttribute(WebContext.CONST_PLUGIN_NAME, pluginName);
    request.setAttribute(WebContext.CONST_PATH_NAME, pathName);

    // 根据typeName,找对应的类型的处理器
    Servlet typeServlet = WebContext.getViewTypeServlet(viewTypeName);
    if (typeServlet != null) {
      typeServlet.service(arg0, arg1);
      return;
    }
    response.sendError(404,
        String.format("未找到映射到视图类型为[%s]的Servlet!", viewTypeName));
  }

  // 过滤器初始化

  public void init(FilterConfig arg0) throws ServletException {
    WebContext.setFilterConfig(arg0);
  }

  public void destroy() {
    // 移除所有的过滤器
    WebContext.unregisterAllFilter();
  }
}
TOP

Related Classes of com.quickwebframework.bridge.ServletFilterBridge$ArrayFilterChain

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.