Tutorial: ExtJS 4 File Upload (Upload de Arquivo) + Spring MVC 3
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.
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.');
}
});
}
}
}]
});
});
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:
<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>
FileUpload Bean
No lado Java, precisamos de um bean para representar o arquivo:
package com.loiane.model;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
/**
* Represents file uploaded from extjs form
*
* @author Loiane Groner
* http://loiane.com
* http://loianegroner.com
*/
public class FileUploadBean {
private CommonsMultipartFile file;
public CommonsMultipartFile getFile() {
return file;
}
public void setFile(CommonsMultipartFile file) {
this.file = file;
}
}
File Upload Controller
E também precisamos de um controller. Este foi implementado com Spring MVC 3:
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
* http://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();
}
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:
package com.loiane.model;
/**
* A simple return message for Ext JS
*
* @author Loiane Groner
* http://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+"}";
}
}
Spring Config
Não podemos esquecer de configurar o arquivo spring também:
<!-- 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>
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:
{
xtype: 'filefield',
name: 'file',
fieldLabel: 'File',
labelWidth: 50,
msgTarget: 'side',
allowBlank: false,
anchor: '100%',
buttonText: 'Select a File...'
}
Java:
public class FileUploadBean {
private CommonsMultipartFile file;
}
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!










Em que pasta é salvo o arquivo… e no caso de ser uma imagem como mostrar essa imagem na aplicação?
No código atual apenas mostramos no console o nome do arquivo, não salvamos em nenhum lugar. Se desejar, você precisa adicionar essa lógica.
O mesmo para mostrar imagem na aplicação. Isso você pode fazer de duas formas: a primeira seria mostrar antes de fazer upload, mas aí entraria problemas de compatibilidade entre browsers. Ou você pode salvar a imagem em banco e depois fazer o retrieval/select e mostrar na aplicação. Vou ver se faço um tutorial sobre isso no futuro.
Hi, very nice tutorial.
I’ve tried to contact you by mail, but with no success.
I’m sorry I don’t know if it is the right way, but I’m contacting you directly.Maybe you’ve seen some of my messages / posts in the Sencha forum.
I’m struggling with using the new system MVC + a CRUD and a ‘hasMany’ ‘belongsTo’ relationships.
Here’s what I’m trying to do:
Display a list of partners, with 3 buttons : “create”, “edit” and “delete”.Sounds “classical”!When the user presses “create”, open a modal windows which display informations about a partner.
In these informations, there should be a list of products: a partner hasMany products.
That’s where I’m stuck.
I’ve been trying for 5 days now to find how I could deal with this.In the examples, in the help, and in the forum, it’s always the same: just a small sample with no ‘hasMany’ ‘belongsTo’ relationships, whereas this is the heart of the database.
May I ask you if you have any idea of where I could take a look, or if you could take a look at what I’ve done (I think it’s pretty straightforward (I’m 100% for K.I.S.S. methods)) and tell me what I should do / where I should change something to make it work… I’m so close but… nothing works, so I’m so far actually!!
Thank you very much indeed,
Kind regards,– Olivier Pons
Hi Oliver,
I´m having issues with my email.
Can you pls post a sample of your code?
Olá Loiane
Consegui resolver o problema da pasta… obrigado. Só que parece que existe um problema ao tentar enviar um json como resposta a requisição do upload. No site da sencha ele falam que essa requisição não é ajax e sim criam dinamicamente um iframe para enviar, e deve ser usado o método hasUpload para fazer algo que não entendi. Vc já testou isso?
Grande abraço
Seu posts são excelentes
Olá Sanderson,
Obrigada!
Para enviar uma resposta, só precisa do success mesmo.
Se quiser enviar uma mensagem a mais, tem que fazer algo mais complexo.
Vou ver se faço um exemplo e posto aqui no blog.
[]‘s
Olá Loiane,
Estou usando o upload de arquivos do EXT JS 3.
Você conhece alguma forma de valiadar o tamanho do arquivo antes do envio, isto é, uma validação cliente side ?
desde já, obrigado pela atenção
Olá Ado,
Vc precisa fazer essa validação com javascript.
Dê uma olhada nesse post: http://stackoverflow.com/questions/3717793/javascript-file-upload-size-validation
[]‘s
Loiane, é possivel fazer esse envio utilizando o store?
e depois sincronizando ele com
store.sync();
Oi Flavio, infelizmente não.
Na store só pode os tipos primitivos do JS.
[]‘s
Olá, Loiane,
Teria algum exemplo parecido com este, que por exemplo faz upload de uma arquivo xls e insere no Banco de Dados.
Obrigado Pela Atenção.
Oi Alphak,
Não tenho esse exemplo.
[]‘s