Raible's Wiki

Raible Designs
Wiki Home
News
Recent Changes

AppFuse

Homepage
  - Korean
  - Chinese
  - Italian
  - Japanese

QuickStart Guide
  - Chinese
  - French
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish
  - Japanese

User Guide
  - Korean
  - Chinese

Tutorials
  - Chinese
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish

FAQ
  - Korean

Latest Downloads

Other Applications

Struts Resume
Security Example
Struts Menu

Set your name in
UserPreferences


Referenced by
Articles
ValidationAndListSpr...




JSPWiki v2.2.33

[RSS]


Hide Menu

SpringControllers_pt


Difference between version 8 and version 2:

At line 8 changed 1 line.
;:%%(color: blue)''I will tell you how I do stuff in the __Real World__ in text like this.''%%
;:%%(color: blue)''Vou dizer a vocês como faço as coisas no __Mundo Real__ em textos como este.''%%
At line 10 changed 1 line.
Let's get started by creating a new Controller and JSP in AppFuse's architecture. If you haven't installed the Spring MVC module at this point, do so by running ''ant install-springmvc''.
Vamos começar criando um novo Controller e JSP com a arquitetura do AppFuse. Se você ainda não instalou o módulo Spring MVC, faça isso rodando ''ant install-springmvc''.
At line 12 changed 7 lines.
!Table of Contents
* [1] Create skeleton JSPs using XDoclet
* [2] Create PersonFormControllerTest to test PersonFormController
* [3] Create PersonFormController
* [4] Run PersonFormControllerTest
* [5] Clean up the JSP to make it presentable
* [6] Create Canoo WebTests to test browser-like actions
!Tabela de Conteúdo
* [1] Crie esqueletos de JSPs utilizando XDoclet
* [2] Crie o PersonFormControllerTest para testar o PersonFormController
* [3] Crie o PersonFormController
* [4] Rode o PersonFormControllerTest
* [5] Limpe o JSP para deixá-lo apresentável
* [6] Crie Canoo WebTests para testar ações comuns de navegador
At line 20 changed 2 lines.
!!Create a skeleton JSP using XDoclet [#1]
In this step, you'll generate a JSP page to display information from the Person object. It will contain Spring's JSP tags that render table rows for each property in Person.java. The [AppGen] tool that's used to do this is based off a StrutsGen tool - which was originally written by [Erik Hatcher|http://www.blogscene.org/erik/]. It's basically just a couple of classes and a bunch of XDoclet templates. All these files are located in extras/appgen.
!!Crie esqueletos de JSPs utilizando XDoclet [#1]
Neste passo, você gerará uma página JSP para mostrar informações sobre um objeto Person. Ele possuirá tags JSP do Spring para renderizar campos editáveis para cada propriedade do Person.java. A ferramenta [AppGen], que é baseada em uma ferramenta chamada StrutsGen - escrita inicialmente por [Erik Hatcher|http://www.blogscene.org/erik/]. São basicamente algumas classes e alguns templates XDoclet. Todos estes arquivos estão localizados em extras/appgen.
At line 23 changed 1 line.
Here are the simple steps to generating the JSP and a properties file containing the labels for the form elements:
Aqui vão alguns passos simples para gerar o JSP e o arquivo de propriedades contendo rótulos para os elementos do formulário:
At line 25 changed 6 lines.
* From the command-line, navigate to "extras/appgen"
* Execute __ant -Dobject.name=Person -Dappgen.type=pojo__ to generate a bunch of files in extras/appgen/build/gen. In fact, it'll generate all the files you need to complete this tutorial. However, let's just grab the ones you need.
** web/WEB-INF/classes/Person.properties (labels for your form elements)
** web/pages/personForm.jsp (JSP file for viewing a single Person)
** web/pages/personList.jsp (JSP file for viewing a list of People)
* Copy the contents of Person.properties into web/WEB-INF/classes/ApplicationResources.properties. These are all the keys you will need for titles/headings and form properties. Here is an example of what you should add to ApplicationResources.properties:
* Da linha de comando, navegue para o diretório "extras/appgen"
* Execute __ant -Dobject.name=Person -Dappgen.type=pojo__ para gerar alguns arquivos em extras/appgen/build/gen. De fato, ele gerará __TODOS__ os arquivos que serão necessários para completar estes tutoriais. Apesar disso, vamos apenas pegar os arquivos necessários para este tutorial.
** web/WEB-INF/classes/Person.properties (rótulos para nossos elementos de formulário)
** web/pages/personForm.jsp (arquivo JSP para mostrar uma única pessoa)
** web/pages/personList.jsp (arquivo JSP para mostrar uma lista de pessoas)
* Copie o conteúdo do arquivo Person.properties em web/WEB-INF/classes/ApplicationResources.properties (para rodar os testes de action sem erros), e depois copie este conteúdo para o arquivo web/WEB-INF/classes/ApplicationResources_pt_BR.properties, modificando o seu conteúdo. Estas são todas as chaves necessárias para título/cabeçalho e propriedades do formulário. Aqui está um exemplo do que adicionar ao arquivo ApplicationResources.properties:
At line 51 removed 1 line.
* Copy personForm.jsp to web/pages/personForm.jsp. Copy personList.jsp to web/pages/personList.jsp.
At line 53 changed 1 line.
;: ''The files in the "pages" directory will end up in "WEB-INF/pages" at deployment time. The container provides security for all files below WEB-INF. This applies to client requests, but not to forwards from the DispatchServlet. Placing all JSPs below WEB-INF ensures they are only accessed through Controllers, and not directly by the client or each other. This allows security to be moved up into the Controller, where it can be handled more efficiently, and out of the base presentation layer.''
E aqui está o exemplo do que adicionar ao arquivo ApplicationResources_pt_BR.properties:
<div style="margin-left: 40px">
{{{
# -- formulário da pessoa --
person.id=Id
person.firstName=Nome
person.lastName=Sobrenome
At line 55 changed 1 line.
The web application security for AppFuse specifies that all *.html url-patterns should be protected (except for /signup.html and /passwordHint.html). This guarantees that clients must go through an Action to get to a JSP (or at least the ones in ''pages'').
person.added=A Pessoa foi adicionada com sucesso.
person.updated=A Pessoa foi alterada com sucesso.
person.deleted=A Pessoa foi removida com sucesso.
At line 57 changed 1 line.
%%note __NOTE:__ If you want to customize the CSS for a particular page, you can add &lt;body id="pageName"/> to the top of the file. This will be slurped up by SiteMesh and put into the final page. You can then customize your CSS on a page-by-page basis using something like the following:
# -- página de listagem de pessoas --
personList.title=Lista de Pessoas
personList.heading=Pessoas
# -- página de detalhamento de pessoa --
personDetail.title=Detalhamento da Pessoa
personDetail.heading=Informações da Pessoa
}}}
</div>
* Copie personForm.jsp para web/pages/personForm.jsp. Copie personList.jsp para web/pages/personList.jsp. __Note que o primeiro caracter de cada novo nome de arquivo é minúsculo.__
;: ''Os arquivos no diretório "pages" serão publicados em "WEB-INF/pages" em tempo de publicação. O container disponibiliza segurança para todos os arquivos dentro de WEB-INF. Isto se aplica a requisições de cliente, mas não a envios para o DispatchServlet. Colocando todos os JSPs em WEB-INF garante que eles serão acessados apenas por Controllers, e não diretamente por um cliente. Isto permite que a segurança seja movida para dentro do Controller, onde pode ser tratada com maior eficiência, retirando ela da camada de apresentação.''
A segurança de aplicação web para o AppFuse especifica que todos os padrões de url *.html devem ser protegidos (exceto o /signup.html e /passwordHint.html). Isto garante que o cliente deve acessar uma Action para acessar um JSP (pelo menos, os que residem em ''pages'').
%%note __NOTA:__ Se você deseja customizar o CSS para uma página particular, você pode adicionar &lt;body id="pageName"/> na parte superior do seu arquivo. Isto será processado pelo SiteMesh e colocado ao final da página. Você pode customizar seu CSS em uma base página por página utilizando algo como o seguinte:
At line 60 changed 2 lines.
* Add keys in ApplicationResources.properties the titles and headings in the JSPs
In the generated JSPs, there are two keys for the title (top of the browser window) and the header (heading in the page). We now need to add these two keys (personDetail.title and personDetail.heading) to ApplicationResources.properties.
* Adicione chaves no ApplicationResources.properties (no nosso caso, ApplicationResources_pt_BR.properties) para os títulos e cabeçalhos nos JSPs
Nos JSPs gerados, existem duas chaves, uma para o título (alto da janela do navegador) e outra para o cabeçalho (cabeçalho da página). Agora precisaremos adicionar estas duas chaves (personDetail.title and personDetail.heading) ao ApplicationResources.properties (no nosso caso, ApplicationResources_pt_BR.properties.).
At line 65 changed 2 lines.
personDetail.title=Person Detail
personDetail.heading=Person Information
personDetail.title=Detalhamento da Pessoa
personDetail.heading=Informações da Pessoa
At line 69 changed 1 line.
;:''Just above, we added "personForm.*" keys to this file, so why do I use personForm ''and'' personDetail? The best reason is because it gives a nice separation between form labels and text on the page. Another reason is because all the *Form.* give you a nice representation of all the fields in your database.
;:''Agora acima, , adicionamos as chaves "personForm.*" a este arquivo, então porque usar personForm ''e'' personDetail? A melhor razão é porque esta prática nos dá uma boa separação entre rótulos de formulários e texto na página. Outra razão é porque todos os *Form.* nos dão uma boa representação de todos os campos de nosso banco de dados.
At line 71 changed 1 line.
I recently had a client who wanted all fields in the database searchable. This was fairly easy to do. I just looked up all the keys in ApplicationResources.properties which contained "Form." and then put them into a drop-down. On the UI, the user was able to enter a search term and select the column they wanted to search. I was glad I followed this Form vs. Detail distinction on that project!''
Recentemente tive um cliente que queria que todos os campos do banco de dados fossem procuráveis. Isto foi fácil de fazer. Apenas procurei todas as chaves no arquivo ApplicationResources.properties que contém o padrão "Form." e os coloquei em um drop-down(select). Na UI, o usuário podia entrar com um termo de busca e selecionar a coluna uqe ele necessitava procurar. Fiquei feliz em ter seguido a distinção Form vs. Detail naquele projeto!''
At line 74 changed 2 lines.
!!Create PersonFormControllerTest to test PersonFormController [#2]
To create a JUnit Test for the PersonFormController, start by creating a PersonFormControllerTest.java file in the test/web/**/action directory.
!!Crie o PersonFormControllerTest para testar o PersonFormController [#2]
Para criar um teste JUnit para o PersonFormController, comece criando um arquivo PersonFormControllerTest.java no diretório test/web/**/action.
At line 144 changed 1 line.
Nothing will compile at this point (ant compile) because you need to create the PersonFormController that you're referring to in this test.
Nada irá compilar agora (ant compile) porque é necessário criar o PersonFormController referenciado neste teste.
At line 147 changed 1 line.
!!Create PersonFormController [#3]
!!Crie o PersonFormController [#3]
At line 149 changed 1 line.
In src/web/**/action, create a PersonFormController.java file with the following contents:
Em src/web/**/action, crie um arquivo PersonFormController.java com o seguinte conteúdo:
At line 234 changed 1 line.
In the class above, there are a few methods you might not be familiar with. The {{formBackingObject()}} method is used to supply the object this Controller operates on. The {{processFormSubmission()}} method is used to detect the cancel button, and {{onSubmit()}} is called on POST requests and handles delete/add/update of a user.
Na classe acima, existem alguns métodos que você pode não estar familiarizado. O método {{formBackingObject()}} é utilizado para fornecer o objeto que este Controller opera. O método {{processFormSubmission()}} é utilizado para detectar o botão cancel, e o {{onSubmit()}} é chamado em requisições POST e manipula remoção/adição/alteração no formulário.
At line 236 changed 1 line.
There are a few keys you (might) need to add to ApplicationResources.properties to display the success messages. This file is located in ''web/WEB-INF/classes'' - open it and add the following:
Existem algumas chaves que você (deve) adicionar ao arquivo ApplicationResources.properties para mostrar as mensagens de sucesso. Este arquivo é localizado em ''web/WEB-INF/classes'' - abra e adicione o seguinte:
At line 238 changed 1 line.
;:''I usually add these under the {{# -- success messages --}} comment.''
;:''Geralmente eu adiciono abaixo do comentário {{# -- Mensagens de Sucesso --}}.''
At line 240 changed 3 lines.
{{{person.added=Person has been added successfully.
person.updated=Person has been updated successfully.
person.deleted=Person has been deleted successfully.
{{{person.added=A Pessoa foi adicionada com sucesso.
person.updated=A Pessoa foi alterada com sucesso.
person.deleted=A Pessoa foi removida com sucesso.
At line 245 changed 1 line.
You could use generic ''added'', ''deleted'' and ''updated'' messages, whatever works for you. It's nice to have separate messages in case these need to change on a per-entity basis.
Você pode utilizar mensagens genéricas para ''added'', ''deleted'' and ''updated'', o que melhor funcionar para você. É bom separar mensagens caso seja necessária uma mudança baseada por entidade.
At line 247 changed 1 line.
You might notice that the code we're using to call the PersonManager is the same as the code we used in our PersonManagerTest. Both PersonFormController and PersonManagerTest are ''clients'' of PersonManagerImpl, so this makes perfect sense.
Você pode notar que o código que estamos utilizando para chamar o PersonManager é o mesmo que chamamos em nosso PersonManagerTest. Tanto o PersonFormController quanto o PersonManagerTest são ''clientes'' do PersonManagerImpl, o que faz sentido.
At line 249 changed 1 line.
Now you need to add a url-mapping for this controller in the web/WEB-INF/action-servlet.xml file. In the block below, the new line is at the bottom, with __&lt;prop key="/editPerson.html"&gt;__:
Agora vamos precisar adicionar o mapeamento url para este controller no arquivo web/WEB-INF/action-servlet.xml. No bloco abaixo, uma linha nova está na parte inferior, com __&lt;prop key="/editPerson.html"&gt;__:
At line 270 changed 1 line.
You also need to add the &lt;bean&gt; definition for personFormController in this same file:
Também é necessário adicionar a definição &lt;bean&gt; para o personFormController no mesmo arquivo:
At line 284 changed 1 line.
;:''The "validator" property is commented out in the above XML block because we haven't defined any validation rules for the Person object. We'll uncomment this value when we add validation.''
;:''A propriedade "validator" está comentada no bloco XML acima porque não definimos nenhuma regra de validações para o objeto Person. Removeremos este comentário quando adicionarmos a validação.''
At line 286 changed 2 lines.
!!Run the PersonFormControllerTest [#4]
If you look at our PersonFormControllerTest, all the tests depend on having a record with id=1 in the database (and testRemove depends on id=2), so let's add those records to our sample data file (metadata/sql/sample-data.xml). I'd just add it at the bottom - order is not important since it (currently) does not relate to any other tables.
!!Rode o PersonFormControllerTest [#4]
Se você olhar nosso PersonFormControllerTest, todos os testes dependem de um registro com o id=1 no banco de dados (e o testRemove depende do id=2), então vamos adicionar estes registros em nosso arquivo de dados para teste (metadata/sql/sample-data.xml). Apenas adiciono eles ao final - a ordem não é importante porque (atualmente) não é relacionado com outras tabelas.
At line 307 changed 1 line.
DBUnit loads this file before we running any of the tests, so this record will be available to your Controller test.
O DBUnit carrega o arquivo antes de rodarmos qualquer teste, então os registros serão disponibilizados para os testes do nosso Controller.
At line 309 changed 1 line.
Make sure are in the base directory of your project. If you run __ant test-web -Dtestcase=PersonFormController__ - everything should work as planned.
Certifique-se que está no diretório base de seu projeto. Se você rodar __ant test-web -Dtestcase=PersonFormController__ - tudo deve funcionar como planejado.
At line 315 changed 1 line.
!!Clean up the JSP to make it presentable [#5]
!!Limpe o JSP para deixá-lo apresentável [#5]
At line 317 changed 1 line.
If you want to add a usability enhancement to your form, you can set the cursor to focus on the first field when the page loads. Simply add the following JavaScript at the bottom of your form:
Se você quer adicionar uma melhoria de utilização para seu formulário, você pode setar o cursor para focar no seu primeiro campo quando a página carregar. Simplesmente adicione o seguinte JavaScript na parte inferior do arquivo:
At line 323 changed 1 line.
Now if you execute __ant db-load deploy__, start Tomcat and point your browser to [http://localhost:8080/appfuse/editPerson.html?id=1], you should see something like this:
Agora se você executar __ant db-load deploy__, iniciar o Tomcat e apontar seu navegador para [http://localhost:8080/appfuse/editPerson.html?id=1]. Você terá um resultado semelhante a este:
At line 325 changed 2 lines.
%%(border: 1px solid black; margin: 0 auto; height: 166px; width: 337px)
[CreateActions/personForm-final.png]
%%(border: 1px solid black; margin: 0 auto; height: 183px; width: 418px)
[editPerson.PNG]
At line 329 changed 1 line.
Finally, to make this page more user friendly, you may want to add a message for your users at the top of the form, but this can easily be done by adding text (using &lt;fmt:message&gt;) at the top of the personForm.jsp page.
Finalmente, para deixar esta página mais amigável, você pode adicionar uma mensagem para seu usuário na parte superior do seu formulário, o que pode ser feito facilmente (usando a tag &lt;fmt:message&gt;) na parte superior de sua página personForm.jsp.
At line 331 changed 2 lines.
!![[Optional] Create a Canoo WebTest to test browser-like actions [#6]
The final (optional) step in this tutorial is to create a [Canoo WebTest|http://webtest.canoo.com] to test the JSPs.
!![[Opcional] Crie Canoo WebTests para testar ações comuns de navegador [#6]
O passo final (opcional) para este tutorial é criar um [Canoo WebTest|http://webtest.canoo.com] para testar osJSPs.
At line 334 changed 1 line.
;:''I say this step is optional, because you can run the same tests through your browser.''
;:''Digo que este teste é opcional porque você pode rodar os mesmos testes no seu navegador.''
At line 336 changed 1 line.
You can use the following URLs to test the different actions for adding, editing and saving a user.
Você pode utilizar as seguintes URLs para testar diferentes ações para adicionar, editar e salvar uma pessoa.
At line 338 changed 4 lines.
* Add - [http://localhost:8080/appfuse/editPerson.html].
* Edit - [http://localhost:8080/appfuse/editPerson.html?id=1] (make sure and run __ant db-load__ first).
* Delete - [http://localhost:8080/appfuse/editPerson.html?method=Delete&amp;id=1] (or edit and click on the Delete button).
* Save - Click [edit|http://localhost:8080/appfuse/editPerson.html?id=1] and then click the Save button.
* Adicionar - [http://localhost:8080/appfuse/editPerson.html].
* Editar - [http://localhost:8080/appfuse/editPerson.html?id=1] (certifique-se de rodar antes __ant db-load__).
* Remover - [http://localhost:8080/appfuse/editPerson.html?method=Delete&amp;id=1] (ou edite um registro e clique o botão Remover).
* Salvar - Clique [edit|http://localhost:8080/appfuse/editPerson.html?id=1] e então clique o botão Salvar.
At line 343 changed 1 line.
Canoo tests are pretty slick in that they're simply configured in an XML file. To add tests for add, edit, save and delete, open test/web/web-tests.xml and add the following XML. You'll notice that this fragment has a target named ''PersonTests'' that runs all the related tests.
Testes Canoo são simples, configurados apenas por um arquivo XML. Para adicionarmos testes para as operações CRUD(add, edit, save e delete), abriremos test/web/web-tests.xml e adicionaremos o seguinte XML. Note que este fragmento possui um alvo(target) nomeado ''PersonTests'' que executa todos os testes relacionados.
At line 345 changed 1 line.
;:''I use CamelCase target names (vs. the traditional lowercase, dash-separated) because when you're typing ''-Dtestcase=Name'', I've found that I'm used to doing CamelCase for my JUnit Tests.''
;:''Utilizo notação composta(CamelCase) para os nomes de alvos (target)(vs. letras minúsculas tradicionais, separadas por hífen) por causa das execuções utilizando o JUnit, como por exemplo, ''-Dtestcase=Name'', Percebi que estou acostumado com a notação composta para meus testes JUnit.''
At line 425 changed 1 line.
After adding this, you should be able to run __ant test-canoo -Dtestcase=PersonTests__ with Tomcat running or __ant test-jsp -Dtestcase=PersonTests__ if you want Ant to start/stop Tomcat for you. To include the PersonTests when all Canoo tests are run, add it as a dependency to the "run-all-tests" target.
Após adicionar isto, seremos capazes de rodar __ant test-canoo -Dtestcase=PersonTests__ com o Tomcat rodando ou __ant test-jsp -Dtestcase=PersonTests__ se quisermos que o Ant inicialize e pare o Tomcat. Para incluir o PersonTests quando todos os testes canoo são executados, adicionaremos sua dependência ao alvo(target) "run-all-tests".
At line 427 changed 1 line.
You'll notice that there's no logging in the client-side window by Canoo. If you'd like to see what it's doing, you can add the following between &lt;/webtest&gt; and &lt;/target&gt; at the end of each target.
Você perceberá que não há registro(logging) na janela cliente do canoo. Se desejarmos ver o que o Canoo está fazendo, podemos adicionar o seguinte código entre &lt;/canoo&gt; e &lt;/target&gt; no final do alvo(target).
At line 439 changed 1 line.
''Next Up:'' __Part IV:__ [Adding Validation and List Screen|ValidationAndListSpring] - Adding validation logic to the personForm so that firstName and lastName are required fields and adding a list screen to display all person records in the database.
''Próximo:'' __Parte IV:__ [Adicionando Validação e Tela de Listagem|ValidationAndListSpring_pt] - Adicionando lógica de validação para o personForm para que o firstName e o lastName sejam campos obrigatórios, e adicionando uma tela de listagem para mostrar todas as tuplas de pessoas no banco de dados.

Back to SpringControllers_pt, or to the Page History.