blob: 44de97987db6294bcb493079321fb431a22a62e8 [file] [log] [blame]
刘洪青6266f992017-05-15 21:21:03 +08001<html><head><META http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>Apache Tomcat 7 (7.0.77) - Advanced IO and Tomcat</title><meta name="author" content="Remy Maucherat"><style type="text/css" media="print">
2 .noPrint {display: none;}
3 td#mainBody {width: 100%;}
4</style><style type="text/css">
5code {background-color:rgb(224,255,255);padding:0 0.1em;}
6code.attributeName, code.propertyName {background-color:transparent;}
7
8
9table {
10 border-collapse: collapse;
11 text-align: left;
12}
13table *:not(table) {
14 /* Prevent border-collapsing for table child elements like <div> */
15 border-collapse: separate;
16}
17
18th {
19 text-align: left;
20}
21
22
23div.codeBox pre code, code.attributeName, code.propertyName, code.noHighlight, .noHighlight code {
24 background-color: transparent;
25}
26div.codeBox {
27 overflow: auto;
28 margin: 1em 0;
29}
30div.codeBox pre {
31 margin: 0;
32 padding: 4px;
33 border: 1px solid #999;
34 border-radius: 5px;
35 background-color: #eff8ff;
36 display: table; /* To prevent <pre>s from taking the complete available width. */
37 /*
38 When it is officially supported, use the following CSS instead of display: table
39 to prevent big <pre>s from exceeding the browser window:
40 max-width: available;
41 width: min-content;
42 */
43}
44
45div.codeBox pre.wrap {
46 white-space: pre-wrap;
47}
48
49
50table.defaultTable tr, table.detail-table tr {
51 border: 1px solid #CCC;
52}
53
54table.defaultTable tr:nth-child(even), table.detail-table tr:nth-child(even) {
55 background-color: #FAFBFF;
56}
57
58table.defaultTable tr:nth-child(odd), table.detail-table tr:nth-child(odd) {
59 background-color: #EEEFFF;
60}
61
62table.defaultTable th, table.detail-table th {
63 background-color: #88b;
64 color: #fff;
65}
66
67table.defaultTable th, table.defaultTable td, table.detail-table th, table.detail-table td {
68 padding: 5px 8px;
69}
70
71
72p.notice {
73 border: 1px solid rgb(255, 0, 0);
74 background-color: rgb(238, 238, 238);
75 color: rgb(0, 51, 102);
76 padding: 0.5em;
77 margin: 1em 2em 1em 1em;
78}
79</style></head><body bgcolor="#ffffff" text="#000000" link="#525D76" alink="#525D76" vlink="#525D76"><table border="0" width="100%" cellspacing="0"><!--PAGE HEADER--><tr><td><!--PROJECT LOGO--><a href="http://tomcat.apache.org/"><img src="./images/tomcat.gif" align="right" alt="
Hongqing Liufd5ee812014-05-10 16:32:51 +080080 The Apache Tomcat Servlet/JSP Container
刘洪青6266f992017-05-15 21:21:03 +080081 " border="0"></a></td><td><h1><font face="arial,helvetica,sanserif">Apache Tomcat 7</font></h1><font face="arial,helvetica,sanserif">Version 7.0.77, Mar 28 2017</font></td><td><!--APACHE LOGO--><a href="http://www.apache.org/"><img src="./images/asf-logo.svg" align="right" alt="Apache Logo" border="0" style="width: 266px;height: 83px;"></a></td></tr></table><table border="0" width="100%" cellspacing="4"><!--HEADER SEPARATOR--><tr><td colspan="2"><hr noshade size="1"></td></tr><tr><!--LEFT SIDE NAVIGATION--><td width="20%" valign="top" nowrap class="noPrint"><p><strong>Links</strong></p><ul><li><a href="index.html">Docs Home</a></li><li><a href="http://wiki.apache.org/tomcat/FAQ">FAQ</a></li><li><a href="#comments_section">User Comments</a></li></ul><p><strong>User Guide</strong></p><ul><li><a href="introduction.html">1) Introduction</a></li><li><a href="setup.html">2) Setup</a></li><li><a href="appdev/index.html">3) First webapp</a></li><li><a href="deployer-howto.html">4) Deployer</a></li><li><a href="manager-howto.html">5) Manager</a></li><li><a href="realm-howto.html">6) Realms and AAA</a></li><li><a href="security-manager-howto.html">7) Security Manager</a></li><li><a href="jndi-resources-howto.html">8) JNDI Resources</a></li><li><a href="jndi-datasource-examples-howto.html">9) JDBC DataSources</a></li><li><a href="class-loader-howto.html">10) Classloading</a></li><li><a href="jasper-howto.html">11) JSPs</a></li><li><a href="ssl-howto.html">12) SSL/TLS</a></li><li><a href="ssi-howto.html">13) SSI</a></li><li><a href="cgi-howto.html">14) CGI</a></li><li><a href="proxy-howto.html">15) Proxy Support</a></li><li><a href="mbeans-descriptors-howto.html">16) MBeans Descriptors</a></li><li><a href="default-servlet.html">17) Default Servlet</a></li><li><a href="cluster-howto.html">18) Clustering</a></li><li><a href="balancer-howto.html">19) Load Balancer</a></li><li><a href="connectors.html">20) Connectors</a></li><li><a href="monitoring.html">21) Monitoring and Management</a></li><li><a href="logging.html">22) Logging</a></li><li><a href="apr.html">23) APR/Native</a></li><li><a href="virtual-hosting-howto.html">24) Virtual Hosting</a></li><li><a href="aio.html">25) Advanced IO</a></li><li><a href="extras.html">26) Additional Components</a></li><li><a href="maven-jars.html">27) Mavenized</a></li><li><a href="security-howto.html">28) Security Considerations</a></li><li><a href="windows-service-howto.html">29) Windows Service</a></li><li><a href="windows-auth-howto.html">30) Windows Authentication</a></li><li><a href="jdbc-pool.html">31) Tomcat's JDBC Pool</a></li><li><a href="web-socket-howto.html">32) WebSocket</a></li></ul><p><strong>Reference</strong></p><ul><li><a href="RELEASE-NOTES.txt">Release Notes</a></li><li><a href="config/index.html">Configuration</a></li><li><a href="api/index.html">Tomcat Javadocs</a></li><li><a href="servletapi/index.html">Servlet Javadocs</a></li><li><a href="jspapi/index.html">JSP 2.2 Javadocs</a></li><li><a href="elapi/index.html">EL 2.2 Javadocs</a></li><li><a href="websocketapi/index.html">WebSocket 1.1 Javadocs</a></li><li><a href="http://tomcat.apache.org/connectors-doc/">JK 1.2 Documentation</a></li></ul><p><strong>Apache Tomcat Development</strong></p><ul><li><a href="building.html">Building</a></li><li><a href="changelog.html">Changelog</a></li><li><a href="http://wiki.apache.org/tomcat/TomcatVersions">Status</a></li><li><a href="developers.html">Developers</a></li><li><a href="architecture/index.html">Architecture</a></li><li><a href="funcspecs/index.html">Functional Specs.</a></li><li><a href="tribes/introduction.html">Tribes</a></li></ul></td><!--RIGHT SIDE MAIN BODY--><td width="80%" valign="top" align="left" id="mainBody"><h1>Advanced IO and Tomcat</h1><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Table of Contents"><!--()--></a><a name="Table_of_Contents"><strong>Table of Contents</strong></a></font></td></tr><tr><td><blockquote>
Hongqing Liufd5ee812014-05-10 16:32:51 +080082<ul><li><a href="#Introduction">Introduction</a></li><li><a href="#Comet_support">Comet support</a><ol><li><a href="#CometEvent">CometEvent</a></li><li><a href="#CometFilter">CometFilter</a></li><li><a href="#Example_code">Example code</a></li><li><a href="#Comet_timeouts">Comet timeouts</a></li></ol></li><li><a href="#Asynchronous_writes">Asynchronous writes</a></li></ul>
83</blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Introduction"><strong>Introduction</strong></a></font></td></tr><tr><td><blockquote>
84
85 <p>
刘洪青6266f992017-05-15 21:21:03 +080086 With usage of APR or NIO APIs as the basis of its connectors, Tomcat is
87 able to provide a number of extensions over the regular blocking IO
Hongqing Liufd5ee812014-05-10 16:32:51 +080088 as provided with support for the Servlet API.
89 </p>
90
91 <p>
92 <b>IMPORTANT NOTE: Usage of these features requires using the APR or NIO
93 HTTP connectors. The classic java.io HTTP connector and the AJP connectors
94 do not support them.</b>
95 </p>
96
97 </blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Comet support"><!--()--></a><a name="Comet_support"><strong>Comet support</strong></a></font></td></tr><tr><td><blockquote>
98
99 <p>
100 Comet support allows a servlet to process IO asynchronously, receiving
101 events when data is available for reading on the connection (rather than
102 always using a blocking read), and writing data back on connections
103 asynchronously (most likely responding to some event raised from some
104 other source).
105 </p>
106
107 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="CometEvent"><strong>CometEvent</strong></a></font></td></tr><tr><td><blockquote>
刘洪青6266f992017-05-15 21:21:03 +0800108
Hongqing Liufd5ee812014-05-10 16:32:51 +0800109 <p>
刘洪青6266f992017-05-15 21:21:03 +0800110 Servlets which implement the <code>org.apache.catalina.comet.CometProcessor</code>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800111 interface will have their event method invoked rather than the usual service
112 method, according to the event which occurred. The event object gives
113 access to the usual request and response objects, which may be used in the
114 usual way. The main difference is that those objects remain valid and fully
115 functional at any time between processing of the BEGIN event until processing
116 an END or ERROR event.
117 The following event types exist:
118 </p>
刘洪青6266f992017-05-15 21:21:03 +0800119
Hongqing Liufd5ee812014-05-10 16:32:51 +0800120 <ul>
刘洪青6266f992017-05-15 21:21:03 +0800121 <li>EventType.BEGIN: will be called at the beginning
122 of the processing of the connection. It can be used to initialize any relevant
123 fields using the request and response objects. Between the end of the processing
Hongqing Liufd5ee812014-05-10 16:32:51 +0800124 of this event, and the beginning of the processing of the end or error events,
125 it is possible to use the response object to write data on the open connection.
刘洪青6266f992017-05-15 21:21:03 +0800126 Note that the response object and dependent OutputStream and Writer are still
127 not synchronized, so when they are accessed by multiple threads,
128 synchronization is mandatory. After processing the initial event, the request
Hongqing Liufd5ee812014-05-10 16:32:51 +0800129 is considered to be committed.</li>
130 <li>EventType.READ: This indicates that input data is available, and that one read can be made
131 without blocking. The available and ready methods of the InputStream or
132 Reader may be used to determine if there is a risk of blocking: the servlet
刘洪青6266f992017-05-15 21:21:03 +0800133 should read while data is reported available. When encountering a read error,
134 the servlet should report it by propagating the exception properly. Throwing
135 an exception will cause the error event to be invoked, and the connection
136 will be closed.
Hongqing Liufd5ee812014-05-10 16:32:51 +0800137 Alternately, it is also possible to catch any exception, perform clean up
138 on any data structure the servlet may be using, and using the close method
刘洪青6266f992017-05-15 21:21:03 +0800139 of the event. It is not allowed to attempt reading data from the request
Hongqing Liufd5ee812014-05-10 16:32:51 +0800140 object outside of the execution of this method.<br>
141 On some platforms, like Windows, a client disconnect is indicated by a READ event.
142 Reading from the stream may result in -1, an IOException or an EOFException.
143 Make sure you properly handle all these three cases.
刘洪青6266f992017-05-15 21:21:03 +0800144 If you don't catch the IOException, Tomcat will instantly invoke your event chain with an ERROR as
Hongqing Liufd5ee812014-05-10 16:32:51 +0800145 it catches the error for you, and you will be notified of the error at that time.
146 </li>
147 <li>EventType.END: End may be called to end the processing of the request. Fields that have
148 been initialized in the begin method should be reset. After this event has
149 been processed, the request and response objects, as well as all their dependent
刘洪青6266f992017-05-15 21:21:03 +0800150 objects will be recycled and used to process other requests. End will also be
Hongqing Liufd5ee812014-05-10 16:32:51 +0800151 called when data is available and the end of file is reached on the request input
152 (this usually indicates the client has pipelined a request).</li>
153 <li>EventType.ERROR: Error will be called by the container in the case where an IO exception
154 or a similar unrecoverable error occurs on the connection. Fields that have
155 been initialized in the begin method should be reset. After this event has
156 been processed, the request and response objects, as well as all their dependent
157 objects will be recycled and used to process other requests.</li>
158 </ul>
159
160 <p>
161 There are some event subtypes which allow finer processing of events (note: some of these
162 events require usage of the org.apache.catalina.valves.CometConnectionManagerValve valve):
163 </p>
164
165 <ul>
刘洪青6266f992017-05-15 21:21:03 +0800166 <li>EventSubType.TIMEOUT: The connection timed out (sub type of ERROR); note that this ERROR
167 type is not fatal, and the connection will not be closed unless the servlet uses the close
Hongqing Liufd5ee812014-05-10 16:32:51 +0800168 method of the event.
169 </li>
170 <li>EventSubType.CLIENT_DISCONNECT: The client connection was closed (sub type of ERROR).
171 </li>
刘洪青6266f992017-05-15 21:21:03 +0800172 <li>EventSubType.IOEXCEPTION: An IO exception occurred, such as invalid content, for example,
Hongqing Liufd5ee812014-05-10 16:32:51 +0800173 an invalid chunk block (sub type of ERROR).
174 </li>
175 <li>EventSubType.WEBAPP_RELOAD: The web application is being reloaded (sub type of END).
176 </li>
177 <li>EventSubType.SESSION_END: The servlet ended the session (sub type of END).
178 </li>
179 </ul>
180
181 <p>
182 As described above, the typical lifecycle of a Comet request will consist in a series of
刘洪青6266f992017-05-15 21:21:03 +0800183 events such as: BEGIN -&gt; READ -&gt; READ -&gt; READ -&gt; ERROR/TIMEOUT. At any time, the servlet
Hongqing Liufd5ee812014-05-10 16:32:51 +0800184 may end processing of the request by using the close method of the event object.
185 </p>
刘洪青6266f992017-05-15 21:21:03 +0800186
Hongqing Liufd5ee812014-05-10 16:32:51 +0800187 </blockquote></td></tr></table>
188
189 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="CometFilter"><strong>CometFilter</strong></a></font></td></tr><tr><td><blockquote>
刘洪青6266f992017-05-15 21:21:03 +0800190
Hongqing Liufd5ee812014-05-10 16:32:51 +0800191 <p>
192 Similar to regular filters, a filter chain is invoked when comet events are processed.
刘洪青6266f992017-05-15 21:21:03 +0800193 These filters should implement the CometFilter interface (which works in the same way as
Hongqing Liufd5ee812014-05-10 16:32:51 +0800194 the regular Filter interface), and should be declared and mapped in the deployment
195 descriptor in the same way as a regular filter. The filter chain when processing an event
196 will only include filters which match all the usual mapping rules, and also implement
197 the CometFiler interface.
198 </p>
刘洪青6266f992017-05-15 21:21:03 +0800199
Hongqing Liufd5ee812014-05-10 16:32:51 +0800200 </blockquote></td></tr></table>
201
202 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Example code"><!--()--></a><a name="Example_code"><strong>Example code</strong></a></font></td></tr><tr><td><blockquote>
刘洪青6266f992017-05-15 21:21:03 +0800203
Hongqing Liufd5ee812014-05-10 16:32:51 +0800204 <p>
205 The following pseudo code servlet implements asynchronous chat functionality using the API
206 described above:
207 </p>
刘洪青6266f992017-05-15 21:21:03 +0800208
209 <div class="codeBox"><pre><code>public class ChatServlet
Hongqing Liufd5ee812014-05-10 16:32:51 +0800210 extends HttpServlet implements CometProcessor {
211
刘洪青6266f992017-05-15 21:21:03 +0800212 protected ArrayList&lt;HttpServletResponse&gt; connections =
Hongqing Liufd5ee812014-05-10 16:32:51 +0800213 new ArrayList&lt;HttpServletResponse&gt;();
214 protected MessageSender messageSender = null;
刘洪青6266f992017-05-15 21:21:03 +0800215
Hongqing Liufd5ee812014-05-10 16:32:51 +0800216 public void init() throws ServletException {
217 messageSender = new MessageSender();
刘洪青6266f992017-05-15 21:21:03 +0800218 Thread messageSenderThread =
Hongqing Liufd5ee812014-05-10 16:32:51 +0800219 new Thread(messageSender, "MessageSender[" + getServletContext().getContextPath() + "]");
220 messageSenderThread.setDaemon(true);
221 messageSenderThread.start();
222 }
223
224 public void destroy() {
225 connections.clear();
226 messageSender.stop();
227 messageSender = null;
228 }
229
230 /**
231 * Process the given Comet event.
刘洪青6266f992017-05-15 21:21:03 +0800232 *
Hongqing Liufd5ee812014-05-10 16:32:51 +0800233 * @param event The Comet event that will be processed
234 * @throws IOException
235 * @throws ServletException
236 */
237 public void event(CometEvent event)
238 throws IOException, ServletException {
239 HttpServletRequest request = event.getHttpServletRequest();
240 HttpServletResponse response = event.getHttpServletResponse();
241 if (event.getEventType() == CometEvent.EventType.BEGIN) {
242 log("Begin for session: " + request.getSession(true).getId());
243 PrintWriter writer = response.getWriter();
刘洪青6266f992017-05-15 21:21:03 +0800244 writer.println("&lt;!DOCTYPE html&gt;");
245 writer.println("&lt;head&gt;&lt;title&gt;JSP Chat&lt;/title&gt;&lt;/head&gt;&lt;body&gt;");
Hongqing Liufd5ee812014-05-10 16:32:51 +0800246 writer.flush();
247 synchronized(connections) {
248 connections.add(response);
249 }
250 } else if (event.getEventType() == CometEvent.EventType.ERROR) {
251 log("Error for session: " + request.getSession(true).getId());
252 synchronized(connections) {
253 connections.remove(response);
254 }
255 event.close();
256 } else if (event.getEventType() == CometEvent.EventType.END) {
257 log("End for session: " + request.getSession(true).getId());
258 synchronized(connections) {
259 connections.remove(response);
260 }
261 PrintWriter writer = response.getWriter();
262 writer.println("&lt;/body&gt;&lt;/html&gt;");
263 event.close();
264 } else if (event.getEventType() == CometEvent.EventType.READ) {
265 InputStream is = request.getInputStream();
266 byte[] buf = new byte[512];
267 do {
268 int n = is.read(buf); //can throw an IOException
269 if (n &gt; 0) {
刘洪青6266f992017-05-15 21:21:03 +0800270 log("Read " + n + " bytes: " + new String(buf, 0, n)
Hongqing Liufd5ee812014-05-10 16:32:51 +0800271 + " for session: " + request.getSession(true).getId());
272 } else if (n &lt; 0) {
273 error(event, request, response);
274 return;
275 }
276 } while (is.available() &gt; 0);
277 }
278 }
279
280 public class MessageSender implements Runnable {
281
282 protected boolean running = true;
283 protected ArrayList&lt;String&gt; messages = new ArrayList&lt;String&gt;();
刘洪青6266f992017-05-15 21:21:03 +0800284
Hongqing Liufd5ee812014-05-10 16:32:51 +0800285 public MessageSender() {
286 }
刘洪青6266f992017-05-15 21:21:03 +0800287
Hongqing Liufd5ee812014-05-10 16:32:51 +0800288 public void stop() {
289 running = false;
290 }
291
292 /**
293 * Add message for sending.
294 */
295 public void send(String user, String message) {
296 synchronized (messages) {
297 messages.add("[" + user + "]: " + message);
298 messages.notify();
299 }
300 }
301
302 public void run() {
303
304 while (running) {
305
306 if (messages.size() == 0) {
307 try {
308 synchronized (messages) {
309 messages.wait();
310 }
311 } catch (InterruptedException e) {
312 // Ignore
313 }
314 }
315
316 synchronized (connections) {
317 String[] pendingMessages = null;
318 synchronized (messages) {
319 pendingMessages = messages.toArray(new String[0]);
320 messages.clear();
321 }
322 // Send any pending message on all the open connections
323 for (int i = 0; i &lt; connections.size(); i++) {
324 try {
325 PrintWriter writer = connections.get(i).getWriter();
326 for (int j = 0; j &lt; pendingMessages.length; j++) {
327 writer.println(pendingMessages[j] + "&lt;br&gt;");
328 }
329 writer.flush();
330 } catch (IOException e) {
331 log("IOExeption sending message", e);
332 }
333 }
334 }
335
336 }
337
338 }
339
340 }
341
刘洪青6266f992017-05-15 21:21:03 +0800342}</code></pre></div>
343
Hongqing Liufd5ee812014-05-10 16:32:51 +0800344 </blockquote></td></tr></table>
345 <table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#828DA6"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Comet timeouts"><!--()--></a><a name="Comet_timeouts"><strong>Comet timeouts</strong></a></font></td></tr><tr><td><blockquote>
346 <p>If you are using the NIO connector, you can set individual timeouts for your different comet connections.
刘洪青6266f992017-05-15 21:21:03 +0800347 To set a timeout, simply set a request attribute like the following code shows:</p>
348 <div class="codeBox"><pre><code>CometEvent event.... event.setTimeout(30*1000);</code></pre></div>
349 <p>or</p>
350 <div class="codeBox"><pre><code>event.getHttpServletRequest().setAttribute("org.apache.tomcat.comet.timeout", new Integer(30 * 1000));</code></pre></div>
351 <p>
Hongqing Liufd5ee812014-05-10 16:32:51 +0800352 This sets the timeout to 30 seconds.
353 Important note: in order to set this timeout, it has to be done on the <code>BEGIN</code> event.
354 The default value is <code>soTimeout</code>
355 </p>
356 <p>If you are using the APR connector, all Comet connections will have the same timeout value. It is <code>soTimeout*50</code>
357 </p>
358 </blockquote></td></tr></table>
359
360 </blockquote></td></tr></table><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="Asynchronous writes"><!--()--></a><a name="Asynchronous_writes"><strong>Asynchronous writes</strong></a></font></td></tr><tr><td><blockquote>
361
362 <p>
363 When APR or NIO is enabled, Tomcat supports using sendfile to send large static files.
刘洪青6266f992017-05-15 21:21:03 +0800364 These writes, as soon as the system load increases, will be performed
Hongqing Liufd5ee812014-05-10 16:32:51 +0800365 asynchronously in the most efficient way. Instead of sending a large response using
366 blocking writes, it is possible to write content to a static file, and write it
367 using a sendfile code. A caching valve could take advantage of this to cache the
368 response data in a file rather than store it in memory. Sendfile support is
369 available if the request attribute <code>org.apache.tomcat.sendfile.support</code>
370 is set to <code>Boolean.TRUE</code>.
371 </p>
刘洪青6266f992017-05-15 21:21:03 +0800372
Hongqing Liufd5ee812014-05-10 16:32:51 +0800373 <p>
374 Any servlet can instruct Tomcat to perform a sendfile call by setting the appropriate
375 request attributes. It is also necessary to correctly set the content length
376 for the response. When using sendfile, it is best to ensure that neither the
377 request or response have been wrapped, since as the response body will be sent later
刘洪青6266f992017-05-15 21:21:03 +0800378 by the connector itself, it cannot be filtered. Other than setting the 3 needed
Hongqing Liufd5ee812014-05-10 16:32:51 +0800379 request attributes, the servlet should not send any response data, but it may use
380 any method which will result in modifying the response header (like setting cookies).
381 </p>
刘洪青6266f992017-05-15 21:21:03 +0800382
Hongqing Liufd5ee812014-05-10 16:32:51 +0800383 <ul>
384 <li><code>org.apache.tomcat.sendfile.filename</code>: Canonical filename of the file which will be sent as
385 a String</li>
386 <li><code>org.apache.tomcat.sendfile.start</code>: Start offset as a Long</li>
387 <li><code>org.apache.tomcat.sendfile.end</code>: End offset as a Long</li>
388 </ul>
389
刘洪青6266f992017-05-15 21:21:03 +0800390 </blockquote></td></tr></table></td></tr><tr class="noPrint"><td width="20%" valign="top" nowrap class="noPrint"></td><td width="80%" valign="top" align="left"><table border="0" cellspacing="0" cellpadding="2"><tr><td bgcolor="#525D76"><font color="#ffffff" face="arial,helvetica.sanserif"><a name="comments_section" id="comments_section"><strong>Comments</strong></a></font></td></tr><tr><td><blockquote><p class="notice"><strong>Notice: </strong>This comments section collects your suggestions
391 on improving documentation for Apache Tomcat.<br><br>
392 If you have trouble and need help, read
393 <a href="http://tomcat.apache.org/findhelp.html">Find Help</a> page
394 and ask your question on the tomcat-users
395 <a href="http://tomcat.apache.org/lists.html">mailing list</a>.
396 Do not ask such questions here. This is not a Q&amp;A section.<br><br>
397 The Apache Comments System is explained <a href="./comments.html">here</a>.
398 Comments may be removed by our moderators if they are either
399 implemented or considered invalid/off-topic.</p><script type="text/javascript"><!--//--><![CDATA[//><!--
400 var comments_shortname = 'tomcat';
401 var comments_identifier = 'http://tomcat.apache.org/tomcat-7.0-doc/aio.html';
402 (function(w, d) {
403 if (w.location.hostname.toLowerCase() == "tomcat.apache.org") {
404 d.write('<div id="comments_thread"><\/div>');
405 var s = d.createElement('script');
406 s.type = 'text/javascript';
407 s.async = true;
408 s.src = 'https://comments.apache.org/show_comments.lua?site=' + comments_shortname + '&page=' + comments_identifier;
409 (d.getElementsByTagName('head')[0] || d.getElementsByTagName('body')[0]).appendChild(s);
410 }
411 else {
412 d.write('<div id="comments_thread"><strong>Comments are disabled for this page at the moment.<\/strong><\/div>');
413 }
414 })(window, document);
415 //--><!]]></script></blockquote></td></tr></table></td></tr><!--FOOTER SEPARATOR--><tr><td colspan="2"><hr noshade size="1"></td></tr><!--PAGE FOOTER--><tr><td colspan="2"><div align="center"><font color="#525D76" size="-1"><em>
416 Copyright &copy; 1999-2017, Apache Software Foundation
Hongqing Liufd5ee812014-05-10 16:32:51 +0800417 </em></font></div></td></tr></table></body></html>