GVKun编程网logo

HTTP状态500-筛选器执行引发异常-重复执行doFilter和invokeDelegate(筛选器错误)

33

对于HTTP状态500-筛选器执行引发异常-重复执行doFilter和invokeDelegate感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍筛选器错误,并为您提供关于2.gateway调用

对于HTTP状态500-筛选器执行引发异常-重复执行doFilter和invokeDelegate感兴趣的读者,本文将会是一篇不错的选择,我们将详细介绍筛选器错误,并为您提供关于2. gateway 调用链截断及filter重复执行、ASP.NET MVC 全局过滤器(FilterConfig)、标记在控制器上和方法上的筛选器执行顺序、ASP.NET MVC筛选器之特殊筛选器IOverrideFilter、asp.net – IIS7 HttpModule和ISAPI Filter执行顺序的有用信息。

本文目录一览:

HTTP状态500-筛选器执行引发异常-重复执行doFilter和invokeDelegate(筛选器错误)

HTTP状态500-筛选器执行引发异常-重复执行doFilter和invokeDelegate(筛选器错误)

我正在使用Spring-MVC(4.2.5)和Spring-
Security(4.1.3)开发Web应用程序。当我尝试将后者纳入我的mvc项目时,我开始遇到问题。

当前,经过几次尝试,我在本地服务器的本地主机上收到此错误:localhost:8080 / BetEx /

HTTP Status 500 - Filter execution threw an exceptiontype Exception reportmessage Filter execution threw an exceptiondescription The server encountered an internal error that prevented it from fulfilling this request.exceptionjavax.servlet.ServletException: Filter execution threw an exceptionroot causejava.lang.StackOverflowError    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:246)    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)[repeated many, many times]

web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns="http://java.sun.com/xml/ns/javaee"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"    id="WebApp_ID" version="3.0">    <display-name>BetEx</display-name>    <welcome-file-list>        <welcome-file>index.html</welcome-file>    </welcome-file-list>    <!-- Spring MVC -->    <servlet>        <servlet-name>betex-controller</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>betex-controller</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping>    <!-- Spring Security Configuration File -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>/WEB-INF/spring/spring-security.xml</param-value>    </context-param>        <context-param>        <param-name>contextClass</param-name>        <param-value>         org.springframework.web.context.support.AnnotationConfigWebApplicationContext      </param-value>    </context-param>    <!-- Spring Security -->    <filter>        <filter-name>springSecurityFilterChain</filter-name>        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>    </filter>    <filter-mapping>        <filter-name>springSecurityFilterChain</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping></web-app>

betex-controller-servlet.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"    xsi:schemaLocation="   http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd   http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-4.3.xsd   http://www.springframework.org/schema/mvc    http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">    <context:component-scan base-package="controller" />    <context:component-scan base-package="service" />    <mvc:annotation-driven />    <mvc:resources mapping="/resources/**" location="/resources/" />    <bean id="templateResolver">        <property name="prefix" value="/WEB-INF/html/" />        <property name="suffix" value=".html" />        <property name="templateMode" value="HTML5" />    </bean>    <bean id="templateEngine">        <property name="templateResolver" ref="templateResolver" />    </bean>    <bean>        <property name="templateEngine" ref="templateEngine" />        <property name="order" value="1" />    </bean>    <bean id="springSecurityFilterChain"/></beans>

spring-security.xml

<?xml version="1.0" encoding="UTF-8"?><beans:beans xmlns="http://www.springframework.org/schema/security"    xmlns:security="http://www.springframework.org/schema/security"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"    xsi:schemaLocation="      http://www.springframework.org/schema/security       http://www.springframework.org/schema/security/spring-security-4.1.xsd      http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">    <http pattern="/resources/**" security="none" />    <http use-expressions="true">        <intercept-url pattern="/index*" access="isAnonymous()" />        <intercept-url pattern="/**" access="isAuthenticated()" />        <form-login login-page=''/index.html'' default-target-url="/home.html"            authentication-failure-url="/index.html?error=true" />        <logout logout-success-url="/index.html" />    </http>    <authentication-manager>        <authentication-provider user-service-ref="customUserDetailsService">            <password-encoder hash="bcrypt" />        </authentication-provider>    </authentication-manager></beans:beans>

我认为此错误意味着该框架无法加载DelegatingFilterProxy bean并将其委托给应用程序上下文。

我哪里错了?提前致谢

编辑:

按照dur的建议,从betex-controller-servlet.xml中删除以下行之后

<bean id="springSecurityFilterChain"/>

尝试打开W​​eb应用程序的根目录时出现以下错误:

GRAVE: Servlet.service() for servlet [betex-controller] in context with path [/BetEx] threw exceptionorg.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named ''springSecurityFilterChain'' is defined    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:698)    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1175)    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060)    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326)    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:255)    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)    at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)    at java.lang.Thread.run(Thread.java:745)

答案1

小编典典

在仔细检查了所有配置文件之后,在阅读了文档之后,我得出的结论是没有错。我只是解决了从版本4.1.3降级到4.0.3的问题

2. gateway 调用链截断及filter重复执行

2. gateway 调用链截断及filter重复执行

1.背景

      开放平台项目,开发者接入开放平台后,调用开平接口,开平网关需要获取开发者的信息,进而做判断开发者权限、 记录流量信息等操作。

2.问题

      开平网关获取开发者信息后,经判断开发者没有权限,想做两个操作 1.返回开发者无权限信息;2.截断之后的filter及向业务服务的调用,如下图所示:

在这里插入图片描述

3.互联网解决方案

      百度之后,发现网上流行的解决方案类似这样:

public static Mono<Void> badReturn(ServerWebExchange exchange, Status statusCode) {
   if(statusCode == null) {
      statusCode = Status.ERROR_ParaMETERS;
   }
   //exchange中获取response
   ServerHttpResponse response = exchange.getResponse();
   //设置response code及header信息
   response.setStatusCode(HttpStatus.OK);
   HttpHeaders headers = response.getHeaders();
   headers= HttpHeaders.writableHttpHeaders(headers);
   headers.setContentType(MediaType.APPLICATION_JSON);
   //生成返回开发者的信息
   String fastResult = returnString(statusCode, "F");
   //将string信息写入dataBuffer中
   DataBuffer dataBuffer = response.bufferFactory().allocateBuffer().write(fastResult.getBytes(StandardCharsets.UTF_8));
   //response写回
   return response.writeWith(Mono.just(dataBuffer));
}

      或者是此种方法的变体,使用ServerHttpResponseDecorator进行封装,类似这样:

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
   List<String> authorization = exchange.getRequest().getHeaders().get("Authorization");
   if (CollectionUtils.isEmpty(authorization) &&
      !PatternMatchUtils.simpleMatch(URL_WITHOUT_AUTH, exchange.getRequest().getURI().toString())) {
      exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
      ServerHttpResponse originalResponse = exchange.getResponse();
      DataBufferFactory bufferFactory = originalResponse.bufferFactory();
      ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
         @Override
         public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
            if (body instanceof Flux) {
               Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
               return super.writeWith(fluxBody.map(dataBuffer -> {
                  // probably should reuse buffers 
                  byte[] content = new byte[dataBuffer.readableByteCount()];
                  dataBuffer.read(content);
                  byte[] uppedContent = new String(content, Charset.forName("UTF-8")).toupperCase().getBytes();
                  return bufferFactory.wrap(uppedContent);
               }));
            }
            return super.writeWith(body); // if body is not a flux. never got there.
         }
      };
      return chain.filter(exchange.mutate().response(decoratedResponse).build()); // replace response with decorator
   }
   String token = authorization.get(0).split(" ")[1];
   // token validation
   return chain.filter(exchange);
}

3.1互联网方案的局限

      我借用了第一种方式,并在项目中实测,确实可以正确的返回开发者信息。虽然可以使用,但在我的项目(gateway版本2.2.8.RELEASE)中产生了两个严重的副作用:1. filter重复执行;2. 第二次执行filter时报错。虽然在重复实行和报错时,因为response已经返回,所以并不会影响调用者,但我觉得此种方式不够完美。

3.2复现说明

      我项目中filter链是这样的,其中0和3两个filter是我添加的,其它filter一部分是项目遗留的,用来记录日志,判断内部调用时token的合法性等的filter,另一部分就是gateway自己的filter了。

在这里插入图片描述


      当执行到index=3时,执行到我自定义的filter

在这里插入图片描述


      filter首次执行时的情况如下图,可以看到body中是有数据的,经过判断后判定没权限,返回调用者无权限。

在这里插入图片描述


      调用者确实可以正常收到结果

在这里插入图片描述


      但继续看后台代码执行过程,诡异的现象出现了。就算此时filter没有截断,也要执行index=4的filter了,但此时,index=1,filter重复执行了,更诡异的是,filter是从index=1执行的,不是index=0的filter。

在这里插入图片描述


      执行到index=3时,再次执行到我定义的filter。

在这里插入图片描述


      此时body数据为空,当然也就无权限,再次返回调用者无权限信息

在这里插入图片描述


      后台发生错误,推测可能是因为过滤器链第一次执行时,response已经返回,链接关闭导致。

在这里插入图片描述

思考

      这个问题可以分成两部分来看,一部分是response返回后filter没有截断,后续filter和业务服务调用依然要发生,只是在发生后续操作的时候,出现了另一个问题,就是filter重复执行,并且从index=1的filter开始执行,不是index=0的filter。
      仔细思考一下,网上的第二种形式应该也是有问题的,它应该也不能完成filter的截断,至于会不会重复执行index=1及之后的filter的情况,我没有实验。
      那如何完成filter的截断呢?
      抛开gateway,从更高的层面想一下,Spring FrameWork 5使用的响应式编程框架是Project Reactor3(以下简称Reactor),Reactor是怎么处理的呢?它是形如这样的代码:

private void reactorExample() {
   Flux.fromIterable(Arrays.asList("a,b,c".split(",")))
      .subscribe(result->{
         //成功时执行此处
      }, error->{
         //失败时执行此处
      });
}

      数据发出后经过Flux或者Mono操作符的处理,处理成功执行result代表的consumer代码块,处理失败执行error代表的errorConsumer代码块。
      gateway执行filter时,实际上是在执行consumer,如果想让filter截断,需要让它执行到其它的分支上去,比如errorConsumer代码分支。

最终方案

      顺着以上思路,我做了如下三点改动:
      1.权限验证失败时,不在使用response回写body数据,而是返回了Mono.error。

在这里插入图片描述


      2.自定义了GatewayException封装返回给调用方的信息。

在这里插入图片描述


      3.定义全局异常处理,在异常里返回调用方信息。

在这里插入图片描述


      亲测问题解决。

ASP.NET MVC 全局过滤器(FilterConfig)、标记在控制器上和方法上的筛选器执行顺序

ASP.NET MVC 全局过滤器(FilterConfig)、标记在控制器上和方法上的筛选器执行顺序

FilterConfig->控制器上的筛选器-->方法上的筛选器(大-->小,上-->下)

全局-->控制器->个别

 尝试的时候记得把返回true

1  protected override bool AuthorizeCore(HttpContextBase httpContext)
2  {
3    //return base.AuthorizeCore(httpContext);
4    return true;//返回true才会执行下一个同类型的filter
5 
6  }
View Code

 需要注意与其他筛选器的执行顺序

 

现在还不知道Order有啥用(试过设置,不管大小如何,顺序依旧- -)20190324

ASP.NET MVC筛选器之特殊筛选器IOverrideFilter

ASP.NET MVC筛选器之特殊筛选器IOverrideFilter

总结

以上是小编为你收集整理的ASP.NET MVC筛选器之特殊筛选器IOverrideFilter全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

asp.net – IIS7 HttpModule和ISAPI Filter执行顺序

asp.net – IIS7 HttpModule和ISAPI Filter执行顺序

我有一个使用 ISAPI Rewrite的网站以及一个自定义的HttpModule,它们都进行了Url重定向和重写.

在IIS 6中,一切正常:首先运行ISAPI Rewrite过滤器,然后运行HttpModule.在IIS 7(集成模式)中,顺序现在是相反的,这会产生问题.

我的问题,特别是,HttpModule有一个条件,它将使用context.RewritePath发出一个Url重写.如果没有提供文档,它将显式地向路径添加“index.aspx”,因此对/ test /的请求将被重写为/test/index.aspx.

在重写路径之后的某个时刻,执行ISAPI重写过滤器.我们有一个与模块相反的规则:对/test/index.aspx的请求被301重定向到/ test /.因此,我们有一个无限循环.

如何在IIS 7中确定HttpModules和ISAPI过滤器的执行顺序?订单可以更改吗?我找到了this question,但它并没有真正帮助.我不是IIS 7的主人,但我确实在某种程度上理解模块和ISAPI过滤器“一起”运行.不幸的是,他们的管理方式不同,我无法弄清楚如何强迫一个人跑到另一个人面前.救命!

注意:我们假设我无法更改现有代码.它在IIS 6中有效.我只想知道是否有办法使其在IIS 7集成模式下工作.

解决方法

我也有一个类似的问题,我认为ISAPI重写首先执行,但显然这不是IIS7的工作原理

我发现这个帖子说明了

In integrated mode the events for native module,isapi and .net are called mixed together

e.g. if it’s a BeginRequest then the native module is the first to come,then isapi,then .net code. After that everything will repeat for AuthenticateRequest…

Some time ago it used to be like this: isapi has processed all events,and only after that .net was invoked. This is probably what you’ve assumed.

http://www.helicontech.com/forum/18447-ISAPI_RW3_Lite_on_IIS_7x_Integrated_mode.html

希望它有所帮助

我们今天的关于HTTP状态500-筛选器执行引发异常-重复执行doFilter和invokeDelegate筛选器错误的分享就到这里,谢谢您的阅读,如果想了解更多关于2. gateway 调用链截断及filter重复执行、ASP.NET MVC 全局过滤器(FilterConfig)、标记在控制器上和方法上的筛选器执行顺序、ASP.NET MVC筛选器之特殊筛选器IOverrideFilter、asp.net – IIS7 HttpModule和ISAPI Filter执行顺序的相关信息,可以在本站进行搜索。

本文标签: