segunda-feira, 3 de dezembro de 2012

Spring MVC 3 - parte 4 - Mapeando Requisições

Usa-se @RequestMapping para mapear URLs para uma classe ou um método tratador particular. O seguinte exemplo apresenta a aplicação Petcare, que é uma das aplicações de exemplo da Spring:
   @Controller
   @RequestMapping("/appointments")
   public class AppointmentsController {

      private final AppointmentBook appointmentBook;

      @Autowired
      public AppointmentsController(AppointmentBook appointmentBook) {
         this.appointmentBook = appointmentBook;
      }

      @RequestMapping(method = RequestMethod.GET)
      public Map<String, Appointment> get() {
         return appointmentBook.getAppointmentsForToday();
      }

      @RequestMapping(value="/{day}", method = RequestMethod.GET)
      public Map<String, Appointment> getForDay(
         @PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, 
         Model model {
          return appointmentBook.getAppointmentsForDay(day);
      }

      @RequestMapping(value="/new", method = RequestMethod.GET)
      public AppointmentForm getNewForm() {
         return new AppointmentForm();
      }

      @RequestMapping(method = RequestMethod.POST)
      public String add(@Valid AppointmentForm appointment, 
         BindingResult result) {
         if (result.hasErrors()) {
            return "appointments/new";
         }

         appointmentBook.addAppointment(appointment);
         return "redirect:/appointments";
      }
   }  
Neste exemplo, @RequestMapping é usada em vários lugares. Primeiro, é usada em nível de classe, indicando que todos os métodos tratadores neste controle são relativos ao path /appointments. O método get() tem um melhor refinamento: aceita requisições do tipo GET, quer dizer, qualquer HTTP GET para /appointments invocará este método. O método add() é similar: aceita requisições do tipo POST, quer dizer, qualquer HTTP POST para /appointments invocará este método. O método getNewForm() combina a definição de método HTTP e path, então, qualquer requisição do tipo GET para appointments/new será tratada por esse método. O método getForDay() apresenta outro uso para @RequestMapping e será detalhado posteriormente.

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.

    sexta-feira, 17 de agosto de 2012

    Os filhos querem colo

    Na sexta feira, dia 12 de maio 2006, uma amiga do meu filho, a Isa, pulou do 8º andar do prédio onde morava em Joinville -SC. Tinha acabado de almoçar, estava com o uniforme do colégio Bom Jesus, e a mochila nas costas, o que indicava que iria retornar ao colégio, pois nas quartas e sextas eles têm aula o dia todo. Foi um choque para todos os colegas! Aí vem a pergunta: Por quê? Ela tinha apenas 15 anos. Que problemas uma menina de 15 anos pode ter? Fiz esta pergunta ao meu filho, e a resposta me deixou chocada... Ele me disse: Mãe, eu acho que era falta de colo! Questionei: Como assim? E ele me disse: Hoje em dia, os pais trabalham praticamente o dia todo, sempre com a mesma desculpa de que querem dar aos filhos tudo aquilo que nunca tiveram e, na maioria das vezes, eles estão conseguindo. Eles estão dando um estudo no melhor colégio, cursos de idiomas, dinheiro pra gastar no shopping, um computador de última geração pro filho ficar enfiado em casa durante o pouco tempo livre que sobra, roupas, tênis, celular, tudo muito caro, etc... E sempre cobrando da gente boas notas, pois estão investindo muito... Não era melhor então ter comprado ações, depositado na poupança, ou sei lá onde? Na maioria das vezes, os pais não têm mais tempo para os filhos, não conversam mais, não fazem um carinho... Quando a gente chega em casa, o que mais quer é o colo da mãe quando vai mal nas provas, ou quando acontece alguma coisa ruim. Por que você acha que hoje os adolescentes são quase todos revoltados? Na maioria das vezes, eles estão querendo chamar a atenção, ser notados, só que no lugar errado e de forma errada: na rua e com violência. Espero que a morte da Isa não tenha sido em vão, pois quem sabe desta forma muitos pais vão repensar suas atitudes para com seus filhos! Não somos máquinas, não somos todos iguais. Não é porque o filho da vizinha tira só dez que todos nós vamos tirar 10... Talvez, nem todos nós queiramos falar inglês! Depois de me falar tudo isso em prantos, ele me abraçou e disse, olhando nos meus olhos: Mãe, obrigado por você estar tão presente em minha vida, por eu poder contar sempre com você nos bons e nos maus momentos... Obrigado, também, pelas broncas, pois sei que mereço. O tempo e o amor são os melhores investimentos que vocês fazem pelos seus filhos, o resto é conseqüência. (Texto anônimo, circulando na Internet)