Struts(二十六):文件上传
-
表单的准备
想要使用html表单上传一个或多个文件
1、须把html表单的enctype属性设置为multipart/form-data
2、须把html表单的method属性设置为post
3、须添加<input type="file">字段
-
Struts2的进行单文件上传需要操作步骤:
1、需要引入struts2需要的包,struts2上传是需要使用fileUpload拦截器实现的,而实际上上传文件是使用Commons FileUpload组建,所以需要导入commons-fileupload-1.3.2.jar、commons-io-2.2.jar包。
2、定制表单index.jsp
<s:form action="testUpload" method="post" enctype="multipart/form-data" theme="simple"> File:<s:file name="myFile"></s:file> File Description:<s:textfield name="desc"></s:textfield> <s:submit value="Submit"></s:submit> </s:form>
3、基本的文件上传设置:直接在action类中定义如下三个属性,并实现getter和setter
private File myFile; private String myFileContentType; private String myFileFileName; public File getMyFile() { return myFile; } public void setMyFile(File myFile) { this.myFile = myFile; } public String getMyFileContentType() { return myFileContentType; } public void setMyFileContentType(String myFileContentType) { this.myFileContentType = myFileContentType; } public String getMyFileFileName() { return myFileFileName; } public void setMyFileFileName(String myFileFileName) { this.myFileFileName = myFileFileName; }
备注:当查看fileUpload拦截器源码
1 /* 2 * $Id$ 3 * 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 package org.apache.struts2.interceptor; 23 24 import com.opensymphony.xwork2.ActionContext; 25 import com.opensymphony.xwork2.ActionInvocation; 26 import com.opensymphony.xwork2.ActionProxy; 27 import com.opensymphony.xwork2.LocaleProvider; 28 import com.opensymphony.xwork2.TextProvider; 29 import com.opensymphony.xwork2.TextProviderFactory; 30 import com.opensymphony.xwork2.ValidationAware; 31 import com.opensymphony.xwork2.inject.Container; 32 import com.opensymphony.xwork2.inject.Inject; 33 import com.opensymphony.xwork2.interceptor.AbstractInterceptor; 34 import com.opensymphony.xwork2.util.TextParseUtil; 35 import com.opensymphony.xwork2.util.logging.Logger; 36 import com.opensymphony.xwork2.util.logging.LoggerFactory; 37 import org.apache.struts2.ServletActionContext; 38 import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper; 39 import org.apache.struts2.util.ContentTypeMatcher; 40 41 import javax.servlet.http.HttpServletRequest; 42 import java.io.File; 43 import java.text.NumberFormat; 44 import java.util.ArrayList; 45 import java.util.Collection; 46 import java.util.Collections; 47 import java.util.Enumeration; 48 import java.util.HashMap; 49 import java.util.List; 50 import java.util.Map; 51 import java.util.Set; 52 53 /** 54 * <!-- START SNIPPET: description --> 55 * <p/> 56 * Interceptor that is based off of {@link MultiPartRequestWrapper}, which is automatically applied for any request that 57 * includes a file. It adds the following parameters, where [File Name] is the name given to the file uploaded by the 58 * HTML form: 59 * <p/> 60 * <ul> 61 * <p/> 62 * <li>[File Name] : File - the actual File</li> 63 * <p/> 64 * <li>[File Name]ContentType : String - the content type of the file</li> 65 * <p/> 66 * <li>[File Name]FileName : String - the actual name of the file uploaded (not the HTML name)</li> 67 * <p/> 68 * </ul> 69 * <p/> 70 * <p/> You can get access to these files by merely providing setters in your action that correspond to any of the three 71 * patterns above, such as setDocument(File document), setDocumentContentType(String contentType), etc. 72 * <br/>See the example code section. 73 * <p/> 74 * <p/> This interceptor will add several field errors, assuming that the action implements {@link ValidationAware}. 75 * These error messages are based on several i18n values stored in struts-messages.properties, a default i18n file 76 * processed for all i18n requests. You can override the text of these messages by providing text for the following 77 * keys: 78 * <p/> 79 * <ul> 80 * <p/> 81 * <li>struts.messages.error.uploading - a general error that occurs when the file could not be uploaded</li> 82 * <p/> 83 * <li>struts.messages.error.file.too.large - occurs when the uploaded file is too large</li> 84 * <p/> 85 * <li>struts.messages.error.content.type.not.allowed - occurs when the uploaded file does not match the expected 86 * content types specified</li> 87 * <p/> 88 * <li>struts.messages.error.file.extension.not.allowed - occurs when the uploaded file does not match the expected 89 * file extensions specified</li> 90 * <p/> 91 * </ul> 92 * <p/> 93 * <!-- END SNIPPET: description --> 94 * <p/> 95 * <p/> <u>Interceptor parameters:</u> 96 * <p/> 97 * <!-- START SNIPPET: parameters --> 98 * <p/> 99 * <ul> 100 * <p/> 101 * <li>maximumSize (optional) - the maximum size (in bytes) that the interceptor will allow a file reference to be set 102 * on the action. Note, this is <b>not</b> related to the various properties found in struts.properties. 103 * Default to approximately 2MB.</li> 104 * <p/> 105 * <li>allowedTypes (optional) - a comma separated list of content types (ie: text/html) that the interceptor will allow 106 * a file reference to be set on the action. If none is specified allow all types to be uploaded.</li> 107 * <p/> 108 * <li>allowedExtensions (optional) - a comma separated list of file extensions (ie: .html) that the interceptor will allow 109 * a file reference to be set on the action. If none is specified allow all extensions to be uploaded.</li> 110 * </ul> 111 * <p/> 112 * <p/> 113 * <!-- END SNIPPET: parameters --> 114 * <p/> 115 * <p/> <u>Extending the interceptor:</u> 116 * <p/> 117 * <p/> 118 * <p/> 119 * <!-- START SNIPPET: extending --> 120 * <p/> 121 * You can extend this interceptor and override the acceptFile method to provide more control over which files 122 * are supported and which are not. 123 * <p/> 124 * <!-- END SNIPPET: extending --> 125 * <p/> 126 * <p/> <u>Example code:</u> 127 * <p/> 128 * <pre> 129 * <!-- START SNIPPET: example-configuration --> 130 * <action name="doUpload" class="com.example.UploadAction"> 131 * <interceptor-ref name="fileUpload"/> 132 * <interceptor-ref name="basicStack"/> 133 * <result name="success">good_result.jsp</result> 134 * </action> 135 * <!-- END SNIPPET: example-configuration --> 136 * </pre> 137 * <p/> 138 * <!-- START SNIPPET: multipart-note --> 139 * <p/> 140 * You must set the encoding to <code>multipart/form-data</code> in the form where the user selects the file to upload. 141 * <p/> 142 * <!-- END SNIPPET: multipart-note --> 143 * <p/> 144 * <pre> 145 * <!-- START SNIPPET: example-form --> 146 * <s:form action="doUpload" method="post" enctype="multipart/form-data"> 147 * <s:file name="upload" label="File"/> 148 * <s:submit/> 149 * </s:form> 150 * <!-- END SNIPPET: example-form --> 151 * </pre> 152 * <p/> 153 * And then in your action code you'll have access to the File object if you provide setters according to the 154 * naming convention documented in the start. 155 * <p/> 156 * <pre> 157 * <!-- START SNIPPET: example-action --> 158 * package com.example; 159 * 160 * import java.io.File; 161 * import com.opensymphony.xwork2.ActionSupport; 162 * 163 * public UploadAction extends ActionSupport { 164 * private File file; 165 * private String contentType; 166 * private String filename; 167 * 168 * public void setUpload(File file) { 169 * this.file = file; 170 * } 171 * 172 * public void setUploadContentType(String contentType) { 173 * this.contentType = contentType; 174 * } 175 * 176 * public void setUploadFileName(String filename) { 177 * this.filename = filename; 178 * } 179 * 180 * public String execute() { 181 * //... 182 * return SUCCESS; 183 * } 184 * } 185 * <!-- END SNIPPET: example-action --> 186 * </pre> 187 */ 188 public class FileUploadInterceptor extends AbstractInterceptor { 189 190 private static final long serialVersionUID = -4764627478894962478L; 191 192 protected static final Logger LOG = LoggerFactory.getLogger(FileUploadInterceptor.class); 193 194 protected Long maximumSize; 195 protected Set<String> allowedTypesSet = Collections.emptySet(); 196 protected Set<String> allowedExtensionsSet = Collections.emptySet(); 197 198 private ContentTypeMatcher matcher; 199 private Container container; 200 201 @Inject 202 public void setMatcher(ContentTypeMatcher matcher) { 203 this.matcher = matcher; 204 } 205 206 @Inject 207 public void setContainer(Container container) { 208 this.container = container; 209 } 210 211 /** 212 * Sets the allowed extensions 213 * 214 * @param allowedExtensions A comma-delimited list of extensions 215 */ 216 public void setAllowedExtensions(String allowedExtensions) { 217 allowedExtensionsSet = TextParseUtil.commaDelimitedStringToSet(allowedExtensions); 218 } 219 220 /** 221 * Sets the allowed mimetypes 222 * 223 * @param allowedTypes A comma-delimited list of types 224 */ 225 public void setAllowedTypes(String allowedTypes) { 226 allowedTypesSet = TextParseUtil.commaDelimitedStringToSet(allowedTypes); 227 } 228 229 /** 230 * Sets the maximum size of an uploaded file 231 * 232 * @param maximumSize The maximum size in bytes 233 */ 234 public void setMaximumSize(Long maximumSize) { 235 this.maximumSize = maximumSize; 236 } 237 238 /* (non-Javadoc) 239 * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation) 240 */ 241 242 public String intercept(ActionInvocation invocation) throws Exception { 243 ActionContext ac = invocation.getInvocationContext(); 244 245 HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST); 246 247 if (!(request instanceof MultiPartRequestWrapper)) { 248 if (LOG.isDebugEnabled()) { 249 ActionProxy proxy = invocation.getProxy(); 250 LOG.debug(getTextMessage("struts.messages.bypass.request", new String[]{proxy.getNamespace(), proxy.getActionName()})); 251 } 252 253 return invocation.invoke(); 254 } 255 256 ValidationAware validation = null; 257 258 Object action = invocation.getAction(); 259 260 if (action instanceof ValidationAware) { 261 validation = (ValidationAware) action; 262 } 263 264 MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request; 265 266 if (multiWrapper.hasErrors()) { 267 for (String error : multiWrapper.getErrors()) { 268 if (validation != null) { 269 validation.addActionError(error); 270 } 271 } 272 } 273 274 // bind allowed Files 275 Enumeration fileParameterNames = multiWrapper.getFileParameterNames(); 276 while (fileParameterNames != null && fileParameterNames.hasMoreElements()) { 277 // get the value of this input tag 278 String inputName = (String) fileParameterNames.nextElement(); 279 280 // get the content type 281 String[] contentType = multiWrapper.getContentTypes(inputName); 282 283 if (isNonEmpty(contentType)) { 284 // get the name of the file from the input tag 285 String[] fileName = multiWrapper.getFileNames(inputName); 286 287 if (isNonEmpty(fileName)) { 288 // get a File object for the uploaded File 289 File[] files = multiWrapper.getFiles(inputName); 290 if (files != null && files.length > 0) { 291 List<File> acceptedFiles = new ArrayList<File>(files.length); 292 List<String> acceptedContentTypes = new ArrayList<String>(files.length); 293 List<String> acceptedFileNames = new ArrayList<String>(files.length); 294 String contentTypeName = inputName + "ContentType"; 295 String fileNameName = inputName + "FileName"; 296 297 for (int index = 0; index < files.length; index++) { 298 if (acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation)) { 299 acceptedFiles.add(files[index]); 300 acceptedContentTypes.add(contentType[index]); 301 acceptedFileNames.add(fileName[index]); 302 } 303 } 304 305 if (!acceptedFiles.isEmpty()) { 306 Map<String, Object> params = ac.getParameters(); 307 308 params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()])); 309 params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])); 310 params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])); 311 } 312 } 313 } else { 314 if (LOG.isWarnEnabled()) { 315 LOG.warn(getTextMessage(action, "struts.messages.invalid.file", new String[]{inputName})); 316 } 317 } 318 } else { 319 if (LOG.isWarnEnabled()) { 320 LOG.warn(getTextMessage(action, "struts.messages.invalid.content.type", new String[]{inputName})); 321 } 322 } 323 } 324 325 // invoke action 326 return invocation.invoke(); 327 } 328 329 /** 330 * Override for added functionality. Checks if the proposed file is acceptable based on contentType and size. 331 * 332 * @param action - uploading action for message retrieval. 333 * @param file - proposed upload file. 334 * @param contentType - contentType of the file. 335 * @param inputName - inputName of the file. 336 * @param validation - Non-null ValidationAware if the action implements ValidationAware, allowing for better 337 * logging. 338 * @return true if the proposed file is acceptable by contentType and size. 339 */ 340 protected boolean acceptFile(Object action, File file, String filename, String contentType, String inputName, ValidationAware validation) { 341 boolean fileIsAcceptable = false; 342 343 // If it's null the upload failed 344 if (file == null) { 345 String errMsg = getTextMessage(action, "struts.messages.error.uploading", new String[]{inputName}); 346 if (validation != null) { 347 validation.addFieldError(inputName, errMsg); 348 } 349 350 if (LOG.isWarnEnabled()) { 351 LOG.warn(errMsg); 352 } 353 } else if (maximumSize != null && maximumSize < file.length()) { 354 String errMsg = getTextMessage(action, "struts.messages.error.file.too.large", new String[]{inputName, filename, file.getName(), "" + file.length(), getMaximumSizeStr(action)}); 355 if (validation != null) { 356 validation.addFieldError(inputName, errMsg); 357 } 358 359 if (LOG.isWarnEnabled()) { 360 LOG.warn(errMsg); 361 } 362 } else if ((!allowedTypesSet.isEmpty()) && (!containsItem(allowedTypesSet, contentType))) { 363 String errMsg = getTextMessage(action, "struts.messages.error.content.type.not.allowed", new String[]{inputName, filename, file.getName(), contentType}); 364 if (validation != null) { 365 validation.addFieldError(inputName, errMsg); 366 } 367 368 if (LOG.isWarnEnabled()) { 369 LOG.warn(errMsg); 370 } 371 } else if ((!allowedExtensionsSet.isEmpty()) && (!hasAllowedExtension(allowedExtensionsSet, filename))) { 372 String errMsg = getTextMessage(action, "struts.messages.error.file.extension.not.allowed", new String[]{inputName, filename, file.getName(), contentType}); 373 if (validation != null) { 374 validation.addFieldError(inputName, errMsg); 375 } 376 377 if (LOG.isWarnEnabled()) { 378 LOG.warn(errMsg); 379 } 380 } else { 381 fileIsAcceptable = true; 382 } 383 384 return fileIsAcceptable; 385 } 386 387 private String getMaximumSizeStr(Object action) { 388 return NumberFormat.getNumberInstance(getLocaleProvider(action).getLocale()).format(maximumSize); 389 } 390 391 /** 392 * @param extensionCollection - Collection of extensions (all lowercase). 393 * @param filename - filename to check. 394 * @return true if the filename has an allowed extension, false otherwise. 395 */ 396 private boolean hasAllowedExtension(Collection<String> extensionCollection, String filename) { 397 if (filename == null) { 398 return false; 399 } 400 401 String lowercaseFilename = filename.toLowerCase(); 402 for (String extension : extensionCollection) { 403 if (lowercaseFilename.endsWith(extension)) { 404 return true; 405 } 406 } 407 408 return false; 409 } 410 411 /** 412 * @param itemCollection - Collection of string items (all lowercase). 413 * @param item - Item to search for. 414 * @return true if itemCollection contains the item, false otherwise. 415 */ 416 private boolean containsItem(Collection<String> itemCollection, String item) { 417 for (String pattern : itemCollection) 418 if (matchesWildcard(pattern, item)) 419 return true; 420 return false; 421 } 422 423 private boolean matchesWildcard(String pattern, String text) { 424 Object o = matcher.compilePattern(pattern); 425 return matcher.match(new HashMap<String, String>(), text, o); 426 } 427 428 private boolean isNonEmpty(Object[] objArray) { 429 boolean result = false; 430 for (int index = 0; index < objArray.length && !result; index++) { 431 if (objArray[index] != null) { 432 result = true; 433 } 434 } 435 return result; 436 } 437 438 protected String getTextMessage(String messageKey, String[] args) { 439 return getTextMessage(this, messageKey, args); 440 } 441 442 protected String getTextMessage(Object action, String messageKey, String[] args) { 443 if (action instanceof TextProvider) { 444 return ((TextProvider) action).getText(messageKey, args); 445 } 446 return getTextProvider(action).getText(messageKey, args); 447 } 448 449 private TextProvider getTextProvider(Object action) { 450 TextProviderFactory tpf = new TextProviderFactory(); 451 if (container != null) { 452 container.inject(tpf); 453 } 454 LocaleProvider localeProvider = getLocaleProvider(action); 455 return tpf.createInstance(action.getClass(), localeProvider); 456 } 457 458 private LocaleProvider getLocaleProvider(Object action) { 459 LocaleProvider localeProvider; 460 if (action instanceof LocaleProvider) { 461 localeProvider = (LocaleProvider) action; 462 } else { 463 localeProvider = container.getInstance(LocaleProvider.class); 464 } 465 return localeProvider; 466 } 467 468 }
时,发现doc文件中备注信息:
org.apache.struts2.interceptor.FileUploadInterceptor Interceptor that is based off of MultiPartRequestWrapper, which is automatically applied for any request that includes a file.
It adds the following parameters, where [File Name] is the name given to the file uploaded by the HTML form: •[File Name] : File - the actual File •[File Name]ContentType : String - the content type of the file •[File Name]FileName : String - the actual name of the file uploaded (not the HTML name)
4、使用io进行文件上传,需要在struts.xml定义action,并在对应的action中实现io上传
<action name="testUpload" class="com.dx.struts2.actions.UploadAction"> <result>/success.jsp</result> <result name="input">/index.jsp</result> </action>
UploadAction.java(需要在WebContent下创建文件夹files)
package com.dx.struts2.actions; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import javax.servlet.ServletContext; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class UploadAction extends ActionSupport { private static final long serialVersionUID = 1L; private File myFile; private String myFileContentType; private String myFileFileName; public File getMyFile() { return myFile; } public void setMyFile(File myFile) { this.myFile = myFile; } public String getMyFileContentType() { return myFileContentType; } public void setMyFileContentType(String myFileContentType) { this.myFileContentType = myFileContentType; } public String getMyFileFileName() { return myFileFileName; } public void setMyFileFileName(String myFileFileName) { this.myFileFileName = myFileFileName; } @Override public String execute() throws Exception { System.out.println(myFile); System.out.println(myFileContentType); System.out.println(myFileFileName); System.out.println("execute..."); ServletContext servletContext = ServletActionContext.getServletContext(); String savePath = servletContext.getRealPath("/files/" + myFileFileName); System.out.println(savePath); FileOutputStream out = new FileOutputStream(savePath); FileInputStream in = new FileInputStream(myFile); byte[] bytes = new byte[1024]; int length = 0; while ((length = in.read(bytes)) != -1) { out.write(bytes, 0, length); } out.close(); in.close(); return super.execute(); } }
-
Struts2的进行多文件上传需要操作步骤:
1、form表单修改:(需要注意的是页面其他属性File Description name需要有下标,否则无法回填)
<s:debug></s:debug> <s:form action="testUpload" method="post" enctype="multipart/form-data" theme="simple"> File:<s:file name="myFile"></s:file> File Description:<s:textfield name="desc[0]"></s:textfield> <br><br> File:<s:file name="myFile"></s:file> File Description:<s:textfield name="desc[1]"></s:textfield> <s:submit value="Submit"></s:submit> </s:form>
2、上传文件属性文件修改为List
package com.dx.struts2.actions; import java.io.File; import java.util.List; import com.opensymphony.xwork2.ActionSupport; public class UploadAction extends ActionSupport { private static final long serialVersionUID = 1L; private List<File> myFile; private List<String> myFileContentType; private List<String> myFileFileName; private List<String> desc; public List<File> getMyFile() { return myFile; } public void setMyFile(List<File> myFile) { this.myFile = myFile; } public List<String> getMyFileContentType() { return myFileContentType; } public void setMyFileContentType(List<String> myFileContentType) { this.myFileContentType = myFileContentType; } public List<String> getMyFileFileName() { return myFileFileName; } public void setMyFileFileName(List<String> myFileFileName) { this.myFileFileName = myFileFileName; } public List<String> getDesc() { return desc; } public void setDesc(List<String> desc) { this.desc = desc; } @Override public String execute() throws Exception { System.out.println(myFile); System.out.println(myFileContentType); System.out.println(myFileFileName); System.out.println(desc); System.out.println("execute..."); return super.execute(); } }
3、提交页面后,后台打印信息:
[D:\Work\Java\apache-tomcat-7.0.75-windows-x64\apache-tomcat-7.0.75\work\Catalina\localhost\Struts_07FileUpload\upload_c2e431f2_8b1a_4aa7_a1d6_ae448d1dddb1_00000004.tmp,
D:\Work\Java\apache-tomcat-7.0.75-windows-x64\apache-tomcat-7.0.75\work\Catalina\localhost\Struts_07FileUpload\upload_c2e431f2_8b1a_4aa7_a1d6_ae448d1dddb1_00000006.tmp] [image/jpeg, image/jpeg] [1.jpg, 2.jpg] [a, b] execute...
-
如何对上传文件的错误信息进行国际化
当我们查看fileUpload拦截器源代码时,会发现其doc文件中写着以下信息:
This interceptor will add several field errors, assuming that the action implements ValidationAware.
These error messages are based on several i18n values stored in struts-messages.properties, a default i18n file processed for all i18n requests.
You can override the text of these messages by providing text for the following keys: •struts.messages.error.uploading - a general error that occurs when the file could not be uploaded •struts.messages.error.file.too.large - occurs when the uploaded file is too large •struts.messages.error.content.type.not.allowed - occurs when the uploaded file does not match the expected content types specified •struts.messages.error.file.extension.not.allowed - occurs when the uploaded file does not match the expected file extensions specified
因此,可以在src下创建i18n.properties文件,并在文件内容定义:
struts.messages.error.uploading="" struts.messages.error.file.too.large="" struts.messages.error.content.type.not.allowed="" struts.messages.error.file.extension.not.allowed=""
在struts.xml中定义国际化设置
<constant name="struts.custom.i18n.resources" value="i18n"></constant>
还可以参考struts-core.jar下的org.apache.struts2包下的struts-messages.properties文件中的message信息:
struts.messages.error.uploading=Error uploading: {0} struts.messages.error.file.too.large=File {0} is too large to be uploaded. Maximum allowed size is {4} bytes! struts.messages.error.content.type.not.allowed=Content-Type not allowed: {0} "{1}" "{2}" {3} struts.messages.error.file.extension.not.allowed=File extension not allowed: {0} "{1}" "{2}" {3}
-
如何对上传文件限定,大小、文件内容类型、扩展名以及总文件大小显示修改
当我们查看fileUpload拦截器源代码时,会发现其doc文件中写着以下信息:
Interceptor parameters: •maximumSize (optional) - the maximum size (in bytes) that the interceptor will allow a file reference to be set on the action. Note, this is not related to the various properties found in struts.properties. Default to approximately 2MB. •allowedTypes (optional) - a comma separated list of content types (ie: text/html) that the interceptor will allow a file reference to be set on the action. If none is specified allow all types to be uploaded. •allowedExtensions (optional) - a comma separated list of file extensions (ie: .html) that the interceptor will allow a file reference to be set on the action. If none is specified allow all extensions to be uploaded. Extending the interceptor: You can extend this interceptor and override the acceptFile method to provide more control over which files are supported and which are not. Example code: <action name="doUpload" class="com.example.UploadAction"> <interceptor-ref name="fileUpload"/> <interceptor-ref name="basicStack"/> <result name="success">good_result.jsp</result> </action>
我们可以通过重写fileUpload拦截器的maximumSize 、allowedTypes 、allowedExtensions 三个字段来设置参数,具体操作修改struts.xml
<interceptors> <interceptor-stack name="myInterceptorStack"> <interceptor-ref name="defaultStack"> <param name="fileUpload.maximumSize">2000</param> <param name="fileUpload.allowedTypes">text/html,text/xml</param> <param name="fileUpload.allowedExtensions">html,dtd,xml</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="myInterceptorStack"></default-interceptor-ref>
重写总文件大小限定,总文件大小设置在struts-core.jar下的org.apache.struts2包下的default.properties文件中:
struts.multipart.maxSize=2097152
可以通过在struts.xml中定义常量来覆盖:
<constant name="struts.multipart.maxSize" value="20971520"></constant>
基础才是编程人员应该深入研究的问题,比如:
1)List/Set/Map内部组成原理|区别
2)mysql索引存储结构&如何调优/b-tree特点、计算复杂度及影响复杂度的因素。。。
3)JVM运行组成与原理及调优
4)Java类加载器运行原理
5)Java中GC过程原理|使用的回收算法原理
6)Redis中hash一致性实现及与hash其他区别
7)Java多线程、线程池开发、管理Lock与Synchroined区别
8)Spring IOC/AOP 原理;加载过程的。。。
【+加关注】。