brutos mvc
Post on 17-Aug-2015
62 Views
Preview:
TRANSCRIPT
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