pondělí, dubna 14, 2008

Grails a Service Layer

Jedním z pilířů frameworku Grails je SpringFramework. Jeho možnosti jsou integrovány na různých místech Grails frameworku. Dneska se podíváme na tzv. “Service Layer”. Kdo Spring Framework někdy použil, tak s velkou určitostí využil jeho možnost tvorby instancí objektů. Tato vlastnost je označována zkratkou IOC(inversion of control). Jednoduše řečeno, Spring vám vytvoří a udržuje objekty s různou “životností” jako je singleton, request, session atp.
Při použití v Javě většinou musíme vytvořit samotnou třídu a její XML deklaraci pro Spring.

V Grailsech je tato Spring infrastruktura dostupná a Groovy je použit jako DSL. Použití je jednoduché. V adresáři projektu Grails vytvoříme Service objekt, který v sobě ponese jak kód samotný, tak i konfiguraci.

Prázdný soubor pro nově definvanou službu vytvoříme takto:

grails create-service FileStorage

Samotná služba může vypadat například takto:(komentáře jsou vloženy do kódu)

// jelikož si Grails s JAVOU velmi dobře rozumí, můžeme přímo importovat JAVA knihovny
import org.springframework.web.multipart.MultipartFile
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.codehaus.groovy.grails.commons.ConfigurationHolder

class FileStorageService {
// služba může být transakčně oddělena od zbytku kódum nyní to ale nevyužijeme
boolean transactional = false
// Grails nám danou službu mohou vytvořet s různou životností: session, prototype, flash, singleton ...
static scope = 'singleton'

// A zde už máme samotné metody služby
// store file into directory
def add_to_store(MultipartFile file, String file_path, String file_name) {
def full_path=ConfigurationHolder.config.fileStorage.uploadDir+”\\”+file_path
def d2= new File(full_path)
d2.mkdirs()
file.transferTo(new File(full_path+”\\”+file_name))
}

// remove file from storage
def remove_from_store(String file_path){
def f=new File(ConfigurationHolder.config.fileStorage.uploadDir+”\\”+file_path)
if (f.exists()){
f.delete()
}
}

// download file
def downloadFile(String file_name, String file_path, response){
response.setContentType(”application/x-download”);
response.setHeader(”Content-disposition”, “attachment; filename=” +file_name);
def f=new File(ConfigurationHolder.config.fileStorage.uploadDir+”\\”+file_path)
f.withInputStream{response.outputStream << it}
}
}