解決一個Bug
在昨晚的開發中遇到了一個非常令人頭疼的Bug
java.lang.IllegalStateException: getOutputStream() has already been called for this response
報錯資訊如下:有點長,,,
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:584)
at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:227)
at com.alibaba.fastjson.serializer.ASMSerializer_2_ResponseFacade.write(Unknown Source)
at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:333)
at com.alibaba.fastjson.serializer.JSONSerializer.writeWithFieldName(JSONSerializer.java:311)
at com.alibaba.fastjson.serializer.ObjectArrayCodec.write(ObjectArrayCodec.java:118)
at com.alibaba.fastjson.serializer.JSONSerializer.write(JSONSerializer.java:285)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:745)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:683)
at com.alibaba.fastjson.JSON.toJSONString(JSON.java:648)
at com.sirc.modelservice.aop.ControllerAspect.logBeforeController(ControllerAspect.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:617)
at org.springframework.aop.aspectj.AspectJMethodBeforeAdvice.before(AspectJMethodBeforeAdvice.java:44)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:57)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at
............
一開始是認為自己寫的關于IO流的代碼資源忘記關閉
自己檢查兩遍后確認沒有問題
進入Debug模式
發現被呼叫介面根本就進不了對應方法
再次觀察錯誤資訊
# at com.alibaba.fastjson.JSON.toJSONString(JSON.java:648)
......
# at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:634)
.......
# at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750)
大概猜到是fastJson包和SpringAop切面那里出了問題
果然,經過百度過后
發現fastjson內的方法使用了類似于out.write()等方法
//部分代碼
for(int var10 = 0; var10 < var9; ++var10) {
SerializeFilter filter = var8[var10];
serializer.addFilter(filter);
}
}
//this
serializer.write(object);
var15 = out.toString();
} finally {
out.close();
}
這個和JSP中呼叫的response.getOutputStream()產生沖突.
即Servlet規范說明
不能既呼叫response.getOutputStream(),又呼叫response.getWriter(),
于是就著手解決方案,因為團隊技術檔案 需要這個切面來記錄每次請求前的資訊以及請求后的回傳資訊,并保存在日志中,
于是我就在想能不能在切面原本匹配的方法中,排除某一個方法
解決方案
@Pointcut("execution(public * x.x.x.controller.*.*(..))")
public void commonController(){}
@Pointcut("execution(public * x.x.x.controller.SqlController.export(..))")
public void excludeController() {
}
@Pointcut("commonController() && !excludeController()")
public void allPointcutWeb() {
}
在定義切面的時候 單獨匹配出需要排除的方法
并使用
@Pointcut("commonController() && !excludeController()")
排除該方法
--最后
該操作要根據實際需求,本次需求的請求不攜帶任何資訊,所以不需要環繞通知也可以,
如果你的方法確實需要環繞通知的話,可以嘗試使用
ResponseEntity
-------謝謝 v
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/544678.html
標籤:Java
上一篇:idea 無法加載主類
