Download - Brutos MVC

Transcript

Brutos Application Brutos Application FrameworkFramework

Um controlador MVCUm controlador MVC

SumárioSumário

►O que é?O que é?►Quais as vantagens em utilizá-lo?Quais as vantagens em utilizá-lo?►Como obter o Brutos Framework??► Como configurá-lo?Como configurá-lo?►Definindo controladores.Definindo controladores.►Definindo ações.Definindo ações.►Definindo interceptores.Definindo interceptores.► Tratando exceções.Tratando exceções.►Mapeamento de beans.Mapeamento de beans.

O que é?O que é?

O Brutos application framework é um controlador MVC O Brutos application framework é um controlador MVC desenvolvido em Java. Projetado para reduzir a complexidade desenvolvido em Java. Projetado para reduzir a complexidade do desenvolvimento web, com mapeamento configurável, do desenvolvimento web, com mapeamento configurável, resolução de vista, bem como suporte ao upload e download resolução de vista, bem como suporte ao upload e download de arquivos. Podendo ser configurado usando XML, anotações de arquivos. Podendo ser configurado usando XML, anotações e CoC.e CoC.

O framework segue os seguintes princípios:O framework segue os seguintes princípios:• flexibilidade;flexibilidade;• baixo acoplamento ebaixo acoplamento e• produtividade.produtividade.

Quais as vantagens em Quais as vantagens em utilizá-lo?utilizá-lo?

►Baixo acoplamento. Baixo acoplamento. ►Geração de componentes testáveis.Geração de componentes testáveis.►Suporte avançado de mapeamento.Suporte avançado de mapeamento.►Fácil aprendizado.Fácil aprendizado.

Como obter o Brutos Framework??

Os pacotes de liberação estão hospedados no sistema de arquivos Os pacotes de liberação estão hospedados no sistema de arquivos da SourceForge em formato ZIP. Cada pacote contém jars, da SourceForge em formato ZIP. Cada pacote contém jars, exemplos, código fonte e entre outros. Seu download pode ser feito exemplos, código fonte e entre outros. Seu download pode ser feito a partir da url http://sourceforge.net/projects/brutos/files/brutos/.a partir da url http://sourceforge.net/projects/brutos/files/brutos/.

Obtendo o pacote Obtendo o pacote

Repositório de artefatos Maven. Repositório de artefatos Maven. São produzidos uma série de artefatos sob o groupId org.brandao.São produzidos uma série de artefatos sob o groupId org.brandao.brutos-core: brutos-core: O artefato principal, necessário para construir O artefato principal, necessário para construir aplicações usando o Brutos APIs nativo.aplicações usando o Brutos APIs nativo.brutos-annotation: brutos-annotation: Artefato opcional que permite a construção de Artefato opcional que permite a construção de aplicações usando anotações. Este artefato depende do brutos-core.aplicações usando anotações. Este artefato depende do brutos-core.brutos-web: brutos-web: Artefato opcional que permite a construção de Artefato opcional que permite a construção de aplicações web.aplicações web.Este artefato depende do brutos-core.Este artefato depende do brutos-core.O repositório oficial do Brutos Framework é O repositório oficial do Brutos Framework é http://www.brutosframework.com.br/maven/2http://www.brutosframework.com.br/maven/2..

Como configurá-lo?Como configurá-lo?

<listener><listener> <listener-class>org.brandao.brutos.web.ContextLoaderListener</listener-class><listener-class>org.brandao.brutos.web.ContextLoaderListener</listener-class></listener></listener>

Registrar o listener no web.xmlRegistrar o listener no web.xml

Registrar o filtro no web.xmlRegistrar o filtro no web.xml<filter><filter> <filter-name>Brutos Framework Filter</filter-name><filter-name>Brutos Framework Filter</filter-name> <filter-class>org.brandao.brutos.web.http.BrutosRequestFilter</filter-class><filter-class>org.brandao.brutos.web.http.BrutosRequestFilter</filter-class> </filter></filter> <filter-mapping><filter-mapping> <filter-name>Brutos Framework Filter</filter-name><filter-name>Brutos Framework Filter</filter-name> <url-pattern>*</url-pattern><url-pattern>*</url-pattern> <dispatcher>REQUEST</dispatcher><dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher><dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher><dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher><dispatcher>ERROR</dispatcher> </filter-mapping></filter-mapping>

Atenção: Se estiver sendo usado um container que suporte a especificação Servlet 3.0, o registro do ContextLoadListener e DispatcherServlet ou BrutosRequestFilter não serão necessários. Eles serão automaticamente registrados.

Definindo controladores.Definindo controladores.

public class SampleController {

...

}

Um controlador pode ser definido de três formas diferentes:Um controlador pode ser definido de três formas diferentes:• seguindo a nomenclatura <nome do controlador>Controller ao definir o nome da seguindo a nomenclatura <nome do controlador>Controller ao definir o nome da classe;classe;• usando a anotação @Controller ouusando a anotação @Controller ou• usando o elemento <controller/> do schema brutos-controllers.xsd.usando o elemento <controller/> do schema brutos-controllers.xsd.

• vistavista: /WEB-INF/samplecontroller/index.jsp: /WEB-INF/samplecontroller/index.jsp• URIURI: /sample: /sample

Definindo controladores.Definindo controladores.@Controllerpublic class Sample {

...

}

• vistavista: /WEB-INF/samplecontroller/index.jsp: /WEB-INF/samplecontroller/index.jsp• URIURI: /sample: /sample

Definindo controladores.Definindo controladores.

<controller id=“/controller” class=“Sample”> ...</controller>

• vistavista: /WEB-INF/sample/index.jsp: /WEB-INF/sample/index.jsp• URIURI: /controller: /controller

public class Sample {

...

}

Definindo ações.Definindo ações.

public class SampleController {

public void testAction() { ... }

}

Uma ação pode ser definida de três formas diferentes:Uma ação pode ser definida de três formas diferentes:• seguindo a nomenclatura <nome da ação>Action ao definir o nome do método;seguindo a nomenclatura <nome da ação>Action ao definir o nome do método;• usando a anotação @Action ouusando a anotação @Action ou• usando o elemento <action/> do schema brutos-controllers.xsd.usando o elemento <action/> do schema brutos-controllers.xsd.

• vistavista: /WEB-INF/samplecontroller/testAction/index.jsp: /WEB-INF/samplecontroller/testAction/index.jsp• URIURI: /sample/test: /sample/test

Definindo ações.Definindo ações.public class SampleController {

@Action public void test() { ... }

}

• vistavista: /WEB-INF/samplecontroller/testAction/index.jsp: /WEB-INF/samplecontroller/testAction/index.jsp• URIURI: /sample/test: /sample/test

Definindo ações.Definindo ações.

• vistavista: /WEB-INF/samplecontroller/test.jsp: /WEB-INF/samplecontroller/test.jsp• URIURI: /controller/test: /controller/test

@Action(value=“/test”, view=@View(“test”))public class SampleController {

}

Definindo ações.Definindo ações.

<controller id=“/controller” class=“Sample”> <action id=“/test” executor=“test”/></controller>

• vistavista: /WEB-INF/sample/testAction/index.jsp: /WEB-INF/sample/testAction/index.jsp• URIURI: /controller/test: /controller/test

public class Sample {

public void test() { ... }

}

Definindo Interceptores.Definindo Interceptores.

public class SampleInterceptorInterceptorController extends AbstractInterceptor {

public void intercepted(InterceptorStack stack, InterceptorHandler handler) throws InterceptedException {

...

}

}

Um interceptor pode ser definido de três formas diferentes:Um interceptor pode ser definido de três formas diferentes:• seguindo a nomenclatura <nome do interceptor>interceptorController ao definir o seguindo a nomenclatura <nome do interceptor>interceptorController ao definir o nome da classe;nome da classe;• usando a anotação @Intercepts ouusando a anotação @Intercepts ou• usando o elemento <interceptor/> do schema brutos-controllers.xsd.usando o elemento <interceptor/> do schema brutos-controllers.xsd.ObsObs::Um interceptor obrigatoriamente tem que implementar a interface Um interceptor obrigatoriamente tem que implementar a interface InterceptorController.InterceptorController.Para interceptar a execução de um controlador, basta usar a anotação @InterceptedBy Para interceptar a execução de um controlador, basta usar a anotação @InterceptedBy nele ou usar o elemento <interceptor-ref/> do schema brutos-controllers.xsd.nele ou usar o elemento <interceptor-ref/> do schema brutos-controllers.xsd.

Definindo Interceptores.Definindo Interceptores.

@Interceptspublic class SampleInterceptor extends AbstractInterceptor {

public void intercepted(InterceptorStack stack, InterceptorHandler handler) throws InterceptedException {

...

}

}

Definindo Interceptores.Definindo Interceptores.

<interceptors> <interceptor name=“sample” class=“SampleInterceptor”/></interceptors>

public class SampleInterceptor extends AbstractInterceptor {

public void intercepted(InterceptorStack stack, InterceptorHandler handler) throws InterceptedException {

...

}

}

Tratando exceções.Tratando exceções.Um exceção pode ser interceptada e tratada de três formas diferentes:Um exceção pode ser interceptada e tratada de três formas diferentes:• apenas declarando a no método;apenas declarando a no método;• usando a anotação @TrowSafe em nível de classe ou método;usando a anotação @TrowSafe em nível de classe ou método;• usando o elemento <throw-safe/> do schema brutos-controllers.xsd.usando o elemento <throw-safe/> do schema brutos-controllers.xsd.

public class SampleController {

public void testAction() throws NullPointerException{ ... }

}

• vista da açãovista da ação: /WEB-INF/samplecontroller/testAction/index.jsp: /WEB-INF/samplecontroller/testAction/index.jsp• URI da açãoURI da ação: /sample/test: /sample/test• vista da exceçãovista da exceção: /WEB-INF/samplecontroller/testAction/nullpointerexception.jsp: /WEB-INF/samplecontroller/testAction/nullpointerexception.jsp

Tratando exceções.Tratando exceções.public class SampleController {

@ThrowSafe(target=NullPointerException.class, view=“npe”) public void testAction() { ... }

}

• vista da açãovista da ação: /WEB-INF/samplecontroller/testAction/index.jsp: /WEB-INF/samplecontroller/testAction/index.jsp• URI da açãoURI da ação: /sample/test: /sample/test• vista da exceçãovista da exceção: /WEB-INF/samplecontroller/testAction/npe.jsp: /WEB-INF/samplecontroller/testAction/npe.jsp

Tratando exceções.Tratando exceções.@ThrowSafe(target=NullPointerException.class, view=“npeController”)public class SampleController {

public void testAction() { ... }

}

• vista da açãovista da ação: /WEB-INF/samplecontroller/testAction/index.jsp: /WEB-INF/samplecontroller/testAction/index.jsp• URI da açãoURI da ação: /sample/test: /sample/test• vista da exceçãovista da exceção: /WEB-INF/samplecontroller/npeController.jsp: /WEB-INF/samplecontroller/npeController.jsp

Tratando exceções.Tratando exceções.public class SampleController {

public void testAction() { ... }

}

• vista da açãovista da ação: /WEB-INF/samplecontroller/testAction/index.jsp: /WEB-INF/samplecontroller/testAction/index.jsp• URI da açãoURI da ação: /sample/test: /sample/test• vista da exceçãovista da exceção: /WEB-INF/samplecontroller/testAction/nullpointerexception.jsp: /WEB-INF/samplecontroller/testAction/nullpointerexception.jsp

<controller id=“/controller” class=“Sample”> <action id=“/test” executor=“test”/></controller>

Mapeamento de beans.Mapeamento de beans.

►Mapeamento de propriedades. Mapeamento de propriedades. ►Mapeamento de construtores.Mapeamento de construtores.►Mapeamento de parâmetros de uma ação.Mapeamento de parâmetros de uma ação.►Mapeamento de enumeração (Enum).Mapeamento de enumeração (Enum).►Mapeamento de datas (Date e Calendar).Mapeamento de datas (Date e Calendar).►Mapeamento de coleções (Collection).Mapeamento de coleções (Collection).►Mapeamento de mapas (Map).Mapeamento de mapas (Map).►Mapeamento de arquivos (File).Mapeamento de arquivos (File).►Mapeamento de polimorfismos.Mapeamento de polimorfismos.

Mapeamento de Mapeamento de propriedades.propriedades.

public class SampleController {

private Integer property;

}

JavaJava ParâmetroParâmetro

SampleController.property property

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property”></form>

VistaVista

MapeamentoMapeamento

Mapeamento de Mapeamento de propriedades.propriedades.

public class SampleController {

@Basic(bean=“prop1”) private Integer property;

}

JavaJava ParâmetroParâmetro

SampleController.property prop1

ControladorControlador

<form action=“/sample” method=“post”> <input type=“text” name=“prop1”></form>

VistaVista

MapeamentoMapeamento

Mapeamento de Mapeamento de propriedades.propriedades.

public class SampleController {

private Integer property;

@Basic(bean=“prop1”) public Integer getProperty(){ return this.property; }

}

JavaJava ParâmetroParâmetro

SampleController.property prop1

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“prop1”></form>

VistaVista

MapeamentoMapeamento

Mapeamento de Mapeamento de construtores.construtores.

public class SampleBean {

@Transient private Integer property;

public SampleBean(@Basic(bean=“prop1”) Integer property){ this.property = property; }

}

BeanBean

public class SampleController {

private SampleBean property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property.prop1”></form>

VistaVista

JavaJava ParâmetroParâmetro

SampleController.property.property property.prop1

MapeamentoMapeamento

Mapeamento de parâmetros de uma Mapeamento de parâmetros de uma ação.ação.

public class SampleController {

public void testAction(@Basic(bean=“prop1”) Integer property){ ... }

}

JavaJava ParâmetroParâmetro

SampleController.testAction[property] prop1

ControladorControlador

<form action=“/sample/test” method=“post”> <input type=“text” name=“prop1”></form>

VistaVista

MapeamentoMapeamento

Mapeamento de parâmetros de uma Mapeamento de parâmetros de uma ação.ação.

public class SampleBean {

@Basic(bean=“prop1”) private Integer property1;

}

BeanBean

public class SampleController {

public void testAction(@Basic(bean=“property”) SampleBean property){ ... }}

ControladorControlador

<form target=“/sample/test” method=“post”> <input type=“text” name=“property.prop1”></form>

VistaVista

JavaJava ParâmetroParâmetro

SampleController.testAction[property.property1]

property.prop1

MapeamentoMapeamento

Mapeamento de enumeração Mapeamento de enumeração (Enum).(Enum).

public enum SampleEnum { VALUE1, VALUE2;}

EnumeraçãoEnumeração

public class SampleController {

private SampleEnum property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property 0 SimpleEnum.VALUE1

SampleController.property

Property VALUE2 SimpleEnum.VALUE2

MapeamentoMapeamento

Mapeamento de enumeração Mapeamento de enumeração (Enum).(Enum).

public enum SampleEnum { VALUE1, VALUE2;}

EnumeraçãoEnumeração

public class SampleController {

@Enumerated(EnumerationType.ORDINAL) private SampleEnum property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property” value=“0”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property 0 SimpleEnum.VALUE1

MapeamentoMapeamento

Mapeamento de enumeração Mapeamento de enumeração (Enum).(Enum).

public enum SampleEnum { VALUE1, VALUE2;}

EnumeraçãoEnumeração

public class SampleController {

@Enumerated(EnumerationType.STRING) private SampleEnum property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property” value=“VALUE1”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property VALUE1 SimpleEnum.VALUE1

MapeamentoMapeamento

Mapeamento de datas (Date e Mapeamento de datas (Date e Calendar).Calendar).

public class SampleController {

private Date property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property” value=“29/08/1984”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property 29/08/1984 Date (29 August 1984)

MapeamentoMapeamento

Mapeamento de datas (Date e Mapeamento de datas (Date e Calendar).Calendar).

public class SampleController {

@Temporal(“yyyy-MM-dd”) private Date property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property” value=“1984-08-29”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property 1984-08-29 Date (29 August 1984)

MapeamentoMapeamento

Mapeamento de coleções Mapeamento de coleções (Collection).(Collection).

public class SampleController {

private List<Integer> property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property.element[0]” value=“1”> <input type=“text” name=“property.element[1]” value=“7”> <input type=“text” name=“property.element[2]” value=“5”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property.element[0] 1

ArrayList(1,7,5)property.element[1] 7

property.element[2] 5

MapeamentoMapeamento

Mapeamento de coleções Mapeamento de coleções (Collection).(Collection).

public class SampleController {

private List<SampleBean> property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property.element[0].intList.element[0]” value=“1”> <input type=“text” name=“property.element[1].intList.element[0]” value=“7”> <input type=“text” name=“property.element[1].intList.element[1]” value=“5”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property.element[0].intList.element[0]

1 ArrayList[SampleBean(intList=ArrayList[1]),SampleBean(intList=ArrayList[7,5])]

property.element[1].intList.element[0]

7

property.element[1].intList.element[1]

5

MapeamentoMapeamento

public class SampleBean {

private List<Integer> intList;

}

BeanBean

Mapeamento de mapas (Map).Mapeamento de mapas (Map).

public class SampleController {

private Map<String,Integer> property;

}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property.key[0]” value=“x1”> <input type=“text” name=“property.element[0]” value=“1”> <input type=“text” name=“property.key[1]” value=“x2”> <input type=“text” name=“property.element[1]” value=“7”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property.key[0] x1HashMap( “x1”=>1, “x2”=>7)

property.element[0] 1

property.key[1] x2

property.element[1] 7

MapeamentoMapeamento

Mapeamento de mapas (Map).Mapeamento de mapas (Map).

public class SampleController {

private Map<SampleBean,String> property;}

ControladorControlador

<form target=“/sample” method=“post”> <input type=“text” name=“property.key[0].intList.element[0]” value=“1”> <input type=“text” name=“property.element[0] value=“x1”> <input type=“text” name=“property.key[1].intList.element[0]” value=“5”> <input type=“text” name=“property.element[1]” value=“x2”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property.key[0].intList.element[0]

1HashMap[SampleBean(intList=ArrayList[1])=>”x1”,SampleBean(intList=ArrayList[5])=>”x2”]

property.element[0] x1

property.key[1].intList.element[0]

5

property.element[1] x2

MapeamentoMapeamento

public class SampleBean {

private List<Integer> intList;}

BeanBean

Mapeamento de arquivos (File).Mapeamento de arquivos (File).

public class SampleController {

private File property;

}

ControladorControlador

<form target=“/sample” method=“post” enctype="multipart/form-data"> <input type=“file” name=“property” ></form>

VistaVista

JavaJava ParâmetrParâmetroo

ValorValor ObjetoObjeto

SampleController.property

property <binary-data> File

MapeamentoMapeamento

Mapeamento de arquivos (File).Mapeamento de arquivos (File).

public class SampleController {

private List<File> property;

}

ControladorControlador

<form target=“/sample” method=“post” enctype="multipart/form-data"> <input type=“file” name=“property[0]” > <input type=“file” name=“property[1]” ></form>

VistaVista

JavaJava ParâmetrParâmetroo

ValorValor ObjetoObjeto

SampleController.property

property[0] <binary-data>ArrayList[File,File]

property[1] <binary-data>

MapeamentoMapeamento

Mapeamento de arquivos (File).Mapeamento de arquivos (File).

public class SampleController {

@Type(ListType.class) private List<File> property;

}

ControladorControlador

<form target=“/sample” method=“post” enctype="multipart/form-data"> <input type=“file” name=“property” > <input type=“file” name=“property” ></form>

VistaVista

JavaJava ParâmetrParâmetroo

ValorValor ObjetoObjeto

SampleController.property

property <binary-data>ArrayList[File,File]

Property <binary-data>

MapeamentoMapeamento

Mapeamento de arquivos (File).Mapeamento de arquivos (File).

public class SampleController {

private UploadedFile property;

}

ControladorControlador

<form target=“/sample” method=“post” enctype="multipart/form-data"> <input type=“file” name=“property” ></form>

VistaVista

JavaJava ParâmetrParâmetroo

ValorValor ObjetoObjeto

SampleController.property

property <binary-data> UploadedFile

MapeamentoMapeamento

Mapeamento de arquivos (File).Mapeamento de arquivos (File).

public class SampleController {

private File property;

private String description;

}

ControladorControlador

<form target=“/sample” method=“post” enctype="multipart/form-data"> <input type=“file” name=“property”> <input type=“text” name=“description” value=“Descrição”></form>

VistaVista

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property property <binary-data> File

SampleController.description description Descrição String(“Description”)

MapeamentoMapeamento

Mapeamento de polimorfismos.Mapeamento de polimorfismos.BeansBeanspublic interface Property {

String getName();

}

public abstract class AbstractProperty {

private String name;

public String getName(){ return his.name }

}

public class DecimalProperty extends AbstractProperty{

private Integer length; private Integer decimals; ...}

public class SetProperty extends AbstractProperty{

private List<String> values; ...}

Mapeamento de polimorfismos.Mapeamento de polimorfismos.ControladorControlador

public class SampleController {

@Any( metaBean=@Basic(bean=“propertyType”), metaType=String.class, metaValues={ @MetaValue(value=“decimal”, target=DecimalProperty.class), @MetaValue(value=“set”, target=SetProperty.class) } ) private Property property;

}

Mapeamento de polimorfismos.Mapeamento de polimorfismos.

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property.propertyType

decimalDecimalProperty( length=10, decimals=2, name=“prop1”)

property.length 10

Property.decimals 2

property.name prop1

MapeamentoMapeamento

<form target=“/sample” method=“post” > <input type=“hidden” name=“property.propertyType” value=“decimal”> <input type=“text” name=“property.length” value=“10”> <input type=“text” name=“property.decimals” value=“2”> <input type=“text” name=“property.name” value=“prop1”></form>

VistaVista

Mapeamento de polimorfismos.Mapeamento de polimorfismos.

JavaJava ParâmetroParâmetro ValorValor ObjetoObjeto

SampleController.property

property.propertyType

setSetProperty( values=ArrayList(“V1”, “V2”) name=“prop1”)

property.values[0] V1

property.values[1] V2

property.name prop1

MapeamentoMapeamento

<form target=“/sample” method=“post” > <input type=“hidden” name=“property.propertyType” value=“set”> <input type=“text” name=“property.values[0]” value=“V1”> <input type=“text” name=“property.values[1]” value=“V2”> <input type=“text” name=“property.name” value=“prop1”></form>

VistaVista

ReferênciasReferências

► http://www.brutosframework.com.br/http://www.brutosframework.com.br/►http://www.amazon.com.br/Brutos-Frahttp://www.amazon.com.br/Brutos-Fra

mework-framework-para-aplica%C3%Amework-framework-para-aplica%C3%A7%C3%B5es-ebook/dp/B00VD3JDOM/r7%C3%B5es-ebook/dp/B00VD3JDOM/ref=sr_1_1?ie=UTF8&qid=1435879104ef=sr_1_1?ie=UTF8&qid=1435879104&sr=8-1&keywords=java+mvc&sr=8-1&keywords=java+mvc

►https://en.wikipedia.org/wiki/Brutos_Frhttps://en.wikipedia.org/wiki/Brutos_Frameworkamework


Top Related