最初實作的方式如下:
<service verb="get" noun="ProductCategoryContentFile">
<in-parameters>
<parameter name="productCategoryContentId" required="true"/>
</in-parameters>
<actions>
<entity-find-one entity-name="mantle.product.category.ProductCategoryContent" value-field="productCategoryContent"/>
<if condition="productCategoryContent?.contentLocation">
<script>ec.web.sendResourceResponse(productCategoryContent.contentLocation, true)</script>
</if>
</actions>
</service>
執行結果中圖檔可以展示出來,如果使用tomcat伺服器的話是沒有問題的,但是如果是在jetty中的話檢視console的時候會出現如下的log
日志内容如下:
1 14:06:12.151 WARN 48402763-759 o.moqui.i.c.TransactionFacadeImpl Transaction rollback for [Error running transition in [http://localhost:8080/rest/s1/slp/products/categories/contents/100001/file]]. Here is the current location:
2 org.moqui.BaseException: Rollback location
3 at org.moqui.impl.context.TransactionFacadeImpl.rollback(TransactionFacadeImpl.groovy:415) [moqui-framework-2.0.0.jar:2.0.0]
4 at org.moqui.impl.context.TransactionFacadeImpl.rollback(TransactionFacadeImpl.groovy:398) [moqui-framework-2.0.0.jar:2.0.0]
5 at org.moqui.impl.screen.ScreenRenderImpl.internalRender(ScreenRenderImpl.groovy:349) [moqui-framework-2.0.0.jar:2.0.0]
6 at org.moqui.impl.screen.ScreenRenderImpl.render(ScreenRenderImpl.groovy:176) [moqui-framework-2.0.0.jar:2.0.0]
7 at org.moqui.impl.webapp.MoquiServlet.doScreenRequest(MoquiServlet.groovy:79) [moqui-framework-2.0.0.jar:2.0.0]
8 at org.moqui.impl.webapp.MoquiServlet.service(MoquiServlet.groovy:54) [moqui-framework-2.0.0.jar:2.0.0]
9 at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [moqui-2.0.0.war:3.1.0]
10 at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:837) [moqui-2.0.0.war:9.3.10.v20160621]
11 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1689) [moqui-2.0.0.war:9.3.10.v20160621]
12 at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.d(WebSocketUpgradeFilter.java:225) [moqui-2.0.0.war:9.3.10.v20160621]
13 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) [moqui-2.0.0.war:9.3.10.v20160621]
14 at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581) [moqui-2.0.0.war:9.3.10.v20160621]
15 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [moqui-2.0.0.war:9.3.10.v20160621]
16 at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) [moqui-2.0.0.war:9.3.10.v20160621]
17 at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) [moqui-2.0.0.war:9.3.10.v20160621]
18 at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180) [moqui-2.0.0.war:9.3.10.v20160621]
19 at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511) [moqui-2.0.0.war:9.3.10.v20160621]
20 at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [moqui-2.0.0.war:9.3.10.v20160621]
21 at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112) [moqui-2.0.0.war:9.3.10.v20160621]
22 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [moqui-2.0.0.war:9.3.10.v20160621]
23 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) [moqui-2.0.0.war:9.3.10.v20160621]
24 at org.eclipse.jetty.server.Server.handle(Server.java:524) [moqui-2.0.0.war:9.3.10.v20160621]
25 at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319) [moqui-2.0.0.war:9.3.10.v20160621]
26 at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253) [moqui-2.0.0.war:9.3.10.v20160621]
27 at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) [moqui-2.0.0.war:9.3.10.v20160621]
28 at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) [moqui-2.0.0.war:9.3.10.v20160621]
29 at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) [moqui-2.0.0.war:9.3.10.v20160621]
30 org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) [moqui-2.0.0.war:9.3.10.v20160621]
31 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) [moqui-2.0.0.war:9.3.10.v20160621]
32 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) [moqui-2.0.0.war:9.3.10.v20160621]
33 at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) [moqui-2.0.0.war:9.3.10.v20160621]
34 at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) [moqui-2.0.0.war:9.3.10.v20160621]
35 at java.lang.Thread.run(Thread.java:745) [?:1.8.0_77]
36 14:06:12.153 ERROR 48402763-759 o.m.i.w.MoquiServlet Internal error processing request: STREAM
37 java.lang.IllegalStateException: STREAM
38 at org.eclipse.jetty.server.Response.getWriter(Response.java:891) ~[?:?]
39 at org.moqui.impl.context.WebFacadeImpl.sendJsonError(WebFacadeImpl.groovy:647) ~[moqui-framework-2.0.0.jar:2.0.0]
40 at org.moqui.impl.context.WebFacadeImpl.handleServiceRestCall(WebFacadeImpl.groovy:1184) ~[moqui-framework-2.0.0.jar:2.0.0]
41 at org.moqui.context.WebFacade$handleServiceRestCall.call(Unknown Source) ~[?:?]
42 at rest_xml_transition_s1_actions.run(rest_xml_transition_s1_actions:6) ~[script:?]
43 at org.moqui.impl.actions.XmlAction.run(XmlAction.groovy:66) ~[moqui-framework-2.0.0.jar:2.0.0]
44 at org.moqui.impl.screen.ScreenDefinition$TransitionItem.run(ScreenDefinition.groovy:701) ~[moqui-framework-2.0.0.jar:2.0.0]
45 at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:239) ~[moqui-framework-2.0.0.jar:2.0.0]
46 at org.moqui.impl.screen.ScreenRenderImpl.recursiveRunTransition(ScreenRenderImpl.groovy:233) ~[moqui-framework-2.0.0.jar:2.0.0]
47 at org.moqui.impl.screen.ScreenRenderImpl.internalRender(ScreenRenderImpl.groovy:347) ~[moqui-framework-2.0.0.jar:2.0.0]
48 at org.moqui.impl.screen.ScreenRenderImpl.render(ScreenRenderImvy:176) ~[moqui-framework-2.0.0.jar:2.0.0]
49 at org.moqui.impl.webapp.MoquiServlet.doScreenRequest(MoquiServlet.groovy:79) [moqui-framework-2.0.0.jar:2.0.0]
50 at org.moqui.impl.webapp.MoquiServlet.service(MoquiServlet.groovy:54) [moqui-framework-2.0.0.jar:2.0.0]
51 at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [moqui-2.0.0.war:3.1.0]
52 at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:837) [moqui-2.0.0.war:9.3.10.v20160621]
53 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1689) [moqui-2.0.0.war:9.3.10.v20160621]
54 at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:225) [moqui-2.0.0.war:9.3.10.v20160621]
55 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) [moqui-2.0.0.war:9.3.10.v20160621]
56 at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581) [moqui-2.0.0.war:9.3.10.v20160621]
57 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [moqui-2.0.0.war:9.3.10.v20160621]
58 at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) [moqui-2.0.0.war:9.3.10.v20160621]
59 at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) [moqui-2.0.0.war:9.3.10.v20160621]
60 at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180) [moqui-2.0.0.war:9.3.10.v20160621]
61 at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511) [moqui-2.0.0.war:9.3.10.v20160621]
62 at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [moqui-2.0.0.war:9.3.10.v20160621]
63 at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112) [moqui-2.0.0.war:9.3.10.v20160621]
64 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [moqui-2.0.0.war:9.3.10.v20160621]
65 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) [moqui-2.0.0.war:9.3.10.v20160621]
66 at org.ejetty.server.Server.handle(Server.java:524) [moqui-2.0.0.war:9.3.10.v20160621]
67 at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319) [moqui-2.0.0.war:9.3.10.v20160621]
68 at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253) [moqui-2.0.0.war:9.3.10.v20160621]
69 at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) [moqui-2.0.0.war:9.3.10.v20160621]
70 at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) [moqui-2.0.0.war:9.3.10.v20160621]
71 at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) [moqui-2.0.0.war:9.3.10.v20160621]
72 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) [moqui-2.0.0.war:9.3.10.v20160621]
73 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) [moqui-2.0.0.war:9.3.10.v20160621]
74 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) [moqui-2.0.0.war:9.3.10.v20160621]
75 at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) [moqui-2.0.0.war:9.3.10.v20160621]
76 at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) [moqui-2.0.0.war:9.3.10.v20160621]
77 at java.lang.Thread.run(Thread.java:745) [?:1.8.0_77]
78 14:06:12.165 WARN 48402763-759 o.moqui.i.c.TransactionFacadeImpl Rollback only not set on current transaction, status is STATUS_NO_TRANSACTION
79 14:06:12.165 ERROR 48402763-759 o.m.i.w.MoquiServlet Error rendering internal-error error screen, sending code 500 with message: STREAM
80 java.lang.RuntimeException: Error rendering screen [component://webroot/screen/webroot.xml]
81 at org.moqui.impl.screen.ScreenRenderImpl.doActualRender(ScreenRenderImpl.groovy:737) ~[moqui-framework-2.0.0.jar:2.0.0]
82 at org.moqui.impl.screen.ScreenRenderImpl.internalRender(ScreenRenderImpl.groovy:594) ~[moqui-framework-2.0.0.jar:2.0.0]
83 .moqui.impl.screen.ScreenRenderImpl.render(ScreenRenderImpl.groovy:176) ~[moqui-framework-2.0.0.jar:2.0.0]
84 at org.moqui.impl.webapp.MoquiServlet.sendErrorResponse(MoquiServlet.groovy:142) [moqui-framework-2.0.0.jar:2.0.0]
85 at org.moqui.impl.webapp.MoquiServlet.doScreenRequest(MoquiServlet.groovy:103) [moqui-framework-2.0.0.jar:2.0.0]
86 at org.moqui.impl.webapp.MoquiServlet.service(MoquiServlet.groovy:54) [moqui-framework-2.0.0.jar:2.0.0]
87 at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [moqui-2.0.0.war:3.1.0]
88 at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:837) [moqui-2.0.0.war:9.3.10.v20160621]
89 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1689) [moqui-2.0.0.war:9.3.10.v20160621]
90 at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:225) [moqui-2.0.0.war:9.3.10.v20160621]
91 at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) [moqui-2.0.0.war:9.3.10.v20160621]
92 at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581) [moqui-2.0.0.war:9.3.10.v20160621]
93 at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [moqui-2.0.0.war:9.3.10.v20160621]
94 at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) [moqui-2.0.0.war:9.3.10.v20160621]
95 at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) [moqui-2.0.0.war:9.3.10.v20160621]
96 at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180) [moqui-2.0.0.war:9.3.10.v20160621]
97 at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511) [moqui-2.0.0.war:9.3.10.v20160621]
98 at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [moqui-2.0.0.war:9.3.10.v20160621]
99 at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112) [moqui-2.0.0.war:9.3.10.v20160621]
100 at org.eclipse.jetty.server.handler.ScopedHandler.handle(Scoped.java:141) [moqui-2.0.0.war:9.3.10.v20160621]
101 at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) [moqui-2.0.0.war:9.3.10.v20160621]
102 at org.eclipse.jetty.server.Server.handle(Server.java:524) [moqui-2.0.0.war:9.3.10.v20160621]
103 at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319) [moqui-2.0.0.war:9.3.10.v20160621]
104 at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253) [moqui-2.0.0.war:9.3.10.v20160621]
105 at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) [moqui-2.0.0.war:9.3.10.v20160621]
106 at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) [moqui-2.0.0.war:9.3.10.v20160621]
107 at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) [moqui-2.0.0.war:9.3.10.v20160621]
108 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) [moqui-2.0.0.war:9.3.10.v20160621]
109 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) [moqui-2.0.0.war:9.3.10.v20160621]
110 at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) [moqui-2.0.0.war:9.3.10.v20160621]
111 at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) [moqui-2.0.0.war:9.3.10.v20160621]
112 at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) [moqui-2.0.0.war:9.3.10.v20160621]
113 at java.lang.Thread.run(Thread.java:745) [?:1.8.0_77]
114 Caused by: java.lang.IllegalStateException: STREAM
115 at org.eclipse.jetty.server.Response.getWriter(Response.java:891) ~[?:?]
116 at org.moqui.impl.screen.ScreenRenderImpl.getWriter(ScreenRenderImpl.groovy:107) ~[moqui-framework-2.0.0.jar:2.0.0]
117 at org.moqui.impl.screen.ScreenWidgets.render(ScreenWidgets.groovy:43) ~[moqui-framework-2.0.0.jar:2.0.0]
118 at org.moqui.impl.screen.ScreenSection.renderSingle(ScreenSection.groovy:140) ~[moqui-framework-2.0.0.jar:2.0.0]
119 at org.moquicreen.ScreenSection.render(ScreenSection.groovy:113) ~[moqui-framework-2.0.0.jar:2.0.0]
120 at org.moqui.impl.screen.ScreenDefinition.render(ScreenDefinition.groovy:459) ~[moqui-framework-2.0.0.jar:2.0.0]
121 at org.moqui.impl.screen.ScreenRenderImpl.doActualRender(ScreenRenderImpl.groovy:719) ~[moqui-framework-2.0.0.jar:2.0.0]
122 ... 32 more
關于這個問題主要是和jetty處理getWriter和getOutputStream的方式有關:
在jetty中的處理方式如下:
1 這兩個方法在jetty容易中是這麼處理:
2 org.eclipse.jetty.server.Response繼承自j2ee裡面的HttpServletResponse.java類
3 org.eclipse.jetty.server.Response.java類裡面
4
5 public ServletOutputStream getOutputStream() throws IOException
6 {
7 if (_outputState!=NONE && _outputState!=STREAM) 如果狀态為WRITER狀态,則抛出異常
8 throw new IllegalStateException("WRITER");
9
10 _outputState=STREAM; 把response狀态改為STREAM流狀态
11 return _connection.getOutputStream();
12 }
13
14 public PrintWriter getWriter() throws IOException
15 {
16 if (_outputState!=NONE && _outputState!=WRITER) 如果狀态為STREAM,則抛出異常
17 throw new IllegalStateException("STREAM");
18
19 /* if there is no writer yet */
20 if (_writer==null)
21 {
22 /* get encoding from Content-Type header */
23 String encoding = _characterEncoding;
24
25 if (encoding==null)
26 {
27 /* implementation of educated defaults */
28 if(_mimeType!=null)
29 encoding = null; // TODO getHttpContext().getEncodingByMimeType(_mimeType);
30
31 if (encoding==null)
32 encoding = StringUtil.__ISO_8859_1;
33
34 setCharacterEncoding(encoding);
35 }
36
37 /* construct Writer using correct encoding */
38 _writer = _connection.getPrintWriter(encoding);
39 }
40 _outputState=WRITER; 把response狀态改為WRITER狀态,
41 return _writer;
42 }
43
44 也就是說在j2ee,web應用裡面不能同時打開PrintWriter和OutputStream,否則就是抛出上面那個異常。
45
46 jetty的response裡面有三種狀态:
47 public static final int
48 NONE=0, 未調用getPrintWriter和getOutputStream之前的預設狀态
49 STREAM=1, 二進制流狀态 調用getOutputStream之後的狀态
50 WRITER=2; 字元流狀态
51
52
53 解決方法:
54 1.在應用中隻使用一個,要麼都用getPrintWriter,要麼都用getOutputStream。
55 2.在webx 中的com.alibaba.citrus.service.requestcontext.buffered.impl.BufferedResponseImpl.java類中有下面這麼解決方案:
56
57 /**
58 * 取得輸出流。
59 *
60 * @return response的輸出流
61 * @throws IOException 輸入輸出失敗
62 */
63 @Override
64 public ServletOutputStream getOutputStream() throws IOException {
65 if (stream != null) {
66 return stream;
67 }
68
69 if (writer != null) {
70 // 如果getWriter方法已經被調用,則将writer轉換成OutputStream
71 // 這樣做會增加少量額外的記憶體開銷,但标準的servlet engine不會遇到這種情形,
72 // 隻有少數servlet engine需要這種做法(resin)。
73 if (writerAdapter != null) {
74 return writerAdapter;
75 } else {
76 log.debug("Attampt to getOutputStream after calling getWriter. This may cause unnecessary system cost.");
77 writerAdapter = new WriterOutputStream(writer, getCharacterEncoding());
78 return writerAdapter;
79 }
80 }
81
82 if (buffering) {
83 // 注意,servletStream一旦建立,就不改變,
84 // 如果需要改變,隻需要改變其下面的bytes流即可。
85 if (bytesStack == null) {
86 bytesStack = new Stack<ByteArrayOutputStream>();
87 }
88
89 ByteArrayOutputStream bytes = new ByteArrayOutputStream();
90
91 bytesStack.push(bytes);
92 stream = new BufferedServletOutputStream(bytes);
93
94 log.debug("Created new byte buffer");
95 } else {
96 stream = super.getOutputStream();
97 }
98
99 return stream;
100 }
101
102 /**
103 * 取得輸出字元流。
104 *
105 * @return response的輸出字元流
106 * @throws IOException 輸入輸出失敗
107 */
108 @Override
109 public PrintWriter getWriter() throws IOException {
110 if (writer != null) {
111 return writer;
112 }
113
114 if (stream != null) {
115 // 如果getOutputStream方法已經被調用,則将stream轉換成PrintWriter。
116 // 這樣做會增加少量額外的記憶體開銷,但标準的servlet engine不會遇到這種情形,
117 // 隻有少數servlet engine需要這種做法(resin)。
118 if (streamAdapter != null) {
119 return streamAdapter;
120 } else {
121 log.debug("Attampt to getWriter after calling getOutputStream. This may cause unnecessary system cost.");
122 streamAdapter = new PrintWriter(new OutputStreamWriter(stream, getCharacterEncoding()), true);
123 return streamAdapter;
124 }
125 }
126
127 if (buffering) {
128 // 注意,servletWriter一旦建立,就不改變,
129 // 如果需要改變,隻需要改變其下面的chars流即可。
130 if (charsStack == null) {
131 charsStack = new Stack<StringWriter>();
132 }
133
134 StringWriter chars = new StringWriter();
135
136 charsStack.push(chars);
137 writer = new BufferedServletWriter(chars);
138
139 log.debug("Created new character buffer");
140 } else {
141 writer = super.getWriter();
142 }
143
144 return writer;
145 }
146
147
148 是以在我們自己的應用中就不要再調用完j2ee的原生response的getPrintWriter之後再調用原生的getOutputStream(),或者調用原生的response的getOutputStream之後再調用getPrintWriter。
下面就IllegalStateException宜昌做分析:
web容器生成的servlet代碼中有out.write(""),這和response.getOutputStream()産生沖突。
servlet規範中有說明,不能既使用response.getOutputStream()又調用response.getWriter(),無論先調用哪一個,在調用第二個的時候就抛出IllegalStateException
基于此,我們可以通過增加out.clear()和outpageContext.pushBody來解決,在寫入圖檔的使用需要加入flush()