Tutorial: ExtJS 4 File Upload (Upload de Arquivo) + Spring MVC 3

18 Jul 2011
3 mins read

Este tutorial tem como objetivo mostrar como fazer upload de arquivo com Ext JS 4 e Spring MVC 3.

Este tutorial é um update do Tutorial: Upload de Arquivo com ExtJS e Spring Framework, implementado com Ext JS 3 e Spring MVC 2.5.

Ext JS File Upload Form

Primeiro, vamos precisar implementar o form de upload de arquivo do Ext JS 4, similar ao mostrado no Ext JS 4 docs.

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
Ext.onReady(function(){

Ext.create('Ext.form.Panel', {
title: 'File Uploader',
width: 400,
bodyPadding: 10,
frame: true,
renderTo: 'fi-form',
items: [{
xtype: 'filefield',
name: 'file',
fieldLabel: 'File',
labelWidth: 50,
msgTarget: 'side',
allowBlank: false,
anchor: '100%',
buttonText: 'Select a File...'
}],

buttons: [{
text: 'Upload',
handler: function() {
var form = this.up('form').getForm();
if(form.isValid()){
form.submit({
url: 'upload.action',
waitMsg: 'Uploading your file...',
success: function(fp, o) {
Ext.Msg.alert('Success', 'Your file has been uploaded.');
}
});
}
}
}]
});
});
[/code]

HTML Page

Depois precisamos implementar uma página HTML para renderizar o form. Essa página também contém os imports JS necessários:

[code lang="html" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<html>
<head>
<title>Spring FileUpload Example with ExtJS 4 Form</title>

<!-- Ext JS Files -->
<link rel="stylesheet" type="text/css" href="/extjs4-file-upload-spring/extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="/extjs4-file-upload-spring/extjs/bootstrap.js"></script>

<!-- file upload form -->
<script src="/extjs4-file-upload-spring/js/file-upload.js"></script>

</head>
<body>

<p>Click on "Browse" button (image) to select a file and click on Upload button</p>

<div id="fi-form" style="padding:25px;"></div>
</body>
</html>
[/code]

FileUpload Bean

No lado Java, precisamos de um bean para representar o arquivo:

[code lang="java" firstline="1" toolbar="true" collapse="false" wraplines="false"]
package com.loiane.model;

import org.springframework.web.multipart.commons.CommonsMultipartFile;

/**
* Represents file uploaded from extjs form
*
* @author Loiane Groner
* https://loiane.com
* http://loianegroner.com
*/
public class FileUploadBean {

private CommonsMultipartFile file;

public CommonsMultipartFile getFile() {
return file;
}

public void setFile(CommonsMultipartFile file) {
this.file = file;
}
}
[/code]

File Upload Controller

E também precisamos de um controller. Este foi implementado com Spring MVC 3:

[code lang="java" firstline="1" toolbar="true" collapse="false" wraplines="false"]
package com.loiane.controller;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.loiane.model.ExtJSFormResult;
import com.loiane.model.FileUploadBean;

/**
* Controller - Spring
*
* @author Loiane Groner
* https://loiane.com
* http://loianegroner.com
*/
@Controller
@RequestMapping(value = "/upload.action")
public class FileUploadController {

@RequestMapping(method = RequestMethod.POST)
public @ResponseBody String create(FileUploadBean uploadItem, BindingResult result){

ExtJSFormResult extjsFormResult = new ExtJSFormResult();

if (result.hasErrors()){
for(ObjectError error : result.getAllErrors()){
System.err.println("Error: " + error.getCode() +" - " + error.getDefaultMessage());
}

//set extjs return - error
extjsFormResult.setSuccess(false);

return extjsFormResult.toString();
}

// Some type of file processing...
System.err.println("-------------------------------------------");
System.err.println("Test upload: " + uploadItem.getFile().getOriginalFilename());
System.err.println("-------------------------------------------");

//set extjs return - sucsess
extjsFormResult.setSuccess(true);

return extjsFormResult.toString();

}
[/code]

Ext JS Form Return

Algumas pessoas me perguntaram como fazer para retornar uma mensagem para o Ext JS. A única coisa que precisamos retornar é uma propriedade boolean chamada success dizendo se tudo ocorreu bem ou não:

[code lang="java" firstline="1" toolbar="true" collapse="false" wraplines="false"]
package com.loiane.model;

/**
* A simple return message for Ext JS
*
* @author Loiane Groner
* https://loiane.com
* http://loianegroner.com
*/
public class ExtJSFormResult {

private boolean success;

public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}

public String toString(){
return "{success:"+this.success+"}";
}
}
[/code]

Spring Config

Não podemos esquecer de configurar o arquivo spring também:

[code lang="xml" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<!-- Configure the multipart resolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="100000"/>
</bean>
[/code]

NullPointerException

Também recebi algumas perguntas sobre NullPointerException. Tenha certeza de que o campo fileupload do Ext JS tenha o mesmo nome da propriedade CommonsMultipartFile  da classe FileUploadBean:

ExtJS:

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false" highlight="3"]
{
xtype: 'filefield',
name: 'file',
fieldLabel: 'File',
labelWidth: 50,
msgTarget: 'side',
allowBlank: false,
anchor: '100%',
buttonText: 'Select a File...'
}
[/code]

Java:

[code lang="java" firstline="1" toolbar="true" collapse="false" wraplines="false" highlight="3"]
public class FileUploadBean {

private CommonsMultipartFile file;
}
[/code]

O nome dessas propriedades SEMPRE precisam ser o MESMO!

Se quiser usar Ext JS 3 com Spring 3 ou Ext JS 4 com Spring 2.5, fique à vontade para fazer merge dos códigos. Os tutoriais são compatíveis, apenas fiz um upgrade na versão dos frameworks!

Download

Você fazer o download do código fonte completo no meu repositório Github (pode fazer um clone ou clicar no botão download no canto direito superior da página do projeto): https://github.com/loiane/extjs4-file-upload-spring

Ou também pode fazer download a partir do repositório no Google Code: http://code.google.com/p/extjs4-file-upload-spring/

Os dois repositórios possuem o mesmo código fonte. O Google Code é apenas umas alternativa.

Bons códigos!