1 下载服务器资源文件 ajax 实现原理一样
2
3 I:首先了解Stream 结果类型
4
5 Struts 专门为文件下载提供了一种 Stream 结果类型. 在使用一个 Stream 结果时, 不必准备一个 JSP 页面.
6
7 Stream 结果类型可以设置如下参数:
8 contentType:被下载的文件的 MIME 类型。默认值为 text/plain
9 contentLength:被下载的文件的大小,以字节为单位
10 contentDisposition: 可以设置下载文件名的ContentDispositon 响应头,默认值为 inline,通常设置为如下格式: attachment;filename="document.pdf".
11
12 inputName:Action 中提供的文件的输入流。默认值为 inputStream
13 bufferSize:文件下载时缓冲区的大小。默认值为 1024
14 allowCaching :文件下载时是否允许使用缓存。默认值为 true
15 contentCharSet:文件下载时的字符编码。
16 Stream 结果类型的参数可以在 Action 以属性的方式覆盖
17
18
19 <action name= "down_*" class ="actions.down" method= "{1}">
20 <result name= "download_success" type="stream" >
21 <param name="contentDisposition" >attachment;filename="my.jpg" </param>
22 <param name="contentType" >image/ jpeg</ param>
23 <param name="bufferSize" >102400 </param>
24 <param name="inputName" >inputStream </param>
25 </result>
26 </action>
27
28 public class down extends ActionSupport {
29
30 // 下载资源文件
31 private InputStream inputStream;
32
33 public InputStream getInputStream() {
34 return inputStream ;
35 }
36
37 public String download() throws Exception {
38 String name = "d:/Hydrangeas.jpg";
39 File fs = new File(name);
40 inputStream = new FileInputStream(fs);
41 return "download_success" ;
42 }
43 }
44 从StreamResult 源码中可以看到下载实现的过程和参数设置
45
46 public class StreamResult extends StrutsResultSupport {
47
48 public static final String DEFAULT_PARAM = "inputName";
49 protected String contentType = "text/plain" ;
50 protected String contentLength;
51 protected String contentDisposition = "inline" ;
52 protected String contentCharSet ;
53 protected String inputName = "inputStream" ;
54 protected InputStream inputStream;
55 protected int bufferSize = 1024;
56 protected boolean allowCaching = true;
57
58 以上都有默认的值 但可以在配置文件中进行参数配置
59 public StreamResult(InputStream in) {
60 this.inputStream = in;
61 }
62
63 public boolean getAllowCaching() {
64 return allowCaching ;
65 }
66
67 public void setAllowCaching(boolean allowCaching) {
68 this.allowCaching = allowCaching;
69 }
70
71 public int getBufferSize() {
72 return (bufferSize );
73 }
74
75 public void setBufferSize(int bufferSize) {
76 this.bufferSize = bufferSize;
77 }
78
79 public String getContentType() {
80 return (contentType );
81 }
82
83 public void setContentType(String contentType) {
84 this.contentType = contentType;
85 }
86
87
88 public String getContentLength() {
89 return contentLength ;
90 }
91
92 public void setContentLength(String contentLength) {
93 this.contentLength = contentLength;
94 }
95
96 public String getContentDisposition() {
97 return contentDisposition ;
98 }
99
100 public void setContentDisposition(String contentDisposition) {
101 this.contentDisposition = contentDisposition;
102 }
103
104 public String getContentCharSet() {
105 return contentCharSet ;
106 }
107
108 public void setContentCharSet(String contentCharSet) {
109 this.contentCharSet = contentCharSet;
110 }
111
112 public String getInputName() {
113 return (inputName );
114 }
115
116 public void setInputName(String inputName) {
117 this.inputName = inputName;
118 }
119
120
121 protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
122
123
124 //设置配置文件参数
125 resolveParamsFromStack(invocation.getStack(), invocation);
126
127 OutputStream oOutput = null;
128
129 try {
130 // inputName:Action 中提供的文件的输入流。默认值为 inputStream
131 if (inputStream == null) {
132 //从action中获取到输入流
133 inputStream = (InputStream) invocation.getStack().findValue(conditionalParse(inputName , invocation));
134 }
135
136 // Find the Response in context
137 HttpServletResponse oResponse = (HttpServletResponse) invocation.getInvocationContext().get(HTTP_RESPONSE );
138
139 contentType:被下载的文件的 MIME 类型。默认值为 text/plain
140 contentCharSet:文件下载时的字符编码。
141 if (contentCharSet != null && ! contentCharSet.equals("" )) {
142 oResponse.setContentType(conditionalParse(contentType , invocation)+";charset=" +contentCharSet );
143 }
144 else {
145 oResponse.setContentType(conditionalParse(contentType , invocation));
146 }
147
148 // contentLength:被下载的文件的大小,以字节为单位
149 if (contentLength != null) {
150 String _contentLength = conditionalParse(contentLength , invocation);
151 int _contentLengthAsInt = -1;
152 try {
153 _contentLengthAsInt = Integer.parseInt(_contentLength);
154 if (_contentLengthAsInt >= 0) {
155 oResponse.setContentLength(_contentLengthAsInt);
156 }
157 }
158 catch(NumberFormatException e) {
159
160 }
161 }
162 // contentDisposition: 可以设置下载文件名的ContentDispositon 响应头,默认值为 inline
163 if (contentDisposition != null) {
164 oResponse.addHeader("Content-Disposition" , conditionalParse(contentDisposition , invocation));
165 }
166
167 // allowCaching :文件下载时是否允许使用缓存。默认值为 true
168
169
170 if (!allowCaching ) {
171 oResponse.addHeader( "Pragma", "no-cache");
172 oResponse.addHeader( "Cache-Control", "no-cache");
173 }
174
175 // Get the outputstream
176 oOutput = oResponse. getOutputStream();
177
178 // Copy input to output
179 if (LOG .isDebugEnabled()) {
180 LOG.debug("Streaming to output buffer +++ START +++");
181 }
182 // bufferSize:文件下载时缓冲区的大小。默认值为 1024
183 byte[] oBuff = new byte[ bufferSize];
184 int iSize;
185
186 while (-1 != (iSize = inputStream.read(oBuff))) {
187 oOutput.write(oBuff, 0, iSize);
188 }
189
190 // Flush
191 oOutput.flush();
192 }
193 finally {
194 if (inputStream != null) inputStream.close();
195 if (oOutput != null) oOutput.close();
196 }
197 }
198
199 //设置配置文件的参数 到成员变量中
200 protected void resolveParamsFromStack(ValueStack stack, ActionInvocation invocation) {
201 String disposition = stack.findString("contentDisposition" );
202 if (disposition != null) {
203 setContentDisposition(disposition);
204 }
205
206 String contentType = stack.findString("contentType" );
207 if (contentType != null) {
208 setContentType(contentType);
209 }
210
211 String inputName = stack.findString( "inputName");
212 if (inputName != null) {
213 setInputName(inputName);
214 }
215
216 String contentLength = stack.findString("contentLength" );
217 if (contentLength != null) {
218 setContentLength(contentLength);
219 }
220
221 Integer bufferSize = (Integer) stack.findValue("bufferSize" , Integer.class);
222 if (bufferSize != null) {
223 setBufferSize(bufferSize.intValue());
224 }
225
226 if (contentCharSet != null ) {
227 contentCharSet = conditionalParse(contentCharSet , invocation);
228 }
229 else {
230 contentCharSet = stack.findString("contentCharSet" );
231 }
232 }
233
234 }