Cliente NOSi – igrpweb Referência
Versão 1.00 Status
Programando em
igrpweb
C ONTEÚDO
Enquadramento ... 3
1 O básico do input e output – Table e Form... 4
1.1 Página List_page ... 4
1.2 Página Form_page ... 9
2 Parâmetros [envio e captura] ... 13
3 Filtros ... 20
4 Criando um Webservice em igrpweb ... 23
E
NQUADRAMENTONeste documento abordamos técnicas de programação em igrpweb. Enquanto que em Utilizando Fields / Campos e em Utilizando Componentes abordamos a forma de programar cada Field e Componente, respetivamente, aqui tentamos ver a programação de forma mais abrangente visando entender a melhor forma de programar no nosso framework.
Com certeza tem como conteúdo complementar o abordado nos documentos acima e o tratado em Interagindo com a Base de Dados.
1 O
BÁSICO DO INPUT E OUTPUT– T
ABLE EF
ORMEnquanto elementos básicos e fundamentais para qualquer aplicação, achamos conveniente começar com duas páginas, List_page com um Table e Form_page com um Form. O igrpweb conta com o CRUD Generator [abordado no documento Funcionalidades Essenciais], uma ferramenta capaz de gerar para cada tabela da DB duas páginas [List_page e Form_page] que nos permitem fazer operações de insert, select, update e delete utilizando querys. Vamos neste capítulo entender como funciona a interação destas duas páginas no igrpweb.
Para facilitar a compreensão, vamos começar com uma BD com uma tabela.
Fig 1 – Table person na base de dados
1.1 Página List_page
Fig 2 – Table
Constituição da página [ List_page ]:
Section Header;
Table [person_table
]:
Text first_name;
Text last_name;
Hidden id, Integer, definido como isKey, para que seja enviado como parâmetro pelos botões de tabela;
Button edit invoca o método actionAdd inviando o id da linha correspondente. Este chama a página Form_page enviando o id para editar o person dessa linha:
Target = Submit Modal;
Action = Form_page;
Refresh parent;
Button delete invoca o método actionDelete na mesma página enviando o id como parâmetro para eliminar a person da linha correspondente:
Target = Submit;
Action = List_age;
Tools Bar
Button Add - invoca o método actionAdd, que chama a Form_page, que se abre em um modal, permitindo a insersão de um novo person:
Target = Modal;
Action = Form_page;
Refresh parent;
Para eventuais dúvidas sobre a programação de Table podemos consultar o documento Utilizando Listas, onde se encontra detalhado o processo, pois aqui pretendemos entender a página.
Programando com dao class
Imports
/*----#start-code(packages_import)----*/
import nosi.webapps.demo.dao.Person; // dao class import java.util.ArrayList;
import java.util.List;
/*----#end-code----*/
Método actionIndex – executado ao carregar a página, preenche o Table.
/*----#start-code(index)----*/
// getting data from DB–table person
List<Person> personList = new Person().findAll();
if( personList != null ){
// creating a list of the type person (this is the table on the page)
List<List_page.Person_table> personTable = new ArrayList<List_page.Person_table>();
// copying data from personList to personTable for( Person p: personList ){
// creating a row for the table
Person_list_page.Person_table row = new Person_list_page.Person_table();
// filling the row
row.setFirst_name( p.getFirstName() );
row.setLast_name( p.getLastName() );
row.setId( p.getId() );
// adding row to the table personTable.add( row );
}
// inserting the table in model
model.setPerson_table( personTable );
} else {
Core.setMessageInfo( "No results found." );// error getting data from DB }
/*----#end-code----*/
Método actionAdd – executado quando acionamos o button add /*----#start-code(add)----*/
/*----#end-code----*/
Neste método não precisamos fazer nada, pois o código gerado é suficiente para abrir a outra página em um Modal.
Método actionEdit – executado quando acionamos o Button edit /*----#start-code(edit)----*/
this.addQueryString("isEdit", "true");
this.addQueryString("p_id", Core.getParamInt("p_id")); // receiving and sending id as parameter /*----#end-code----*/
Como o Button edit envia o id como p_id, capturamo-lo e enviamos para a página invocada pelo método [ Form_page ] para realizar a edição. O parâmetro isEdit é utilizado para assinalar ao actionIndex da
página invocada, que queremos editar e não inserir novos dados. Logo deve buscar na BD os dados referentes ao id enviado [no caso p_id] para edição.
Método actionDelete – executado quando acionamos o Button delete /*----#start-code(delete)----*/
Integer personId = Core.getParamInt("p_id");
if( Core.isNotNullOrZero( personId ) ) {
Person person = new Person().findOne( personId );
if ( person!=null && !person.hasError() ) {
boolean del = person.delete( person.getId() ); // deleting row from db if (del == true)
Core.setMessageSuccess( "Person deleted from DB successfully!" );
else
Core.setMessageError( "Error deleting person from DB!" );
} else {
Core.setMessageError( person.getError().toString() );// error getting person from DB }
} else {
Core.setMessageError( "Id not valid!" );
}
/*----#end-code----*/
Este método também recebe o id [ p_id ] do objeto a eliminar enviado pelo Button delete e realiza a ação desejada na BD.
Programando com query
Método actionIndex – executado ao carregar a página /*----#start-code(index)----*/
String connection = Core.defaultConnection();
// creating a query to select data from DB QueryInterface query = Core.query( connection,
"SELECT id as id, first_name as first_name, last_name as last_name FROM public.person");
// loading the query on the table model.loadTable_person( query );
/*----#end-code----*/
Aqui cada atributo deve ser selecionado com o nome do campo correspondente no Table [da página List_page ]. Caso contrário não funcionará.
Método actionDelete – executado quando acionamos o Button delete /*----#start-code(delete)----*/
ResultSet result = Core.delete( Core.defaultConnection(), "public", "person" ) .where( "id=:id_" )
.addInt( "id_", Core.getParamInt("p_id") ) .execute();
if( !result.hasError() )
Core.setMessageSuccess();
else
Core.setMessageError( r.getError().toString() );
/*----#end-code----*/
1.2 Página Form_page
Fig 3 – Form
A nossa segunda página [ Form_page ] é constituida por um Form onde podemos inserir um novo person, ou, caso receba um id como parâmetro vai à base de dados buscar os dados do person correspondente para edição. Esta página é constituída por:
Form person_form;
Text first_name;
Text last_name;
Hidden id, Integer;
Tools Bar:
Button save - configurado como action submit, executa o método actionSave:
Target – Submit;
Action – Form_Page;
Programando com dao class Imports
/*----#start-code(packages_import)----*/
import nosi.webapps.demo.dao.Person;
/*----#end-code----*/
Método actionIndex – executado quando a página é chamada /*----#start-code(index)----*/
if( Core.isNotNull( Core.getParam("isEdit") ) ) {
// creating na object of type person and getting data from DB Person person = new Person().findOne( model.getId() );
if ( person != null && !person.hasError() ){
// filling form with data to edit
model.setFirst_name( person.getFirstName() );
model.setLast_name( person.getLastName() );
} else {
Core.setMessageError( person.getError().toString() ); // error finding person on DB }
}
/*----#end-code----*/
O parâmetro isEdit Assinala que estamos a chamar a página através do Button edit, logo através do id, que também é recebido vamos a BD buscar os dados para edição.
Aqui recebemos o id do person através do Model porque a classe correspondente contém um campo de nome id, que na geração da página foi mapeado para receber um parâmetro de nome p_id, através deste código:
@RParam(rParamName = "p_id") private int id;
Caso tivessemos enviado o parâmetro com outro nome deveríamos recebê-lo através da classe Core [Saber mais a respeito de Parâmetros].
Método actionSave /*----#start-code(save)----*/
Person person = new Person( ); // creating na object of type Person if( ! Core.isNullOrZero( model.getId() ) )
person = person.findOne( model.getId() );
// getting the input data
person.setFirstName( model.getFirst_name() );
person.setLastName( model.getLast_name() );
// saving on DB
if( Core.isNullOrZero( model.getId() ) ) person = person.insert();
else
person = person.update();
// checking errors
if ( person != null && !person.hasError() ) { Core.setMessageSuccess();
} else {
Core.setMessageError( person.getError() ); // error inserting person on DB return this.forward("demo_app","Person_page","index");
}
/*----#end-code----*/
Notemos que o id não foi enviado como parâmetro, pois já se encontrava no Model.
O retorno com o método forward, em caso de erro, permite que os dados de input sejam repostos no Form, logo sem a necessidade de voltar a preenchê-lo.
Programando com query
Método actionIndex /*----#start-code(index)----*/
if( Core.isNotNull( Core.getParam("isEdit") ) ){ // getting data from DB
QueryInterface query = Core.query( Core.defaultConnection(), "SELECT id as id, first_name as first_name,"
+" last_name as last_name"
+" FROM public.person"
+" WHERE id="+ model.getId() ); // model receives id as a parameter // loading data on model / setting data on form fields
model.load( query );
}
/*----#end-code----*/
Método actionSave /*----#start-code(save)----*/
ResultSet result = null;
if( Core.isNullOrZero( model.getId() ) ) // inserting a new person on DB result = Core.insert( Core.defaultConnection(), "public", "person") .addString( "first_name", model.getFirst_name() ) .addString( "last_name", model.getLast_name() ) .execute();
else // updating a person on DB
result = Core.update( Core.defaultConnection(), "public", "person") .addString( "first_name", model.getFirst_name() ) .addString( "last_name", model.getLast_name() ) .where( "id=:id_" )
.addInt( "id_", model.getId() ) .execute();
// checking errors if ( !result.hasError() ){
Core.setMessageSuccess();
} else {
Core.setMessageError( result.getError() );
return this.forward("demo_app","Person_form","index", this.queryString() );
}
/*----#end-code----*/
O retorno com o método forward em caso de erro permite que os dados de input sejam repostos no Form, logo sem a necessidade de o voltar a preencher.
2 P
ARÂMETROS[
ENVIO E CAPTURA]
Depois de entendermos o funcionamento da tabela e do formulário, vamos agora ver as formas de enviar e receber parâmetros no igrpweb, já que se trata de um dos aspetos fundamentais para a comunicação entre páginas e aplicações.
Note que quando invocamos um método de um ficheiro Controller diferente, para enviarmos parâmetros devemos incluir na lista de parâmetros do método de retorno [que retorna um Response – ex: métodos redirect e forwoard] o quarto parâmetro [ this.queryString() ], que consiste na lista de parâmetros a serem enviados.
Ex1:
return this.redirect("demo_application","DemoPage","index");
Neste exemplo os parâmetros definidos na página somente terão efeito se ela chamar a si mesma. Caso ela chame outra página os parâmetros não serão enviados, sendo para isso necessário o quarto parâmetro.
Ex1:
return this. redirect("demo_application","DemoPage","index", this.queryString() );
Aqui os parâmetros sempre serão enviados independendo de que página será chamada.
1. Formas de envio de Parâmetros
1.1. Método forward
O Controller oferece um método para retorno / invocação de páginas, que envia todos os dados do Model como parâmetros, cada um destes assumindo o nome do campo correspondente precedido do prefixo p_. Assim o campo date será enviado como um parâmetro de nome p_date.
Exemplo:
return this.forward("demo_application","DemoPage","index");
Do mesmo modo que no exemplo anterior, se estivermos invocando uma página diferente, devemos incluir o quarto parâmetro [ this.queryString() ].
1.2. Método addQueryString
Este é o método padrão de passagem de parâmetros no igrpweb e pode ser utilizado na maioria dos casos.
Permite passar os mais variados tipos de valores, que podem ser recebidos por métodos listados mais a frente neste capítulo. Não funciona no método actionIndex.
Segue a estrutura this.addQueryString( nomeDoParametro, valor );
Exemplos:
Integer personId = 11;
this.addQueryString( "personId", personId );
String name = "John Doe";
this.addQueryString( "name", name);
1.3. Método loadQueryString
Este é o método a ser utilizado quando queremos enviar todos os dados do Model como parâmetros. Os dados podem ser recebidos como um Map. Não funciona no método actionIndex.
Exemplo:
this.loadQueryString();
Recebido assim:
Map <String, String[]> parameters = Core.getParameters();
Obs: esses parâmetros também podem ser recebidos individualmente, caso for conveniente para o programador. Neste caso deve receber cada um pelo nome segundo as formas de receção mais a frente abordadas.
1.4. Método setLink [associação de parâmetros a botões]
Existe a opção de associar parâmetros a botões. No caso do exemplo a seguir, consideremos a existência de um botão de nome save, responsável por enviar o parâmetro id. Preste atenção no parâmetro do método setLink. Este é um dos métodos utilizados para envio de parâmetros a partir do método actionIndex, pois o seu retorno não permite o envio do parâmetro this.queryString().
Exemplo 1:
Integer id = 26;
view.btn_save.setLink("save&id="+ id.toString() );
Exemplo 2:
String name = "John Doe";
view.btn_save.setLink("save&name="+ name );
1.5. Método addParam [associação de parâmetros a lookup e locator]
De forma similar ao método setLink, o método addParam permite associar parâmetros ao lookup e ao locator, que também pode ser utilizado dentro do método actionIndex ou qualquer outro.
Se por exemplo, temos um lookup cuja tag é coordinator podemos enviar o parâmetro department_id através dele com o código:
String departmentId = "14";
view.coordinator.addParam( "department_id", departmentId );
1.6. Lookup
Fig 4 – Lookup
O lookup tem um espaço onde podemos escrever, sempre que não estiver configurado como readonly ou disabled. Logo o texto nele inserido é enviado como um parâmetro de nome p_fwl_search sempre que o respetivo botão for acionado. Esse parâmetro deve ser recebido assim:
String wordToSearch = Core.getParam( "p_fwl_search" );
1.7. Botões de Tabela com campos isKey
Quando temos botões em tabelas podemos enviar parâmetros através deles parâmetros correspondem a valores de determinadas colunas nas respetivas linhas.
Fig 5 – Botões de tabela [exemplo]
Fig 6 – Propriedades de campo de tabela
Configuramos o campo que pretendemos enviar como isKey [Fig 6] sendo este um id para auxiliar na ação realizada pelo botão. O parâmetro tem o nome da tag do campo com o prefixo p_. Assim o campo id será enviado como p_id. e será recebido conforme o código a seguir, por exemplo:
Integer id = Core.getParamInt( "p_id" );
1.8. Campos Hidden
Com os campos do tipo hidden não há propriamente um envio de parâmetro e sim o armazenamento de valores no Model pelo método actionIndex, e posteriormente sua leitura pelo método invocado, desde que a página esteja invocando a si mesma. Caso contrário não funcionrá.
No exemplo a seguir temos um formulário onde registamos ou editamos os dados de uma pessoa. Nos casos de edição podemos inserir o id da pessoa no hidden id, assinalado na Fig 7, e em seguida no método do botão save – actionSave, fazemos a leitura desse valor para nos auxiliar na realização da ação desejada.
Fig 7 – Campo Hidden numa tabela
Método actionIndex /*----#start-code(index)----*/
// …
Integer personId = 11;
model.setPerson_id( personId );
// …
Método actionSave /*----#start-code(save)----*/
// …
Integer personId = model.getPerson_id();
// …
2. Formas de captura de Parâmetros
2.1. Mapeamento de fields no Model
Quando desenhamos uma página os campos que suportam dados como texto data number, etc, são representados no Model e automaticamente mapeados para receber um parâmetro que tenha o mesmo nome da sua tag com o prefixo p_ , como podemos ver no exemplo seguinte. O campo first_name está mapeado para o parâmetro p_first_name. É este mapeamento que faz funcionar o método this.forward funcionar.
// …
public class Add_emplyee extends Model {
@RParam(rParamName = "p_first_name") private String first_name;
@RParam(rParamName = "p_last_name") private String last_name;
// …
Esta configuração pode facilitar o trabalho do programador quando for necessário enviar parâmetros que serão capturados e posteriormente inseridos em determinados campos. Para estes casos basta enviá-los com o nome com que estão a ser esperados.
2.2. Métodos do Core
A classe Core oferece um conjunto de métodos capazes de receber os mais diversos tipos de parâmetros.
Funcionam com a estrutura Core.getParam( String paramName ) e esta é a forma padrão de receber parâmetros no igrpweb.
String name = Core.getParam("p_name");
O nome do método varia conforme o tipo de dados a ser capturado e geralmente recebe o nome do parâmetro esperado. Na tabela a seguir temos a lista dos métodos e o tipo de dados que retornam.
Método Retorno
Core.getParam( "paramName" ); String
Core.getParamArray( "paramName" ); String[]
Core.getParamInt( "paramName" ); Integer
Core.getParamShort( "paramName" ); Short
Core.getParamLong( "paramName" ); Long
Core.getParamFloat( "paramName" ); Float
Core.getParamDouble( "paramName" ); Double
Core.getParameters(); Map < String, String[]>
Notemos que o método Core.getParameters recebe todos os parâmetros enviados à página e que, por isso, dispensa o nome de parâmetros. Para os casos onde enviamos os parâmetros com o método this.loadQueryString é aconselhável o uso deste método. Entretanto ele pode ser utilizado sempre que o programador achar conveniente.
Map < String, String[]> allParameters = Core.getParameters();
2.3. Métodos do Controller
Do mesmo modo que o Core o Controller também oferece vários métodos de captura de parâmetros listados na tabela a seguir que funcionam de forma similar e destinados à captura dos mais diversos tipos de parâmetros.
Método Retorno
this.getQueryString( "paramName" ); String
this.getQueryArray( "paramName" ); String[]
this.getQueryStringInteger( "paramName" ); Integer
this.getQueryStringShort( "paramName" ); Short
this.getQueryStringLong( "paramName" ); Long
this.getQueryStringFloat( "paramName" ); Float
this.getQueryStringDouble ( "paramName" ); Double
3 F
ILTROSAproveitando o exemplo da tabela anterior [Fig 2], vamos implementar um filtro para facilitar listagem de dados numa tabela. Adicionamos à página [Fig 8] um formulário com dois textfields, cujas tags são, respetivamente, first_name_filter e last_name_filter e um botão search para disparar o processo de filtragem.
Fig 8 – Página com filtro
Configuramos o botão search conforme a figura seguinte, ativando a propriedade Custom return, pois pretendemos alterar o método de retorno, e implementamos o método correspondente para enviar todos os dados do Model como parâmetros:
Método actionSearch /*----#start-code(search)----*/
return this.forward( "demo", "PersonList", "index" );
/*----#end-code----*/
Fig 9 – Configuração de botão de pesquisa
Implementação utilizando dao class
Método actionIndex /*----#start-code(index)----*/
Person person = new Person().find();
if( model.getFirst_name_filter() != null && !model.getFirst_name_filter().isEmpty() ) person.andWhere( "firstName", "like", "%"+ model.getFirst_name_filter() +"%" );
if( model.getLast_name_filter() != null && !model. getLast_name_filter().isEmpty() ) person.andWhere( "lastName", "=", model.getLast_name_filter() );
List<Person> personList = person.all();
if( personList != null ) {
List<Table_demo.Person_table> personTable = new ArrayList<Table_demo.Person_table>();
for( Person p: personList ) {
Table_demo.Person_table row = new Table_demo.Person_table();
row.setFirst_name( p.getFirstName() );
row.setLast_name( p.getLastName() );
row.setId( p.getId() );
personTable.add( row );
}
model.setPerson_table( personTable );
} else {
Core.setMessageInfo( "No results found." );// error getting data from DB }
/*----#end-code----*/
Implementação utilizando query
Método actionIndex /*----#start-code(index)----*/
String queryString = "SELECT id as id, first_name as first_name, last_name as last_name
FROM public.person WHERE 1=1 ";
if( model.getFirst_name_filter() != null && !model.getFirst_name_filter().isEmpty() ) queryString += " AND first_name like '%" + model.getFirst_name_filter() + "%' ";
if( model.getLast_name_filter() != null && !model. getLast_name_filter().isEmpty() ) queryString += " AND last_name = '"+ model.getLast_name_filter() +"' ";
QueryInterface queryInterface = Core.query( Core.defaultConnection(), queryString );
model.loadPerson_table( queryInterface );
/*----#end-code----*/
4 C
RIANDO UMW
EBSERVICE EM IGRPWEBPáginas igrpweb podem retornar uma resposta em formato XML, JSON, entre outros, ou seja, funcionar como um webservice a ser consumido por outra aplicação.
Para isso criamos uma página [My_service], que deve ser definida como public, para que possa ser invocada de fora da aplicação correspondente, e o Link respetivo deve ser utilizado para invocar o serviço.
Então, após criarmos a página devemos gerar o seu conteúdo [classes java e outros constituintes como XML, XSL, etc]. Para isso abrimo-la no Gerador de Código através do botão [Fig 10] e fazemos click sobre o botão [Fig 11].
Fig 10
Fig 11
Em seguida devemos programar o serviço dentro do método acitonIindex, pois este é executado quando a página é invocada.
Como é necessário alterar o retorno e este encontra-se na parte do código protegida pelo Gerador de Código, vamos utilizar o File Editor que permite alterar as partes protegidas do código.
Assim comentamos as linhas assinaladas pela cor azul no código abaixo e programamos o nosso serviço.
Neste exemplo estamos a retornar um XML mas podia ser um JSON.
Classe My_service_pageController
package nosi.webapps.igrpweb_demo.pages.my_service;
import nosi.core.webapp.Controller;
import nosi.core.webapp.databse.helpers.ResultSet;
import nosi.core.webapp.databse.helpers.QueryInterface;
import java.io.IOException;
import nosi.core.webapp.Core;
import nosi.core.webapp.Response;
/*----#start-code(packages_import)----*/
import nosi.webapps.igrpweb_demo.person_info_service.Content;
import nosi.webapps.igrpweb_demo.person_info_service.Address;
import nosi.webapps.igrpweb_demo.person_info_service.Person;
import nosi.webapps.igrpweb_demo.daoservice.TblPerson;
import nosi.webapps.igrpweb_demo.daoservice.TblAddress;
import java.util.List;
import java.util.ArrayList;
import java.io.StringWriter;
import javax.xml.bind.JAXB;
/*----#end-code----*/
public class My_serviceController extends Controller {
public Response actionIndex() throws IOException, IllegalArgumentException, IllegalAccessException{
My_service model = new My_service();
model.load();
My_serviceView view = new My_serviceView();
/*----#start-code(index)----*/
// Getting data from db
List<TblPerson> personTblList = new TblPerson().findAll();
// creating the content to be serialized and filling it Content content = new Content();
ArrayList<Person> personList = new ArrayList<>();
for ( TblPerson tblPerson: personTblList ) { Person person = new Person();
person.setName( tblPerson.getName() );
person.setGender( tblPerson.getGender() );
person.setBirth_date( tblPerson.getBirthdate() );
ArrayList<Address> addressList = new ArrayList<>();
tblPerson.getTblAddresses().forEach( tblAddress -> { Address address = new Address();
address.setStreet( tblAddress.getStreet() );
address.setApt_suite( tblAddress.getAptSuite() );
address.setState_province( tblAddress.getStateProvince() );
address.setCity( tblAddress.getCity() );
address.setCountry( tblAddress.getCountry() );
addressList.add( address );
});
person.setAddress_list( addressList );
personList.add( person );
}
content.setPerson_list( personList );
// serializing the content to the XML to be returned StringWriter sw = new StringWriter();
JAXB.marshal( content, sw );
String xmlString = sw.toString();
this.format = Response.FORMAT_XML; // or this.format = Response.FORMAT_JSON;
return this.renderView( xmlString );
/*----#end-code----*/
//view.setModel(model);
//return this.renderView(view);
}
/*----#start-code(custom_actions)----*/
/*----#end-code----*/
}
As classes que representam os dados devem ser preparadas/mapeadas para serialização. No caso serão serializados em XML.
Classe Content – representa todo o conteúdo a ser retornado pelo serviço package nosi.webapps.igrpweb_demo.my_service;
import java.util.List;
public class Content {
private List<Person> person_list;
public Content () {}
public void setPerson_list( List<Person> person_list ) { this.person_list = person_list;
}
public List<Person> getPerson_list() { return this.person_list;
} }
Classe Person – representa os dados de uma pessoa package nosi.webapps.igrpweb_demo.my_service;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
@XmlAccessorType(XmlAccessType.FIELD) public class Person {
@XmlAttribute(name="id") private Integer id;
private String name;
private String gender;
private String birth_date;
private List<Address> address;
public Person() {}
public Integer getId() { return id;
}
public void setId( Integer id ) { this.id = id;
}
public String getName() { return name;
}
public void setName( String name ) { this.name = name;
}
public String getGender() { return gender;
}
public void setGender( String gender ) { this.gender = gender;
}
public String getBirth_date() { return birth_date;
}
public void setBirth_date( String birth_date ) { this.birth_date = birth_date;
}
public List<Address> getAddress() { return address;
}
public void setAddress( List<Address> address ) { this.address = address;
} }
Classe Address – representa cada um dos endereços de uma pessoa package nosi.webapps.igrpweb_demo.my_service;
public class Address { private String street;
private String apt_suite;
private String city;
private String state_province;
private String country;
public Address() {}
public String getStreet() { return street;
}
public void setStreet(String street) { this.street = street;
}
public String getApt_suite() { return apt_suite;
}
public void setApt_suite( String apt_suite ) { this.apt_suite = apt_suite;
}
public String getCity() { return city;
}
public void setCity( String city ) { this.city = city;
}
public String getState_province() { return state_province;
}
public void setState_province( String state_province ) { this.state_province = state_province;
}
public String getCountry() { return country;
}
public void setCountry( String country ) { this.country = country;
} }
De acordo com as classes acima a estrutura do XML será esta:
<content>
<person id="1">
<name>John Doe</name>
<gender>Male</gender>
<birth_date>28-08-1900</birth_date>
<address>
<street>Jonhn Street1</street>
<apt_suite>John Ap12</apt_suite>
<city>John City</city>
<state_province>John State</state_province>
<country>John Country</country>
</address>
<address>
<street>Pedonal</street>
<apt_suite>No XX, Ap YY</apt_suite>
<city>Praia</city>
<state_province>Santiago</state_province>
<country>Cape Verde</country>
</address>
</person>
<person id="2">
<name>Anne Frank</name>
<gender>Female</gender>
<birth_date>12-06-1929</birth_date>
<address>
<street>Anne Frank Street</street>
<apt_suite>No X1, Ap Y2</apt_suite>
<city>Amsterdam</city>
<state_province>Amsterdam</state_province>
<country>Netherlands</country>
</address>
</person>
</content>