quarta-feira, 14 de novembro de 2012

Spring MVC 3 - Índice

Estou escrevendo uma série de artigos sobre o framework Web Spring MVC 3. 
Estarei disponbilizando esses artigos conforme for escrevendo.
Até a parte 3 já está disponível no blog.
Espero que seja útil para a comunidade de desenvolvedores. 

  • Parte 1 - Introdução - clique aqui para leitura
  • Parte 2 - Configuração - clique aqui para leitura
  • Parte 3 - Controladores - clique aqui para leitura
  • Parte 4 - Mapeando Requisições - clique aqui para leitura
  • Parte 5 - Views
  • Parte 6 - Interceptando Requisições
  • Parte 7 - Internacionalizando a Aplicação
  • Parte 8 - View Resolver
  • Parte 9 - Exceções
  • Parte 10 - Tratando Formulários
  • Parte 11 - Bean Validation
  • Spring MVC 3 - Parte 3 - Controladores

    Uma classe de Controle do Spring MVC possui métodos tratadores para requisições de usuário. Utiliza a anotação de classe @Controller e possui a anotação @RequestMapping que pode ser aplicada em nível de classe ou método. Em nível de classe mapeia uma URL para a classe de controle e, então, um método particular HTTP mapeia para cada método do controle. Controle interpreta a entrada do usuário e a transorma dentro de um modelo que é apresentado ao usuário através de uma view.
        package ... ;
    
        ...
        import org.springframework.stereotype.Controller;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.servlet.ModelAndView;
        import org.springframework.ui.Model;
    
        @Controller
        @RequestMapping("/welcome")
        public class WelcomeController {
        
            @RequestMapping(method = RequestMethod.GET)
            public String welcome(Model model) {
                Date today = new Date();
                model.addAttribute("today", today);
                return "welcome";
           }
        }
    
    
    O exemplo acima é um controle do Spring MVC, mapeado com a anotação @Controller. O primeiro @RequestMapping é usado em nível de classe para especificar que qualquer requisição recebida para /welcome será atendida por este controle. O segundo @RequestMapping é usado em nível de método e, nesse caso, atende qualquer requisição HTTP GET. No caso, este método é o método default para este controle e toda requisição recebida para /welcome será direcionada para o método welcome(Model model). No caso deste controle, se nenhum método HTTP GET default fosse declarado, a exceção ServletException seria lançada. Uma variação deste comportamento seria declarar ambos os valores no método:
        @Controller
        public class WelcomeController {
    
            @RequestMapping(value = "/welcome", method=RequestMethod.GET)
            public String welcome(Model model) {
            ...
    
    
    Um outro exemplo de método tratador no controle pode ser visto abaixo. Ele recebe todas as requisições HTTP POST enviadas para o controle, normalmente enviadas pelo usuário após submeter um HTML form, além de dois parâmetros de entrada. O primeiro é @RequestParam("courtName") String courtName, usado para extrair o parâmetro de requisição chamado courtName. O segundo parâmetro é Model model, usado para definir um objeto que podemos passar dados e retornar para a view. Na execução do método, uma variável chamada reservations é adicionada ao objeto Model, tornando-se disponível para retornar a visão para ser apresentada ao usuário e o método finaliza com um retorno para a view reservationQuery, indicada pela string de retorno.
        
        @RequestMapping(method = RequestMethod.POST)
        public String sumbitForm(@RequestParam("courtName") String courtName, Model model) {
            List reservations = java.util.Collections.emptyList();
            if (courtName != null) {
                reservations = reservationService.query(courtName);
           }
           model.addAttribute("reservations", reservations);
           return "reservationQuery";
        }
    
    
    Para habilitar auto detecção das classes de controle anotadas na sua aplicação, é necessário configurar o contexto do Spring informando o pacote base das classes de controle, conforme pode ser visto ne exemplo abaixo:
     
       <?xml version="1.0" encoding="UTF-8"?>
       <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:p="http://www.springframework.org/schema/p"
            xmlns:context="http://www.springframework.org/schema/context"
            xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
            <context:component-scan base-package=
                  "org.springframework.samples.petclinic.web"/>
    
            <!-- ... -->
       </beans>
    

    Spring MVC 3 - Parte 2 - Configurações

    Usando Maven, é preciso informar as dependências abaixo para desenvolver uma aplicação com Spring MVC:
        
            org.springframework
            spring-webmvc
            ${spring.version}
        
        
            org.springframework
            spring-web
            ${spring.version}
        
    
    É necessário configurar o servlet do Spring MVC no arquivo web.xml:
        
            ...
       
            
                aplicacao
                
                    org.springframework.web.servlet.DispatcherServlet
                
                1
            
            
                aplicacao
                /
            
        
    
    É necessário criar um arquivo xml do Spring para carregar as configurações para o Spring MVC. Por default, esse arquivo terá o nome do servlet, informando no arquivo web.xml, acrescido de -servlet.xml. Usando como exemplo a configuração do web.xml acima, o nome do arquivo seria aplicacao-servlet.xml. É possível especificar um outro nome utilizando o parâmetro contextConfigLocation no arquivo web.xml. Para carregar outros arquivos de configuração do Spring, ao lado do arquivo do Spring MVC, neste caso aplicacao-servlet.xml, é necessário definir o listener ContextLoaderListener no web.xml. Por default, ele carrega o arquivo /WEB-INF/applicationContext.xml, mas pode-se especificar outros arquivos, usando o parâmetro contextConfigLocation. Os arquivos de configuração devem ser separados por vírgula ou espaços.
        
            ...
    
            
                contextConfigLocation
                /WEB-INF/aplicacao-service.xml
            
            
                
                    org.springframework.web.context.ContextLoaderListener
                
            
        
    
    É necessário configurar a aplicação para escanear a presença de anotações nas classes de controle do Spring MVC, como @Controller e @RequestMapping. Para isso, é preciso habilitar o Spring para detectar as anotações através do elemento informando o pacote base da aplicação, que será a raiz para procurar pelas anotações. Em adição, a anotação @RequestMapping mapeia requisições URLs para classes controladoras e respectivos métodos. Por isso, é preciso registrar também as classes DefaultAnnotationHandlerMapping e AnnotationMethodHandlerAdapter. A primeira, para processar requisições em nível de classe e a segunda, em nível de método. A seguir, encontra-se um exemplo dessas configurações, que podem ser incluídas no arquivo de configuração do Spring MVC.
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/
                                               spring-context-3.0.xsd">
    
           <context:component-scan
                base-package="com.apress.springrecipes.court.web" />
            
           <bean class="org.springframework.web.servlet.mvc.annotation.
                                   DefaultAnnotationHandlerMapping" />
    
           <bean class="org.springframework.web.servlet.mvc.annotation.
                                    AnnotationMethodHandlerAdapter" />
    </beans>
    

    terça-feira, 13 de novembro de 2012

    Spring MVC 3 - Parte 1 - Introdução

    O componente central do Spring MVC é um controlador (controller) que é um servlet configurado no web.xml chamado Dispatcher Servlet. Este servlet segue o padrão Front Controller. Quando uma requisição web é enviada para uma aplicação Spring MVC, um controlador recebe esta requisição e faz o tratamento necessário. Para se definir uma classe de controle, a classe precisa ser anotada com @Controlller. Quando esta classe recebe uma requisição, ela procura por um apropriado método para tratar esta requisição. Então é necessário mapear cada requisição para um método da classe de controle, usando um ou mais mapeamentos. Para fazer isso, os métodos são decorados com a anotação @RequestMapping. A assinatura desses métodos pode ter qualquer nome, uma variedade de argumentos e pode ter qualquer um de uma série de retornos, como exemplo, String ou void. A seguir encontra-se uma lista parcial de argumentos válidos para os métodos do controlador:
    • HttpServletRequest ou HttpServleResponse
    • Parâmetros de Requisição anotados com @RequestParam
    • Atributos de Modelo anotados com @ModelAttribute
    • Cookies incluídos na requisição anotados com @CookieValue
    • Map ou ModelMap, para o método adicionar atributos ao modelo
    • Errors ou BindingResult, para o método fazer o “binding” e validar o resultado de de objetos
    • SessionStatus, para notificações de completude de processamento de sessão
    Depois que o método do controle finaliza seu processamento, ele delega o controle para a view, que é representada pelo valor de retorno do método, no caso uma String. Esse valor de retorno é um valor lógico (ex: user ou report) e não uma implementação da view (ex: user.jsp ou report.pdf). Se o retorno é void, um valor default lógico é usado. Os objetos dos argumentos do método recebidos como parâmetros, como por exemplo um Map ou SessionStatus estarão acessíveis na view, tendo sido modificados ou não pelo método do controlador. Um bean do Spring do tipo ViewResolver, configurado na aplicação, resolve o valor lógico de retorno do método para uma implementação.