对于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(筛选器错误)
- 2. gateway 调用链截断及filter重复执行
- ASP.NET MVC 全局过滤器(FilterConfig)、标记在控制器上和方法上的筛选器执行顺序
- ASP.NET MVC筛选器之特殊筛选器IOverrideFilter
- asp.net – IIS7 HttpModule和ISAPI Filter执行顺序
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"/>
尝试打开Web应用程序的根目录时出现以下错误:
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重复执行
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)、标记在控制器上和方法上的筛选器执行顺序
FilterConfig->控制器上的筛选器-->方法上的筛选器(大-->小,上-->下)
全局-->控制器->个别
尝试的时候记得把返回true


1 protected override bool AuthorizeCore(HttpContextBase httpContext)
2 {
3 //return base.AuthorizeCore(httpContext);
4 return true;//返回true才会执行下一个同类型的filter
5
6 }
需要注意与其他筛选器的执行顺序
现在还不知道Order有啥用(试过设置,不管大小如何,顺序依旧- -)20190324
ASP.NET MVC筛选器之特殊筛选器IOverrideFilter
总结
以上是小编为你收集整理的ASP.NET MVC筛选器之特殊筛选器IOverrideFilter全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
asp.net – IIS7 HttpModule和ISAPI Filter执行顺序
在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集成模式下工作.
解决方法
我发现这个帖子说明了
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执行顺序的相关信息,可以在本站进行搜索。
本文标签: