Pesquisar este blog

sexta-feira, 18 de setembro de 2015

Introdução ao Linux, Sistemas Operacionais Abertos

Introdução ao Linux

Aqui vão ser explicados alguns comandos básicos do linux, para testá-los na sua casa você deve acessar o terminal. Cada distribuição do linux possui uma configuração de um sistema de janelas diferentes, mas todos vem com um terminal instalado. Para acessá-lo, encontre o sistema de busca de programas, e digite terminal. O logo do terminal geralmente é um quadrado com o fundo preto, ou vermelho, abra ele e pronto, você já está apto a usar os comandos que serão mostrados aqui.
Uma outra forma de acessar o terminal é usando as teclas ctrl + alt + 1 isso te leva ao modo texto do linux. Agora é só digitar o seu usuário e senha e pronto, você já estará acessando o terminal.
No linux a caixa da letra (maiúscula e minúscula) fazem a diferença, então tudo o que será mostrado aqui, deve ser seguido a risca.

Top

O comando top mostra uma lista dos processos que estão sendo executado no seu sistema. Em cima da tela ele exibe um cabeçalho, onde estão informações como o número total de Tasks, quantas estão rodando, quantas estão dormindo, quantas estão paradas. Qual é a porcentagem da cpu que está sendo utilizada, qual é a quantidade da memória está sendo utilizada, incluindo o SWAP (memória virtual).
Abaixo do cabeçalho, temos uma lista dos processos, ordenados pela ocupação da CPU, ou seja, os que mais estão consumindo processamento, serão mostrados primeiro.
Dentre as informações importantes que temos no top, estão o PID (proccess id), que é o id do processo no sistema. O pid será usado mais afrente neste post, na definição do comando kill.
Quanto cada processo está ocupando do processador, memória e ha quanto tempo ele está rodando, quem é o usuário dono do processo (aquele que iniciou o processo).
Ele se atualiza a cada 3 segundos, por padrão, mas para alterar isso basta usar o argumento -d
top -d 10
Faz com que a lista se atualize a cada 10 segundos.

Aptitude (apt-get)

No início, a instalação de um software no Linux era uma tarefa complicada, todo software que era instalado, deveria ser compilado pelo usuário, e no seu processo de compilação, ele checava as dependências daquele software. Por exemplo, se o software A depende do B, você deve instalar primeiro o B, para depois instalar o A. Esta lista inicialmente era bem pequena, mas depois de algum tempo, administrar todas estas dependências tornou-se um processo complicado.
Algumas distribuições como o SuSe (da novel), o RedHat, o Debian e o e algumas outras, criaram a sua forma de facilitar o processo de instalação de softwares no Linux.
O apt-get é o administrador de pacotes das distribuições baseadas no Debian, dentre elas o Ubuntu, o Mint, mas ele também pode ser instalado nas outras distribuições.
O funcionamento do apt-get se dá da seguinte maneira. Cada distribuição possui uma lista de servidores onde ficam armazenados os softwares que estarão disponíveis para serem utilizados. Estes servidores também possuem uma lista de quais softwares e quais versões estão disponíveis nele.
Toda configuração de onde o apt-get irá procurar e baixar os softwares ficam aramazenadas no arquvo:
/etc/apt/sources.list  (em algumas distribuições este arquivos pode ter um nome ou uma localização diferente desta)
Existem diversas fontes diferentes de softwares, como pendrives, cdroms, dvds e tudo isso pode ser configurado neste arquivo:
deb http://sítio.exemplo.com/debian distribuição componente1 componente2 componente3
deb-src http://sítio.exemplo.com/debian distribuição componente1 componente2 componente3
Distribuição é onde será configurada o nome da sua distribuição, e os componentes são subdivisões de como os softwares são categorizados, e elas geralmente são:
  • main 
  • contrib
  • non-free
Cada distribuição faz a sua subdivisão de quais softwares estarão em cada categoria.
Os comandos do apt-get são:
  • update que atualiza a lista de pacotes disponíveis para instalação
  • upgrade atualiza os softwares instalados
  • install instala os softwares listados
  • dist-upgrade atualiza a versão da distribuição
  • remove remove um pacote
  • clean apaga os arquivos baixados para instalação
Um exemplo de instalação seria:
apt-get install htop

Usuário Root e comando sudo

Toda instalação do linux, possui um super usuário, também conhecido como root. Este usuário é quem consegue instalar, alterar as configurações e apagar os arquivos do sistema.
Nunca devemos usar um usuário em uma estação como root, por exemplo, caso haja um vírus, se você estiver com o seu usuário, não root, o máximo que este vírus conseguirá fazer de estrado, é apagar as coisas do seu usuário e nunca, apagar um software instalado no sistema, já que isso necessita da permissão de root.
Uma das formas de fazer com o que seu usuário tenha a permissão de root, momentâneamente, é utilizando o comando sudo.
Para usarmos o apt-get devemos ter permissão de root, então como exemplo teríamos que usá-lo assim:
sudo apt-get update
Com isso o seu usuário se torna root, por alguns minutos, e o apt-get consegue rodar a instalar os softwares que você pediu.
Um usuário só consegue usar o sudo, se ele estiver no grupo de sudo.

Adicionando usuário ao grupo

Existem duas formas de se adicionar um usuário a um grupo, a primeira delas é através do comando:
  useradd -G grupo usuario
No caso para adicionar o usuário dirceu ao grupo sudo faça:
useradd -G sudo dirceu
A outra forma de fazer isso é editando o arquivo:
/etc/group
E adicionar o nome do usuário na linha do grupo do sudo:
 sudo:x:27:dirceu
Para isso deve-se usar um editor de texto

Editor de texto nano

O nano é um dos editores que vem instalado na distribuição debian e vamos utilizá-lo para alterar os arquivos.
A maioria dos comandos do nano são acessados através da tecla ctrl.
A sua utilização é bem simples, para acessar o arquivo de grupos digite:
suto nano /etc/group
Com isso ele abrirá o arquivo na sua tela.
ctrl+w
é o comando que usamos para busca, e como queremos achar o grupo sudo, basta digitar ctrl+w sudo
Ao achar o texto, seu cursor será direcionado para o texto encontrado, da mesma forma como acontece nos softwares que estamos acostumados.
Os comandos básicos do nano são:
  • ctrl+x sair
  • ctrl+a tecla home
  • ctrl+e tecla end
  • ctrl+y page down
  • ctrl+v page up

Cat

Cat é o comando responsável por mostrar o conteúdo de um arquivo na tela.
cat /etc/group
Irá mostrar o conteúdo do arquivo /etc/group na sua tela, com isso podemos ver se a nossa alteração foi realmente salva no arquivo.

Comando PS

O comando top nos mostra os processos em exeucção no momento, já o comando ps, nos mostra uma lista com todos os processos sendo executados.
  • A mostra todos os processos
  • a todos os processos daquele terminal
O ps é um comando bem útil quando queremos saber qual é o PID de um certo processo. Como a saída do ps -A é bem grande, vamos explicar uma forma de limitar o resultado apresentado.

Comando | grep

O pipe, ou | serve para encadear processos no linux. Com o pipe podemos direcionar a saída de um comando, para outro.
Grep é o comando utilizado para realizar buscas em arquivos dentro de um diretório.
grep dirceu *
Procura a palavra dirceu em todos os arquivos daquele diretório.
ps -A | grep dirceu
Vai procurar a palavra dirceu na saída gerada pelo comando ps -A, portanto se houver algum processo chamado dirceu rodando na sua máquina, a linha dela será mostrada e com isso teremos o PID daquele processo.

Matando um processo com o kill

Kill é um comando que envia um sinal para um processo, e como o seu nome diz, este sinal geralmente é o de terminar o processo. Quando algo trava, podemos usar o kill para matar aquele processo e evitar termos que reiniciar a máquina. Reiniciar o Linux é uma tarefa muito rara.
Existem mais de 60 tipos de sinais que podem ser enviados pelo comando kill, mas o que estamos mais interessados é o 9
kill -9 1234
Irá mandar um sinal de SIGKILL para o processo com id 1234. Lembre para saber o PID de um processo usamos o comando ps, descrito acima. SIGKILL é o sinal responsável por matar aquele processo. Este é o comando mais forte do kill. Por padrão, se nenhum comando for especificado, um comando -15 será usado SIGTERM, caso ele falhe, deveremos utilizar o kill -9 para matar o processo.
Para matar um processo (kill -15) usando o seu nome, podemos usar o comando killall, mas saiba que o comando killall matará todos os processos que tiverem aquele nome.
killall nano
Envia um comando SIGTERM para todas as instancias do nano que estão sendo executadas naquela máquina.

Tarefas em background

O terminal do Linux é multitarefas, ou seja, conseguimos executar vários softwares nele ao mesmo tempo.
Uma das formas de se colocar um processo em background, ou seja, executando mas sem ocupar a tela, é através da utilização do caracter &
nano /etc/group &
Irá fazer com que o nano seja executado em background.
Para parar um processo que está sendo executado, e jogá-lo em background pausado, usamos as teclas ctrl+z
Com isso o processo vai para background, mas fica parado. Podemos fazer isso com vários programas e para listá-los podemo suar o comando jobs, que irá te mostrar a lista de processos e a situação deles.
Como o nano é um programa que precisa da tela, toda vez que jogarmos ele para background ele ficará parado.
Exemplo de saída o jobs:
[1]+  Stopped                 nano /etc/group
[2]   Running                 tail -f /etc/group &
[3]-  Stopped                 tail -f /etc/group &
Aqui ele mostrou uma lista com três processos, cada um deles, com seu número, estado e o comando.
Como o processo 3 está parado, caso seja necessário deixá-lo rodando em background  deve-se usar o comando bg. Bg é o comando que joga um processo para background.
bg 3
Fará com que o status do comando 3 mude de Stopped para Running
[1]+  Stopped                 nano /etc/group
[2]   Running                 tail -f /etc/group &
[3]-  Running                 tail -f /etc/group &
 O último comando deste post é o fg, mas e se você quiser ver o resultado, ou trazer para a tela um dos processos que estão sendo executados em background? Basta usar o comando fg, que funciona da mesma forma que o bg:
fg 3
Coloca na tela (foreground) o processo tail -f /etc/group

segunda-feira, 14 de setembro de 2015

Spring Data com anotações e JSF

No último post foi mostrado um padrão de MVC push, ou seja, a interface enviava os dados e realizava as chamadas aos controllers. Aqui será mostrado uma maneira de desenvolver uma aplicaçao Web com o MVC pull, ou seja, a interface pucha os dados da camada de serviço.

Java Server Faces

JSF é uma especificação do Java, baseada em componentes, para se construir a interface de um aplicativo Web. Na primeira versão do JSF as páginas eram construidas utilizando a tecnologia JSP, depois da versão 2.0 do JSF elas passaram a ser construidas sobre uma tecnologia chamada Facelets.
Facelet é uma tecnologia da apache de modelos das interfaces web.

Configuração de um aplicativo Web com JSF e Spring Data

Aqui serão apresentados os detalhes da configuração do web.xml de uma aplicação JSF com Spring Data
A primeira coisa que devemos nos preoupar, ao configurar um aplicativo web, é a configuração do seu servlet, para o JSF utilizamos o FacesServlet, que será responsável por mapear todas as requisições das páginas a camada de serviço, a sua configuração é feita por:
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
A tag servlet-mapping é de extrema importância, pois é nela que declaramos onde estarão localizados os nossos arquivos de interface, o que neste caso serão todos os arquivos .xhtml da pasta raiz:

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
A configuração do spring por anotações é realizada pela classe AnnotationConfigWebApplicationContext, e introduzindo o texto a seguir no seu web.xml irá configurar o spring para ler as anotações do projeto e configurar os Beans a partir delas.
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>

Depois de definir que o projeto será configurado por anotações deveremos especificar qual é a classe de configuração dos nossos beans:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>br.unip.dsd.config.JPAConfig</param-value>
    </context-param>
A última configuração a ser adicionada é a configuração dos listeners. O ContextLoaderListener é responsável por ler e parsear todas as configurações referentes ao contexto da aplicação, como a instanciação dos beans. Já o ConfigureListener irá ler e parsear todas as configurações do JSF, e a sua configuração no web.xml é assim:
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>
Com isso o nosso aplicativo está pronto para ser executado, agora serão mostradas as configurações do JSF.

Configuração do JSF

Todas as configurações dos aplicativos Web ficam em uma pasta WEB-INF, o arquivo de configuração do JSF chama-se faces-config.xml. Nele serão definidas as configurações dos beans do JSF e da classe responsável por enviar mensagens ao nosso aplicativo.
No nosso post de MVC, as classes que recebiam as chamadas da interface eram chamadas de Controllers, aqui no JSF elas são chamadas de Managed-Bean. Um managed-bean é um Bean do Java que pode ser acessado através dos componentes do JSF, e sua configuração define o nome, que será utilizado na interface, e a sua respectiva classe:
    <managed-bean>
        <managed-bean-name>usuarioBean</managed-bean-name>
        <managed-bean-class>br.unip.dsd.bean.UsuarioBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
Também podemos configurar as mensagens da nossa interface, por mensagens entenda qualquer texto que será utilizado em nossa interface. Nesta configuração podemos usar a internacionalizaçao do Java. Mas o que é isto?
Nesta configuração pode-se definir quais são as linguas suportadas pelo nosso aplicativo, e cada lingua suportada, terá um arquivo de mensagens específico. O browser detecta automaticamente a lingua do cliente, e exibe as mensagens na sua lingua específica, caso a lingua do usuário não seja suportada, ele mostrará a lingua padrão.
Nesta configuração defini-se como lingua padrão o br (de portugues do Brasil) e en (de English, ou Inglês) como segunda lingua suportada.

  <application>
    <message-bundle>br.unip.dsd.mensagens.MensagensAplicacao</message-bundle>
    <locale-config>
       <default-locale>br</default-locale>
       <supported-locale>en</supported-locale>
    </locale-config>
    <el-resolver>
            org.springframework.web.jsf.el.SpringBeanFacesELResolver
        </el-resolver>
   
  </application>
A tag message-bundle, define a localização dos arquivos de mensagem do aplicativo, o que será um arquivo localizado no pacote  br.unip.dsd.mensagens, chamado MensagensAplicacao.properties (para o ingles) e MensagensAplicacao_br.properties (para o portugues). Aqui é possível adicionar quantas linguas você quiser, para isso basta adicionar um supported-locale, e um arquivo de propriedades.
Um arquivo de propriedades é um arquivo de chave, valor, ou seja, ele possui uma coluna com as chaves, nomes usados no nosso aplicativo e que deverão estar definidos em todos os arquivos utilizados aqui, e um valor, que é o texto mostrado para o usuário:
erroEmailExiste=Email já cadastrado
erroConfirmacaoEmail=Por favor verifique se os emails digitados são idênticos
Acima temos um exemplo de duas mensagens de erro, sendo que as chaves, que serão utilizadas pelo aplicativo para recuperar as mensagens, estão grifadas, e os valores, que serão mostrados ao usuário estão definidos logo a frente.
No aplicativo, para acessar estas mensagens vamos precisar de uma Factory, que é definida assim:
  private ResourceBundle bundle;
  private Locale locale;
 
  public MessagemFactory() {
    locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
      bundle = ResourceBundle.getBundle("br.unip.dsd.mensagens.MensagensAplicacao", locale);
  }
Nestes caso o bundle é onde foi definido as nossas mensagens, e locale é onde está localizado o nosso cliente.
Para recuperar uma mensagem basta usar um bundle.getString(valor) e pronto, ele irá cuidar de mostrar a mensagem correta ao nosso cliente.

Managed Bean

A definição de um bean é feita através da anotação @ManagedBean, conforme mostrado abaixo:
@Component
@ManagedBean
public class UsuarioBean
Todos os valores que forem acessados pela sua interface, devem ser definidos como propriedades do seu Bean, e eles devem ter seus métodos de get e set, para que o JSF consiga acessar e alterar os seus valores.
Então você pode estar pensando que aqui você vai por os seus modelos? Bem não é exatamente isto o que deve ser feito. Nos beans colocamos regras de negócios, por exemplo se o seu bean for um bean de gravação de usuário, aqui podemos colocar as regras de validação dos valores digitados, assim como uma instância do repositório dos usuuários.
Para colocar qualquer instância de qualquer bean definido no contexto do seu aplicativo, basta usar a anotação @Autowired, que toda aquela configuração colocada no web.xml irá cuidar de encontrar o bean e instanciá-lo:
@Autowired
 private RepositorioUsuario repositorioUsuario;
Irá prover uma instância do repositório do usuário, definido pela interface RepositorioUsuario.
Com isso conseguimos gravar os dados recebidos da tela no banco de dados.

Interface JSF

Bom, já foi mostrada toda a integração e a parte de backend, mas e os componentes do JSF, como utilizá-los?
A definição dos componentes JSF podem ser feitos em um arquivo HTML, aqui neste projeto estamos usando arquivos .xhtml. Precisamos definir as configurações do JSF nos metadados do nosso html e isso é feito usando:
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html">
Repare que definimos xmlns:h e isso determina que os componentes do jsf serão definidos como h:componente.
Para definirmos um campo que acessa o valor de nome do nosso bean do usuário, basta fazermos:
<h:inputText id="nome" value="#{usuarioBean.usuario.nome}"
            required="true" />
Para que isto funcione, o nosso bean de usuário, deverá ter uma propriedade usuario, que por sua vez terá uma propriedade nome. Com isso acessamos a propriedade nome, do usuario do usuarioBean e o valor digitado no nosso campo texto será automaticamente setado nele.
Aqui devemos considerar que para que isso funcione, o usuário não pode ser nulo, do contrário teremos uma NullPointerException sendo disparada.
Todos os arquivos deste exemplo estão disponíveis no meu repositório e a apresentação.

quarta-feira, 9 de setembro de 2015

Controllers com Spring MVC

Antes de começar, saiba que para conseguir implementar os códigos mostrados aqui neste post, o seu pom.xml deverá ter as seguintes dependências:

   <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.8.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.185</version>
        </dependency>

        <!-- DataSource (HikariCP) -->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
            <version>2.2.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
Estamos desenvolvendo um aplicativo Web de cadastro de usuários e neste post será mostrado como fazer um Controller.
O Controller, ou Controlador, é um dos pilares do MVC (Model, View e Controller), o modelos já foram discutidos no post sobre entidades e view é a camada visual do nosso aplicativo.
Esta camada é quem realiza as iterações entre os modelos e a UI (Interface com o Usuário - View), e estas iterações ocorrem tanto enviando dados da UI para os modelos, e possivelmente alterando os valores armazenados no banco. Como também envia mensagens dos modelos para a ui, alterando os valores mostrados para o usuário.
Estamos usando o SpringMVC para nos ajudar a configurar um Controller do Java.

Servlets

Com o Java podemos criar páginas Html com conteúdo dinâmico, ou seja, podemos escrever e alterar os dados que são mostrados em uma página para o usuário.
Os servlets são como pequenos servidores, que processam chamadas Html, processam a requisição e devolvem uma resposta.
Em um aplicativos Web, temos que processar as requisições Html geradas para o nossos Servlets, cada iteração do cliente, gera uma chamada Http ao nosso Servlet.
No java os Servlets extendem a classe javax.servlet.http.HttpServlet. 
Todos os controllers utilizados por nós, serão servlets, e o papel do Spring MVC aqui é nos ajudar a escrever menos código para conseguirmos processar as resquisições Html.

Configurando o web.xml

No web.xml serão configurados os servlets e os seus caminhos, assim como página inicial.
Quando desenvolvemos Servlets na mão, cada servlet precisa de uma entrada no arquivo web.xml, lá podemos definir qual classe será responsável por processar as requisições a cada caminho.
Com a utilização do Spring MVC esta configuração será realizada com annotations dentro dos Controllers.
O Spring MVC possui uma classe que escuta todas as requisições ao nosso aplicativo, e ela será responsável por direcionar estas requisições para cada um dos controllers.
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <!-- Processa as requisições -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        //so annotations
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>                org.springframework.web.context.support.AnnotationConfigWebApplicationContext
            </param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>br.unip.dsd.config.JPAConfig</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- Configura o arquivo padrão -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>
A target <servlet> é onde definimos esta classe, ela irá processar todas as requisições e de acordo com as configurações inseridas nos controllers, elas serão direcionadas.
A classe definida como contextClass é usada quando queremos que todas as configurações dos controllers sejam feitas com anotações. Já contextConfigLocation indica a classe onde colocamos todas as configurações dos nossos beans.
Na tag servlet-mapping está configurado que o servlet irá escutar todas as requisições desde a raiz, aqui definida pela "/΅.
O arquivo de boas vindas (welcome-file) define qual será o arquivo a ser exibido assim que um usuário fizer alguma requisição ao endereço raiz do aplicativo.

Definições de Endereços dos Métodos

Para desenvolver um software, devemos definir os métodos, cada método fica responsável por realizar um tipo de operação, ou pelo menos é o que define a teoria.
Nos aplicativos Web, também temos a definição de métodos, sendo o seu nome o endereço da chamada. Porém na web somente o endereço não define um método, pois uma chamada, a um mesmo endereço pode ser realizada utilizando diferentes métodos Http. Os métodos http mais utilizados são:
  • GET
  • PUT
  • POST
  • DELETE
Não necessariamente uma chamada que utiliza o método Http DELETE irá realizar uma operação de remoção de dados, nada impede que um método de criação seja implementado com o método Http DELETE, porém isso foge aos padrões esperados. Por padrão, as chamadas GET são utilizadas para requisitar alguma informação, na forma de uma entidade, do servidor web, já uma chamada PUT envolve a submissão de dados de uma entidade, quando esta entidade já existir, deve-se assumir que uma alteração foi submetida, quando a entidade ainda não existir, deve-se assumir que uma operação de inserção está sendo realizada. 
O método POST é utilizado para a criação de recursos, ou a inserção de dados, porém ele não deve ser utilizado quando a URL em questão não existe, por exemplo que acontece em posts de blogs, ou criação de dados que geram URLs.
DELETE requer que os dados daquela URL sejam apagados.

Argumentos dos métodos

Existem algumas formas de enviar argumentos a um método Http, e a mais simples delas, geralmente utilizada em métodos GET, é passar os argumentos pelo caminho do método, como mostrado abaixo:
www.seuservico.com.br/usuario?usuario_id=1;usuario_nome=teste
No caso acima, utilizamos o nosso serviço de usuários "/usuario" e dois argumentos, usuario_id e usuario_nome.
Note que em um serviço Web, uma URI pode apontar para um dado específico, por exemplo quando o ID daquele dado faz parte de uma URL.
www.seuservico.com.br/pessoas/1
Neste caso, esta chamada contém o ID da pessoa ao final da URI e todos os métodos com esta URI referenciam a pessoa com ID=1.
Esta prática de passar argumentos pela URL é bem comum e bem simples de se construir, porém note, qualquer pessoa ou serviço, como o seu provedor de acesso a internet, podem mapear as requisições aos seus serviços e dependendo das informações que você coloca na url, dados importantes dos seus usuários podem ficar expostos, como a senha, números de documentos, etc. A recomendação aqui é utilizar este tipo de método com cautela, ou nunca usá-la.
Veja nas páginas que você acessa hoje, se o endereço da web que está no seu navegador não contém argumentos, se tiver, você pode tentar descobrir quais atributos estão sendo utilizados por ele.
Uma outra forma de se passar argumentos, é através do Body Http da sua mensagem, neste caso o seu provedor de acesso também pode mapear os atributos da sua requisição, a não ser que você esteja fazendo uma chamada Https, que será criptografada e evita esta instrospecção.

Definição do Controller

Para definir um controller utilizando o Spring MVC, basta adicionar a anotação @Controller no topo de sua classe:
@Controller
@RequestMapping("/primeiro")
public class PrimeiroController {

 @RequestMapping(method = RequestMethod.GET)
 public String imprimeOla(ModelMap model) {
   model.addAttribute("mensagem", "Olá seu primeiro MVC!");
   return "primeiro";
 }
}
Com o conttroller definido, devemos mapear quais serão os seus métodos, o que é feito pela anotação @RequestMapping. Repare que esta classe só irá processar requisições feitas ao endereço /primeiro.
O ModelMap, é uma classe que podemos passar para a nossa página jsp, e nela consultar os valores inseridos neste modelo, o que é feito com:
<@ page contentType="text/html; charset=UTF-8" >
<html>
<head>
<title> Olá MVC</title>
</head>
<body>
   <h2>${mensagem}</h2>
</body>
</html>

A nossa mensagem será mostrada na página, através do ${mensagem}. Esta é uma das formas de enviarmos dados para a nossa página jsp, repare que podemos chamar vários addAttributes no nosso model, e acessar todos eles na nossa página.
Em RequestMapping estamos definindo a qual método http aquele método irá responder, o GET.
O RequestMapping também pode ser utilizado em cada método, onde também é possível definir um caminho específico para aquele método, por exemplo:
@RequestMapping("/indice")
public String indice() {
   return "indice";
}
Ao definir este método, você estará configurando ele para ser acessado pelo caminho da classe, o que no nosso caso é /primeiro, mais indice, portanto para acessá-lo devemos:
www.seuservico.com.br/primeiro/indice