精华内容
下载资源
问答
  • 众所周知,在Servlet2.3规范之前Filter会拦截包括内部转发和外部转发,也就是会拦截Forward方式的转发请求。在2.4规范之后,Filter只会拦截外部请求,诸如以下...如果需要拦截Foward方式的转发则需要配置web.xmlfi...

    众所周知,在Servlet2.3规范之前Filter会拦截包括内部转发和外部转发,也就是会拦截Forward方式的转发请求。

    在2.4规范之后,Filter只会拦截外部请求,诸如以下方式转发的请求,Filter不会拦截

    request.getRequestDispatcher(newUri).forward(req, response);

    如果需要拦截Foward方式的转发则需要配置web.xml内filter的配置,需要指明拦截dispatcher为FORWARD的方式。

      <filter-mapping>
        <filter-name>ActionFilter</filter-name>
        <url-pattern>*.do</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
      </filter-mapping>

    一般情况下,开发者都能控制这个流程,但是倘若做一些url的重写,下面举一个例子:

    现有一个struts项目配置的filter拦截请求的地址为*.action没有配置dispacher为FORWARD方式的请求,在struts的filter前有一个filter做url重写,需求是将请求地址栏的比如http://localhost/a.html转发到http://localhost/a.action做伪静态化。

    那么当url rewrite filter将请求改写为a.aciton时,由于请求进入tomcat时为a.html,struts拦截的是*.action请求,filterchain并没有将struts filter加入到其中,如果只是重写getRequestUri,getRequestUrl,请求还是无法到达struts。

    另一种方式就是做FORWARD转发,结果也是可想而知,struts filter将不会拦截FORWARD方式的转发。

    有的同学会说,那我把struts filter的dispacher加上FORWARD方式不就好了?

    但是得考虑到,这可能是一个庞大的项目,不一定可以这样随意修改。

    下面说下思路:

    在跟踪了tomcat dispacher那一块的源码后发现,在请求进入tomcat后,tomcat 在request请求实现上会创建filterchain,然后根据路径是否匹配filter

           public ApplicationFilterChain createFilterChain(ServletRequest request, Wrapper wrapper, Servlet servlet) {
            // get the dispatcher type
            DispatcherType dispatcher = null; 
            if (request.getAttribute(DISPATCHER_TYPE_ATTR) != null) {
                dispatcher = (DispatcherType) request.getAttribute(DISPATCHER_TYPE_ATTR);
            }
            String requestPath = null;
            Object attribute = request.getAttribute(DISPATCHER_REQUEST_PATH_ATTR);
            
            if (attribute != null){
                requestPath = attribute.toString();
            }
            
            // If there is no servlet to execute, return null
            if (servlet == null)
                return (null);
    
    
            boolean comet = false;
            
            // Create and initialize a filter chain object
            ApplicationFilterChain filterChain = null;
            if (request instanceof Request) {
                Request req = (Request) request;
                comet = req.isComet();
                if (Globals.IS_SECURITY_ENABLED) {
                    // Security: Do not recycle
                    filterChain = new ApplicationFilterChain();
                    if (comet) {
                        req.setFilterChain(filterChain);
                    }
                } else {
                    filterChain = (ApplicationFilterChain) req.getFilterChain();
                    if (filterChain == null) {
                        filterChain = new ApplicationFilterChain();
                        req.setFilterChain(filterChain);
                    }
                }
            } else {
                // Request dispatcher in use
                filterChain = new ApplicationFilterChain();
            }
    
    
            filterChain.setServlet(servlet);
    
    
            filterChain.setSupport
                (((StandardWrapper)wrapper).getInstanceSupport());
    
    
            // Acquire the filter mappings for this Context
            StandardContext context = (StandardContext) wrapper.getParent();
            FilterMap filterMaps[] = context.findFilterMaps();
    
    
            // If there are no filter mappings, we are done
            if ((filterMaps == null) || (filterMaps.length == 0))
                return (filterChain);
    
    
            // Acquire the information we will need to match filter mappings
            String servletName = wrapper.getName();
    
    
            // Add the relevant path-mapped filters to this filter chain
            for (int i = 0; i < filterMaps.length; i++) {
                if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
                    continue;
                }
                if (!matchFiltersURL(filterMaps[i], requestPath))
                    continue;
                ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
                    context.findFilterConfig(filterMaps[i].getFilterName());
                if (filterConfig == null) {
                    // FIXME - log configuration problem
                    continue;
                }
                boolean isCometFilter = false;
                if (comet) {
                    try {
                        isCometFilter = filterConfig.getFilter() instanceof CometFilter;
                    } catch (Exception e) {
                        // Note: The try catch is there because getFilter has a lot of 
                        // declared exceptions. However, the filter is allocated much
                        // earlier
                    }
                    if (isCometFilter) {
                        filterChain.addFilter(filterConfig);
                    }
                } else {
                    filterChain.addFilter(filterConfig);
                }
            }
    
    
            // Add filters that match on servlet name second
            for (int i = 0; i < filterMaps.length; i++) {
                if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
                    continue;
                }
                if (!matchFiltersServlet(filterMaps[i], servletName))
                    continue;
                ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
                    context.findFilterConfig(filterMaps[i].getFilterName());
                if (filterConfig == null) {
                    // FIXME - log configuration problem
                    continue;
                }
                boolean isCometFilter = false;
                if (comet) {
                    try {
                        isCometFilter = filterConfig.getFilter() instanceof CometFilter;
                    } catch (Exception e) {
                        // Note: The try catch is there because getFilter has a lot of 
                        // declared exceptions. However, the filter is allocated much
                        // earlier
                    }
                    if (isCometFilter) {
                        filterChain.addFilter(filterConfig);
                    }
                } else {
                    filterChain.addFilter(filterConfig);
                }
            }
    
    
            // Return the completed filter chain
            return (filterChain);
    
    
        }

    仔细观察如下代码

            //注意这个地方
            //在遍历所有的filter判断当前请求是否需要添加filter
            //matchDispatcher则是实现判断的地方
            // Add filters that match on servlet name second
            for (int i = 0; i < filterMaps.length; i++) {
                if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
                    continue;
                }
                if (!matchFiltersServlet(filterMaps[i], servletName))
                    continue;
                ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
                    context.findFilterConfig(filterMaps[i].getFilterName());
                if (filterConfig == null) {
                    // FIXME - log configuration problem
                    continue;
                }
                boolean isCometFilter = false;
                if (comet) {
                    try {
                        isCometFilter = filterConfig.getFilter() instanceof CometFilter;
                    } catch (Exception e) {
                        // Note: The try catch is there because getFilter has a lot of 
                        // declared exceptions. However, the filter is allocated much
                        // earlier
                    }
                    if (isCometFilter) {
                        filterChain.addFilter(filterConfig);
                    }
                } else {
                    filterChain.addFilter(filterConfig);
                }
            }

    接下来看下matchDispatcher方法的实现

        //很明显这里判断了下filter的dispacher type和参数type是否匹配
        //也就是刚说的在filter的filter-mapping里指明的Dispacher type
        //如果是在filter-mapping里有指明当前转发方式则返回true否则返回false
        private boolean matchDispatcher(FilterMap filterMap, DispatcherType type) {
            switch (type) {
                case FORWARD : {
                    if ((filterMap.getDispatcherMapping() & FilterMap.FORWARD) > 0) {
                            return true;
                    }
                    break;
                }
                case INCLUDE : {
                    if ((filterMap.getDispatcherMapping() & FilterMap.INCLUDE) > 0) {
                        return true;
                    }
                    break;
                }
                case REQUEST : {
                    if ((filterMap.getDispatcherMapping() & FilterMap.REQUEST) > 0) {
                        return true;
                    }
                    break;
                }
                case ERROR : {
                    if ((filterMap.getDispatcherMapping() & FilterMap.ERROR) > 0) {
                        return true;
                    }
                    break;
                }
                case ASYNC : {
                    if ((filterMap.getDispatcherMapping() & FilterMap.ASYNC) > 0) {
                        return true;
                    }
                    break;
                }
            }
            return false;
        }

    这样子看来就很明显了,只要把type参数改为REQUEST就可以实现让转发的FORWARD请求伪装成REQUEST请求了,也就是这样请求就可以和一个新的请求一样再走一遍正常流程了。

    那么这个dispatcher参数是从哪里获取的呢?

    回到第一段代码的开始,可以看到

            // get the dispatcher type
            DispatcherType dispatcher = null; 
            if (request.getAttribute(DISPATCHER_TYPE_ATTR) != null) {
                dispatcher = (DispatcherType) request.getAttribute(DISPATCHER_TYPE_ATTR);
            }
     /**
         * Request dispatcher state.
         */
        public static final String DISPATCHER_TYPE_ATTR = "org.apache.catalina.core.DISPATCHER_TYPE";

    这样子就明朗了

    请求在被进行分发的时候,分发器会读取请求的类型,也就是DispacherType,具体就是读取请求的"org.apache.catalina.core.DISPATCHER_TYPE"的属性,然后再装载filterchain的时候根据这个请求类型来装载filter,没有指明拦截FORWARD的filter不会装载在FORWAD的请求上,基于此种方式,我们只要将request的"org.apache.catalina.core.DISPATCHER_TYPE"属性改为DispacherType.REQUEST就可以达到让FORWARD请求变成REQUEST请求了,从而让我们的内部转发可以达到外部转发的效果。

    接下来放两个实现类

    public class FitrstFilter implements Filter {
        private String servletPath;
        public FitrstFilter() {
        }
        public void destroy() {
        }
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
                throws IOException, ServletException {
            DispatcherWrapper req = new DispatcherWrapper((HttpServletRequest) request);
            System.out.println("第一个filter");
            // 表明是请求第一次进入filter
            if (req.getAttribute("com.zhibei.filter.FORWARD") == null) {
                // 设置参数
                req.setAttribute("com.zhibei.filter.FORWARD", Boolean.TRUE);
                // 请求分发
                String newUri = req.getRequestURI().replace(this.servletPath, "").replace("index", "index2");
                request.getRequestDispatcher(newUri).forward(req, response);
            } else {
                // 设置为false防止请求进入死循环
                req.setAttribute("com.zhibei.filter.FORWARD", Boolean.FALSE);
                chain.doFilter(request, response);
            }
        }
        public void init(FilterConfig fConfig) throws ServletException {
            this.servletPath = fConfig.getServletContext().getContextPath();
        }
        private class DispatcherWrapper extends HttpServletRequestWrapper {
            public DispatcherWrapper(HttpServletRequest request) {
                super(request);
            }
            @Override
            public Object getAttribute(String name) {
                // TOMCAT内部的请求分发属性
                if (name.equals("org.apache.catalina.core.DISPATCHER_TYPE")) {
                    Object forward = this.getAttribute("com.zhibei.filter.FORWARD");
                    if (forward == Boolean.TRUE) {
                        //这里返回变量有两种,在Tomcat6中并没有DispacherType这个类,与REQUEST相对应的是一个int类型的数值8
                        //这个属性在Tomcat7后才被抽象为一个类
                        //所以这里要判断下如果有这个类则返回DisPacherType.REQUEST否则返回8即可
                        try {
                            Class.forName("javax.servlet.DispatcherType");
                            return javax.servlet.DispatcherType.REQUEST;
                        } catch (Exception e) {
                            return 8;
                        }
                    }
                }
                return super.getAttribute(name);
            }
        }
    }

    DispacherWrapper重写getAttribute,当获取request的"org.apache.catalina.core.DISPATCHER_TYPE"属性时,返回DispacherType.REQUEST即可,为了防止请求被无限转发进入死循环,加一个标志来判断即可,实现非常轻松。

    public class SecondFilter implements Filter {
        public SecondFilter() {
        }
        public void destroy() {
        }
        //在第二个filter中打印相关信息
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
                           throws IOException, ServletException {
            System.out.println("第二个filter");
            HttpServletRequest req = (HttpServletRequest) request;
            System.out.println("URI:" + req.getRequestURI());
            System.out.println("URL" + req.getRequestURL());
            System.out.println("QueryString:" + req.getQueryString());
            Map<String, String[]> paramMap = req.getParameterMap();
            for (String key : paramMap.keySet()) {
                for (String value : paramMap.get(key)) {
                    System.out.println("key:" + key + ",value:" + value);
                }
            }
            chain.doFilter(request, response);
        }
        public void init(FilterConfig fConfig) throws ServletException {
        }
    }
    

    请求地址:

    http://localhost:8080/filter/index.html?sdsd45=dw48d

    打印结果:

    第一个filter
    第一个filter
    第二个filter
    URI:/filter/index2.html
    URLhttp://localhost:8080/filter/index2.html
    QueryString:sdsd45=dw48d
    key:sdsd45,value:dw48d

    和预想的一样,FirstFilter进入了两次,第一次为原始请求,第二次为FORWARD的请求

    工程下载:https://download.csdn.net/download/yy417168602/10445381
    展开全文
  • 博文https://blog.csdn.net/yy417168602/article/details/80497664的工程附件
  • http://www.family168.com/tutorial/jsp/html/jsp-ch-07.html...在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和的情况。到了servlet-2.4中Filter默认下只拦截外部提交的请求,forward和i

    http://www.family168.com/tutorial/jsp/html/jsp-ch-07.html 

     

    我们已经了解了filter的基本用法,还有一些细节配置在特殊情况下起作用。

    在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和<%@ include file="/index.jsp"%>的情况。

    到了servlet-2.4中Filter默认下只拦截外部提交的请求,forward和include这些内部转发都不会被过滤,但是有时候我们需要forward的时候也用到Filter,这样就需要如下配置。

    <filter>
        <filter-name>TestFilter</filtername>
        <filter-class>anni.TestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>TestFilter</filtername>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>EXCEPTION</dispatcher>
    </filter-mapping>
    在tomcat5.5的web.xml最高应该是支持servlet2.4的...
    ----------------------------------
    以Spring支持的OpenSessionInViewFilter为例,comment in blue.
     protected void doFilterInternal(
       HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
       throws ServletException, IOException {
      SessionFactory sessionFactory = lookupSessionFactory(request);
      boolean participate = false;
      if (isSingleSession()) {
       // single session mode
       if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
        // Do not modify the Session: just set the participate flag.
        participate = true;
       }
       else {
        logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter");
        Session session = getSession(sessionFactory);
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
       }
      }
      else {
       // deferred close mode
       if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) {
        // Do not modify deferred close: just set the participate flag.
        participate = true;
       }
       else {
        SessionFactoryUtils.initDeferredClose(sessionFactory);
       }
      }
      try {
       filterChain.doFilter(request, response);
    //如果还有其他filter则执行其他filter, 没有的话就执行jspServlet去了。 也就是说最后finally的在渲染view之后的。
      }
      finally {
       if (!participate) {
        if (isSingleSession()) {
         // single session mode
         SessionHolder sessionHolder =
           (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
         logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter");
         closeSession(sessionHolder.getSession(), sessionFactory);
        }
        else {
         // deferred close mode
         SessionFactoryUtils.processDeferredClose(sessionFactory);
        }
       }
      }
     }//Long term of session...
    展开全文
  • Filter路径转发的问题

    2013-05-14 22:44:28
    import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet....
  • 使用Filter拦截器实现请求跨域转发

    千次阅读 2019-06-12 15:50:28
    因为公司项目需求,项目中前端请求需要通过一个类似中转的服务转发(请求在该服务中会重新包装一些通用参数),在使用Filter实现转发后特做一次记录 package com.unicloud.cce.Filter; import ...

    因为公司项目需求,项目中前端请求需要通过一个类似中转的服务转发(请求在该服务中会重新包装一些通用参数),在使用Filter实现转发后特做一次记录

    package com.unicloud.cce.Filter;
    
    import com.alibaba.fastjson.JSON;
    import com.unicloud.cce.common.RestfulEntity;
    import com.unicloud.cce.service.CloudosService;
    import org.apache.commons.io.IOUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.*;
    import org.springframework.stereotype.Component;
    import org.springframework.util.AntPathMatcher;
    import org.springframework.util.StringUtils;
    import org.springframework.web.client.RestTemplate;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.*;
    
    /**
     * @author skyxt
     * Created 2019-06-11 18:46
     * Email skyxt.yang@gmail.com
     */
    @WebFilter(filterName = "authFilter", urlPatterns = { "/*" })
    @Component
    public class RequestFilter implements Filter {
    
    
        //该处配置需要转发的路径
        public static final Set<String> FILTER_URL = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
                "/config/*"
        )));
    
        @Autowired
        private RestTemplate restTemplate;
        @Autowired
        private CloudosService cloudosService;
    
    
        private final static Logger logger = LoggerFactory.getLogger(RequestFilter.class);
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
                return;
            }
            HttpServletRequest req = (HttpServletRequest) request;
            HttpServletResponse rsp = (HttpServletResponse) response;
            AntPathMatcher matcher = new AntPathMatcher();
            Optional<String> cloudIp = Optional.empty();
    //        for (String url : FILTER_URL) {
    //            if (matcher.match(url, req.getRequestURI().substring(req.getContextPath().length()))) {
    //                cloudIp = cloudosService.cloudosList("", "").stream().filter(cloudos ->
    //                        cloudos.getId().equals(((HttpServletRequest) request).getHeader("cloudId"))
    //                ).map(Cloudos::getCloudIp).findFirst();
    //            }
    //        }
            cloudIp = Optional.of("localhost");
            if (cloudIp.isPresent()) {
                switch (req.getMethod()) {
                    case "GET": {
                        request(req, rsp, HttpMethod.GET, cloudIp.get());
                        break;
                    }
                    case "POST": {
                        request(req, rsp, HttpMethod.POST, cloudIp.get());
                        break;
                    }
                    case "PUT": {
                        request(req, rsp, HttpMethod.PUT, cloudIp.get());
                        break;
                    }
                    case "PATCH": {
                        request(req, rsp, HttpMethod.PATCH, cloudIp.get());
                        break;
                    }
                    case "DELETE": {
                        request(req, rsp, HttpMethod.DELETE, cloudIp.get());
                        break;
                    }
                    default:{
                        logger.error("unknow request method:" + req.getMethod());
                        rsp.setCharacterEncoding("UTF-8");
                        try (PrintWriter out = rsp.getWriter()) {
                            out.write("请求方法未知");
                        } catch (Exception e1) {
                            logger.error(e1.getMessage() + e1);
                        }
                    }
    
                }
            } else {
                chain.doFilter(request, response);
            }
        }
    
        @Override
        public void destroy() {
    
        }
    
        private void request(HttpServletRequest req, HttpServletResponse rsp, HttpMethod method, String cloudIp) throws IOException {
            rsp.setCharacterEncoding("UTF-8");
            String requestBody = IOUtils.toString(req.getInputStream(), "UTF-8");
            Object body = null;
            if (StringUtils.hasText(requestBody)) {
                body = JSON.parse(requestBody);
            }
            HttpHeaders headers = new HttpHeaders();
            Enumeration<String> headerNames = req.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                headers.add(name, req.getHeader(name));
            }
            String url;
            if (StringUtils.hasText(req.getQueryString())) {
                url = String.format(
                        "http://%s:15120%s?%s",
                        cloudIp,
                        req.getRequestURI().substring(req.getContextPath().length()),
                        req.getQueryString()
                        );
            } else {
                url = String.format(
                        "http://%s:15120%s",
                        cloudIp,
                        req.getRequestURI().substring(req.getContextPath().length())
                );
            }
            HttpEntity<Object> httpEntity = new HttpEntity<>(body, headers);
            ResponseEntity<RestfulEntity> exchange = null;
            try {
                exchange = restTemplate.exchange(
                        url,
                        method,
                        httpEntity,
                        RestfulEntity.class
                );
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                try (PrintWriter out = rsp.getWriter()) {
                    out.write("请求异常");
                } catch (Exception e1) {
                    logger.error(e1.getMessage() + e1);
                }
            }
            if (exchange != null) {
                exchange.getStatusCode();
                rsp.setStatus(exchange.getStatusCodeValue());
                exchange.getHeaders().entrySet().stream().forEach(entry -> {
                    String value = entry.getValue().toString();
                    rsp.addHeader(entry.getKey(), value.substring(1, value.length()-1));
                });
                try (PrintWriter out = rsp.getWriter()) {
                    out.write(JSON.toJSONString(exchange.getBody()));
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            } else {
                logger.info("error: URL:" + "http://" + cloudIp + ":15120" + req.getRequestURI().substring(req.getContextPath().length()));
                try (PrintWriter out = rsp.getWriter()) {
                    out.write("请求异常");
                } catch (Exception e1) {
                    logger.error(e1.getMessage() + e1);
                }
            }
    
        }
    }
    

     

    展开全文
  • 配置文件 &lt;welcome-file-list&gt; &lt;welcome-file&gt;view/home/index.jsp&lt;/welcome-file&...--路径转发的控制器--&gt; &lt;servlet&gt; &lt;servlet-...

    配置文件

    <welcome-file-list>
            <welcome-file>view/home/index.jsp</welcome-file>
        </welcome-file-list>
        <!--路径转发的控制器-->
        <servlet>
            <servlet-name>DispatchersServlet</servlet-name>
            <servlet-class>service.DispatchersServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>DispatchersServlet</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    
        <!--登录检测的过滤器-->
        <filter>
            <filter-name>LoginFilter</filter-name>
            <filter-class>service.LoginFilter</filter-class>
            <!--初始化的参数-->
            <init-param>
                <!--页面编码UTF-8-->
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
            <init-param>
                <!--过滤跳转的页面-->
                <param-name>loginPage</param-name>
                <param-value>/view/login/index.jsp</param-value>
            </init-param>
        </filter>
        <!--过滤的页面-->
        <filter-mapping>
            <filter-name>LoginFilter</filter-name>
            <url-pattern>/view/*</url-pattern>
        </filter-mapping>

    控制路由转发的servlet

    package service;
    
    import controller.LoginController;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebServlet(name = "DispatchersServlet")
    public class DispatchersServlet extends HttpServlet {
        @Override
        public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
            request.setCharacterEncoding("utf-8");
            // 获取访问的路径
            String url = request.getRequestURI();
    //      System.out.println("url:"+ url);
            // 拆分路径
            String path = url.substring(url.indexOf("/") + 1, url.lastIndexOf("."));
            System.out.println("path:" + path);
            // 例子: Login/index   =>  ['Login', 'index']
            String ary[] = path.split("/");
    //      System.out.println("ary:" + java.util.Arrays.toString(ary));
            // 如果拆分的路径不是两个字符串, 则跳转到404页面
            if(ary.length != 2){
                request.getRequestDispatcher("/view/error/404.jsp").forward(request, response);
            }else{
                if("Login".equals(ary[0])){
                    // 第一个字符串是 Login, 就new一个LoginController的servlet的控制类
                    LoginController login = new LoginController();
                    if("index".equals(ary[1])){
                        // 加载登录页面
                        login.index(request, response);
                    }else if("submit".equals(ary[1])){
                        // 登录
                        login.submit(request, response);
                    }else if("logout".equals(ary[1])){
                        // 退出登录
                        login.logout(response, request);
                    }
                }
            }
        }
    }
    

    filter过滤器

    package service;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    @WebFilter(filterName = "LoginFilter")
    public class LoginFilter implements Filter {
        // 获取配置文件的信息
        private String encoding = null;
        private String loginPage = null;
        private String respEncoding = null;
        // 销毁过滤器
        public void destroy() {
            System.out.println("销毁过滤器!");
        }
        // 具体的过滤的方法
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            // 设置返回数据的编码方法为utf-8
            resp.setContentType(respEncoding);
            // 设置接收数据的编码方式为utf-8
            req.setCharacterEncoding(encoding);
            // 将req resp 转为子接口的类型
            HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse)resp;
            // 获取路径
            String urlPath = request.getServletPath();
            System.out.println(urlPath);
            // 获取session
            HttpSession session = request.getSession(true);
            // 如果所在页面不是登录页面并且没有session数据则跳转到登录页面,否则放行
            if(session.getAttribute("user") == null && !("/view/login/index.jsp".equals(urlPath))){
                response.sendRedirect(loginPage);
                return;
            }else{
                chain.doFilter(request, response);
                return;
            }
        }
        // 初始化方法
        public void init(FilterConfig config) throws ServletException {
            this.encoding = config.getInitParameter("encoding");
            this.loginPage = config.getInitParameter("loginPage");
            this.respEncoding = config.getInitParameter("respEncoding");
            System.out.println("初始化过滤器!");
        }
    
    }
    

    处理登录的servlet控制器

    package controller;
    
    import dbDao.checkUser;
    import javaBean.Users;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class LoginController {
    
        /*
            加载登录首页
         */
        public void index(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
            response.sendRedirect("/view/login/index.jsp");
        }
    
        /*
            登录表单提交
         */
        public void submit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
            String userName = request.getParameter("username");
            String passWord = request.getParameter("password");
            Users user = new Users(userName, passWord);
            checkUser cu = new checkUser();
            boolean ok = cu.OkUser(user);
            if(ok){
                request.getSession().setAttribute("user", user);
                response.sendRedirect("/view/home/index.jsp");
            }else{
                response.sendRedirect("/view/login/register.jsp");
            }
        }
    
        /*
            退出登录
         */
        public void logout(HttpServletResponse response, HttpServletRequest request) throws ServletException, IOException{
            request.getSession().invalidate();
            response.sendRedirect("/view/home/index.jsp");
        }
    }
    

    登录页面

    <%--
      Created by IntelliJ IDEA.
      User: admin
      Date: 2018/3/15
      Time: 20:20
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>登录</title>
        <link rel="stylesheet" href="/css/bootstrap.css">
    </head>
    <body>
        <div class="container-fluid" style="margin: 12% auto;">
            <h1 class="text-center" style="margin-bottom: 20px;">登录</h1>
            <div class="row" style="width: 80%; margin: auto;">
                <div class="col-md-6 col-md-offset-3">
                    <form class="form-horizontal " action="/Login/submit.do">
                        <div class="form-group" style="margin: 10px auto;">
                            <label for="inputEmail3" class="col-sm-2 control-label">用户名</label>
                            <div class="col-sm-10">
                                <input type="text" class="form-control" id="inputEmail3" placeholder="请输入用户名" name="username">
                            </div>
                        </div>
                        <div class="form-group" style="margin: 10px auto;">
                            <label for="inputPassword3" class="col-sm-2 control-label">密  码</label>
                            <div class="col-sm-10">
                                <input type="password" class="form-control" id="inputPassword3" placeholder="请输入密码" name="password">
                            </div>
                        </div>
                        <div class="form-group" style="margin: 10px auto;">
                            <div class="col-sm-offset-2 col-sm-10">
                                <div class="checkbox">
                                    <label>
                                        <input type="checkbox"> 记住我
                                    </label>
                                </div>
                            </div>
                        </div>
                        <div class="form-group" style="margin: 10px auto;">
                            <div class="col-sm-offset-2 col-sm-10">
                                <button type="submit" class="btn btn-default">登录</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    
    </body>
    <script src="/js/jquery.js"></script>
    <script src="/js/bootstrap.js"></script>
    </html>
    

    简易首页

    <%--
      Created by IntelliJ IDEA.
      User: admin
      Date: 2018/3/13
      Time: 13:19
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" import="java.util.*" language="java" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
        <head>
          <title>首页</title>
        </head>
        <body>
            <c:set value="${sessionScope.user.userName}" var="num" scope="session"/>
            <%--<c:out value="${num}" />--%>
            <c:choose>
                <c:when test="${num != null}">
                    <h1><span>用户名</span>${sessionScope.user.userName}</h1>
                    <br/>
                    <h2><a href="/Login/logout.do" style="text-decoration: none;">退出登录</a></h2>
                </c:when>
                <c:otherwise>
                    <h1><span>用户名</span>未登录</h1>
                </c:otherwise>
            </c:choose>
            <a href="/Login/index.do">登录1</a>
            <a href="/getList.do">登录2</a>
        </body>
    </html>
    
    展开全文
  • Javaweb基础----过滤器filter转发

    千次阅读 2017-08-30 11:25:32
    一、Filter简介  Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现...
  • 这个问题也可以转变为filter过滤器为何不能过滤转发请求 在servlet-2.3中,Filter会过滤一切请求,包括服务器内部使用forward转发请求和<%@ includefile="/index.jsp"%>的情况。 到了servlet-2.4中Filter...
  • 如果用树莓派当作路由器转发有线和无线网络,则...iptables共3个tables(filter nat mangle,现在貌似是4个表)5条chains(PREROUTING INPUT FORWARDING OUTPUT POSTROUTING)4个连接跟踪数据包状态(NEW INVALID EST
  • java过滤器Filter

    万次阅读 多人点赞 2019-07-31 19:08:31
    Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断如是否有权限访问页面等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它...
  • }else if(urlBuffer.toString().contains("platform/touzi")){ //使用sendRedirect请求转发 System.out.println("过滤器doFilter中调用,sendRedirect请求转发."); String redirectUrl = ...
  • Linux服务器内外网端口转发映射

    千次阅读 2018-11-11 05:27:09
    Linux服务器内外网端口转发映射
  • 拦截/web开头的请求,然后把url中的/web去掉进行转发 @WebFilter(urlPatterns = "/web/*") public class WebForwardFilter implements Filter { @Override public void init(FilterConfig filterConfig) { } ...
  • linux开启内部路由转发功能

    千次阅读 2016-12-01 14:41:39
    linux开启内部路由转发功能 2015-09-23 18:02:09 标签:linux开启内部路由转么功能 linux内部机器共享上网 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将...
  • 一、开启路由转发 转自http://blog.51cto.com/zouqingyun/1697571 一组内部机器需要连接外网,则需要找一台机器,即可以连接外网,内网机器也可以连接。 因此将这台外网机器当做路由器,做路由转发 1、在需要做...
  • Java Web之过滤器(Filter

    万次阅读 多人点赞 2018-07-31 16:58:40
    过滤器(Filter) 过滤器实际上就是对web资源进行拦截,做一些处理后再交给servlet。 通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理 大概流程图如下 应用场景 自动登录 统一设置...
  • 不会,比如请求转发,前前后后都是一个url 首先要弄清请求重定向与请求转发的区别; 举例来说有两个网页index.jsp 然后分别通过两种方式跳转到main.jsp请求转发 服务器端行为,可以理解为“内部处理”内容变,url...
  • 在chain.doFilter(request,response)后若有重定向或转发语句,执行顺序是: 1.所要访问的资源不是转发的目标资源: chain.doFilter(request,response)–>下一个过滤器(如果有)–>执行完整个 过滤器链–>执行...
  • spring cloud gateway之filter

    万次阅读 多人点赞 2018-12-17 21:45:21
    转载请标明出处: ...本文出自方志朋的博客 在上一篇文章详细的介绍了Gateway的Predict,Predict决定了请求由哪一个路由处理,在路由处理之前,需要经过“pre...由filter工作流程点,可以知道filter有着非常重要的作用...
  • linux实现nat转发和内部端口映射

    千次阅读 2018-01-25 17:35:12
    linux实现nat转发和内部端口映射 双网卡: 路由机 eth0:114.114.114.114(公网ip) eth1:192.168.1.1(内网ip) pc1 eth0:192.168.1.2(内网ip) eth1(拨号ip) pc2 eth0:192.168.1.3(内网ip) eth1(拨号ip)  ...
  • 认识Filter

    千次阅读 2016-07-25 22:06:05
    1.定义Filter的翻译就是过滤器,可以认为它是一种加强版的Servlet。几种常见Filter: 1. 用户授权Filter。用于检查用户请求,根据请求过滤用户非法请求。 2. 日志Filter。用于记录某些特殊的用户请求。 3. 解码...
  • 详谈 Filter 过滤器

    千次阅读 2016-11-26 00:31:00
    详谈 Filter 过滤器文章首发在CSDN博客,转载请务必注明以下所有链接,否则考虑法律追究责任。CSDN地址:个人博客地址:www.54tianzhisheng.cn/Blog/html/filter.html (阅读效果最好)更多精彩博客还请关注我的...
  • Filter-Policy

    万次阅读 多人点赞 2021-01-27 20:51:35
    影响路由的产生、发布、选择等,进而影响报文的转发路径。 目的 Filter-Policy路由策略Filter-Policy应用场景距离矢量(RIP)配置案例链路状态(OSPF)配置案例 Filter-Policy 路由过滤工具,只能过滤路由...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 70,998
精华内容 28,399
关键字:

filter内转发