Author |
Message |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 10/04/2007 07:42:33
|
saoj
Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline
|
- Validação:
O Struts2 oferece validação via XML ou Annotations.
A documentação do Struts2 continua sendo, na minha opinião, pouco objetiva e pouco clara. Clique aqui para acessar a documentação oficial sobre validação, e tire suas próprias conclusões. Repare que não há nenhum código Java, apenas XML.
Validação via XML: (repare que existe código Java dentro do XML !!!! )
Code:
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<!-- Field Validators for email field -->
<field name="email">
<field-validator type="required" short-circuit="true">
<message>You must enter a value for email.</message>
</field-validator>
<field-validator type="email" short-circuit="true">
<message>Not a valid e-mail.</message>
</field-validator>
</field>
<!-- Field Validators for email2 field -->
<field name="email2">
<field-validator type="required">
<message>You must enter a value for email2.</message>
</field-validator>
<field-validator type="email">
<message>Not a valid e-mail2.</message>
</field-validator>
</field>
<!-- Plain Validator 1 -->
<validator type="expression">
<param name="expression">email.equals(email2)</param>
<message>Email not the same as email2</message>
</validator>
<!-- Plain Validator 2 -->
<validator type="expression" short-circuit="true">
<param name="expression">email.startsWith('mark')</param>
<message>Email does not start with mark</message>
</validator>
</validators>
Validação via Annotations: (como deturpar o uso de annotations assim como foi feito com o uso de XML)
Clique aqui para ver que isso está na documentação oficial do Struts2
Code:
@Validation()
public class SimpleAnnotationAction extends ActionSupport {
@RequiredFieldValidator(type = ValidatorType.FIELD, message = "You must enter a value for bar.")
@IntRangeFieldValidator(type = ValidatorType.FIELD, min = "6",
max = "10", message = "bar must be between ${min} and ${max}, current value is ${bar}.")
public void setBar(int bar) {
this.bar = bar;
}
public int getBar() {
return bar;
}
@Validations(
requiredFields =
{@RequiredFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "customfield", message = "You must enter a value for field.")},
requiredStrings =
{@RequiredStringValidator(type = ValidatorType.SIMPLE,
fieldName = "stringisrequired", message = "You must enter a value for string.")},
emails =
{ @EmailValidator(type = ValidatorType.SIMPLE,
fieldName = "emailaddress", message = "You must enter a value for email.")},
urls =
{ @UrlValidator(type = ValidatorType.SIMPLE,
fieldName = "hreflocation", message = "You must enter a value for email.")},
stringLengthFields =
{@StringLengthFieldValidator(type = ValidatorType.SIMPLE, trim = true, minLength="10" ,
maxLength = "12", fieldName = "needstringlength", message = "You must enter a stringlength.")},
intRangeFields =
{ @IntRangeFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "intfield", min = "6", max = "10", message = "bar must be between ${min} and ${max}, current value is ${bar}.")},
dateRangeFields =
{@DateRangeFieldValidator(type = ValidatorType.SIMPLE,
fieldName = "datefield", min = "-1", max = "99", message = "bar must be between ${min} and ${max}, current value is ${bar}.")},
expressions = {
@ExpressionValidator(expression = "foo > 1",
message = "Foo must be greater than Bar 1. Foo = ${foo}, Bar = ${bar}."),
@ExpressionValidator(expression = "foo > 2",
message = "Foo must be greater than Bar 2. Foo = ${foo}, Bar = ${bar}."),
@ExpressionValidator(expression = "foo > 3",
message = "Foo must be greater than Bar 3. Foo = ${foo}, Bar = ${bar}."),
@ExpressionValidator(expression = "foo > 4",
message = "Foo must be greater than Bar 4. Foo = ${foo}, Bar = ${bar}."),
@ExpressionValidator(expression = "foo > 5",
message = "Foo must be greater than Bar 5. Foo = ${foo}, Bar = ${bar}.")
}
)
public String execute() throws Exception {
return SUCCESS;
}
}
Mais uma vez a configuração programática do Mentawai mostra todo o seu poder facilitando a implementação dessa funcionalidade tão essencial e importante:
Filtro de Validação do Mentawai: (pode ser aplicado em mais de uma action)
Ou vc pode também fazer a validação diretamente na action através da interface Validatable: http://recipes.mentaframework.org/posts/list/4.page
Code:
public class HelloWorldValidator extends ValidationFilter {
private static final String FIELD_REQUIRED_ERROR = "Field required!";
private static final String INVALID_USERNAME_LENGTH = "Username length invalid!";
private static final String INVALID_AGE = "Invalid age!";
private static final String INVALID_PASSWORD_LENGTH = "Invalide password length!";
private static final String PASSWORD_DOES_NOT_MATCH = "Passwords do not match!";
public void initValidator() {
add("username", new RequiredFieldRule(), FIELD_REQUIRED_ERROR);
add("username", new StringRule(6, 30), INVALID_USERNAME_LENGTH);
add("age", new RequiredFieldRule(), FIELD_REQUIRED_ERROR);
add("age", new IntegerRule(18, 50), INVALID_AGE);
add("password", new RequiredFieldRule(), FIELD_REQUIRED_ERROR);
add("password", new StringRule(4, 20), INVALID_PASSWORD_LENGTH);
add("password", new EqualRule("password", "passconf"), PASSWORD_DOES_NOT_MATCH);
add("passconf", new RequiredFieldRule(), FIELD_REQUIRED_ERROR);
}
}
E para internacionalizar essas mensagens, tudo que vc precisa fazer é criar um arquivo HelloWorldValidator_en_US.i18n dentro do diretório /validation:
Code:
###############################################
# Messages for the filter HelloWorldValidator #
###############################################
required = Required field cannot be left blank
2 = Your username must be between %min% and %max% characters long.
3 = You must be %min% years old or older.
4 = Your password must be between %min% and %max% characters long.
5 = Passwords do not match.
E o filtro de validação ficaria assim:
Code:
public class HelloWorldValidator extends ValidationFilter {
private static final String FIELD_REQUIRED_ERROR = "required"; // to illustrate that this can be a string too
private static final int INVALID_USERNAME_LENGTH = 2;
private static final int INVALID_AGE = 3;
private static final int INVALID_PASSWORD_LENGTH = 4;
private static final int PASSWORD_DOES_NOT_MATCH = 5;
public void initValidator() {
add("username", new RequiredFieldRule(), FIELD_REQUIRED_ERROR);
add("username", new StringRule(6, 30), INVALID_USERNAME_LENGTH);
add("age", new RequiredFieldRule(), FIELD_REQUIRED_ERROR);
add("age", new IntegerRule(18, 50), INVALID_AGE);
add("password", new RequiredFieldRule(), FIELD_REQUIRED_ERROR);
add("password", new StringRule(4, 20), INVALID_PASSWORD_LENGTH);
add("password", new EqualRule("password", "passconf"), PASSWORD_DOES_NOT_MATCH);
add("passconf", new RequiredFieldRule(), FIELD_REQUIRED_ERROR);
}
}
- Internacionalização:
A documentação oficial do Struts para internacionalização está aqui: http://struts.apache.org/2.x/docs/localization.html
Mais uma vez a documentação deixa em aberto as seguintes questões:
- Struts2 utiliza ResourceBundle, o que provavelmente vai forçar um restart da aplicação a cada mudança nos arquivos properties do resourcebundle.
- Se o locale do meu usuário está salvo no banco, como forço para que o locale da aplicação seja esse locale para esse usuário?
- Tenho a opção de criar apenas um único arquivo onde todo o meu conteúdo internacionalizado estará presente (arquivo master) ?
- O Struts2 permite internacionalizar actions colocando arquivos properites dentro do pacote da action. É boa prática colocar os arquivos de internacionalização separados do seu código e num lugar que possa ser acessível pelo designer e/ou tradutor. (Ou vc programador vai fazer essa tarefa?)
Compare o approach do Struts2 com o approach do Mentawai e tire suas próprias conclusões: http://www.mentaframework.org/i18n.jsp?loc=pt
- Conversão:
Assim como sua documentação, os conversores do Struts não são nem simples, nem claros, nem pragmáticos:
Code:
/**
* Observação bem grande na documentação, para te ajudar:
*
* To allow Struts to recognize that a conversion error has occurred,
* the converter class need to throw XWorkException or preferably
* TypeConversionException.
*/
public class MyConverter extends StrutsTypeConverter {
public Object convertFromString(Map context, String[] values, Class toClass) {
.....
}
public String convertToString(Map context, Object o) {
.....
}
}
É difícil entender e/ou justficar algo tão bizarro acima para algo tão simples como uma conversão, principalmente quando olhamos a versão do Mentawai abaixo:
Code:
public class MyConverter extends BasicConverter {
public Object convert(Object value) throws ConversionException {
// ...
}
}
// ou ainda para converter baseado no locale
public class MyConverter extends LocaleConverter {
public Object convert(Object value, Locale loc) throws ConversionException {
// ...
}
}
- Filtros:
A configuração dos filtros é feita via XML, como sempre. Se tivermos que por exemplo aplicar o mesmo filtro em 100 actions diferentes, teremos que usar copy/paste e transformar a nossa configuração num arquivo XML gigantesco. Em contrapartida, se utilizarmos configuração programática, podemos fazer um for/loop, métodos, if, etc.
Veja o exemplo de um interceptor do Struts:
Code:
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class SimpleInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception {
MyAction action = (MyAction)invocation.getAction();
action.setDate(new Date());
return invocation.invoke();
}
}
Reparem que, talvez pela falta de um INPUT/OUTPUT para as actions, o interceptor acima está fortemente acoplado a action MyAction, ou seja, só pode ser aplicado a ela.
Na versão do Mentawai ficaria assim:
(reparem que o filtro abaixo poderá ser aplicado em qualquer action, e não apenas MyAction)
Code:
public class SimpleFilter implements Filter {
public String filter(InvocationChain chain) throws Exception {
Action action = chain.getAction();
Input input = action.getInput();
input.setValue("someDate", new Date());
return chain.invoke();
}
public void destroy() { }
}
Aguardem mais comparativos !!!
|
Sergio Oliveira
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/04/2007 21:00:16
|
ricardolecheta
Joined: 01/08/2005 21:14:08
Messages: 19
Offline
|
Oi Sergio,
vc nao pode comparar o ww2 com menta deste jeito...
esse lance dos interceptors vc usa interfaces.. pra nao acoplar a uma action.
nao olhe so a validacao.. precisa olhar o framework como um todo, o struts2 ta um show.
no ww2 qualquer classe é uma action, nao precisa fazer extends de nada e nem ter input, output...
tipo
MinhaClaseDeNegocio{
private String msg;
public String go(){..business.here....}
public string getMsg(){ return msg;}
}
e nao view $msg... nao precisa configurar nada, pois existem os ActionMappers..
agora a validação usando @ é uma mer*** mesmo.. da arrepio só de olhar.
agora vc nao pode falar mal de quem vc copiou...
filtro=interceptor
consequence=result..
converter=converter.. nao sei como chama no menta
tem q olhar como um todo....
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/04/2007 06:48:21
|
saoj
Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline
|
ricardolecheta wrote:
esse lance dos interceptors vc usa interfaces.. pra nao acoplar a uma action.
O exemplo do Struts2 está dando um CAST para uma action em específico, ou seja, o exemplo do struts2 está acoplando o filtro a uma action em específico, porque ele não trabalha com input, ou seja, para pegar algo de uma action ele tem que dar cast para aquela action, entendeu?
nao olhe so a validacao.. precisa olhar o framework como um todo, o struts2 ta um show.
Mais eu olhei um monte de coisas: validacao, filtros, conversão e internacionalizacao. o que mais vc sugere que a gente compare? Deve ter alguma coisa em que o Struts é mais simples que o mentawai, e é isso que estamos procurando...
no ww2 qualquer classe é uma action, nao precisa fazer extends de nada e nem ter input, output...
Ter INPUT e OUTPUT é muito bom! Facilita um monte de coisas e não acopla a sua action ao filtro por exemplo. E se vc bater o pé e falar que não gosta, usa o InjectionFilter e o OutputFilter e ignore input/output, por favor.
Há discussões de 15 páginas no GUJ sobre herança. Qual a vantagem de sua action não precisar estender nada??????? Sinceramente, a não ser que sua action seja algo que vc quer reaproveitar em outro lugar (o seu modelo de negócios está implementado dentro dela ???????) faze-la estender ou implementar alguma coisa é um detalhe insignificante. Mas aguarde que em breve, apenas para oferecer essa opção aos puritanos de plantão, iremos fazer isso também...
e nao view $msg... nao precisa configurar nada, pois existem os ActionMappers..
Tb temos CoC para a camada view, mas há uma discussão bem grande sobre o porque isso não se aplica a projetos maiores. O CoC para view é um tiro no pé. Não dá para fugir de cofiguração de view em projetos grandes.
agora a validação usando @ é uma mer*** mesmo.. da arrepio só de olhar.
Configuração programática resolve isso bonito. Desde de 2005 o menta é assim. EXISTE ALGO MAIS PODEROSO PARA ABSTRAIR COMPLEXIDADE DO QUE ORIENTAÇÃO A OBJETOS?
agora vc nao pode falar mal de quem vc copiou...
filtro=interceptor
consequence=result..
converter=converter.. nao sei como chama no menta
O que as pessoas precisam entender é que o pulo-do-gato do menta foi simplificar todo o processo de desenvolvimento web através de configuração programática. Esse é a grande diferença dele para Struts e WW.
O Menta é MUUUUUUUUUITO diferente do que o WW.
filtro = interceptor (acho quem teve essa idéia primeiro foi o WW ou talvez a própria api de servelts que tem FILTROS) Te pergunto? Existe algum framework web action-based que não utiliza filtros? Seria fazer um framework web sem validação. Isso é básico e muito importante, e talvez quem tenha provado isso tenha sido o WW mesmo!
consequence = result (naooooooooooooo result no mentawai eh String e consequencia é algo totalmente diferente, ww não tem consequencia, tem apenas result)
converter = converter (ué, converter e validação não se copia, é fato, qualquer framework precisa. E dá uma olhada acima no modo bizarro que o Struts2 trabalha com converção, não que seja bisarro, mas ilustra o estilo do struts, uma chamada toda complexa para algo ridicularmente simples que é conversão.
tem q olhar como um todo....
Sim, eu olhei as partes principais: validação, filtros, conversão, etc. Em breve faremos mais comparação.
Não estou falando que o Struts2 é ruim. Isso é totalmente subjetivo. Estou dizendo que para quem não conhece o Mentawai e para quem não conhece o Struts2, o Mentawai é bem mais simples!
Não estamos discutindo aqui quem é o melhor. Estamos discutindo qual é o mais simples de usar e obter os resultados que vc quer sem dores de cabeça. Veja o Dalton que fez o infoblogs por exemplo. Ele manja tudo de WW e de Struts2, ou seja, para ele, o Struts2 é melhor do que o Mentawai. Nada mais correto.
|
Sergio Oliveira
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/04/2007 07:44:29
|
ricardolecheta
Joined: 01/08/2005 21:14:08
Messages: 19
Offline
|
saoj wrote:
O exemplo do Struts2 está dando um CAST para uma action em específico, ou seja, o exemplo do struts2 está acoplando o filtro a uma action em específico, porque ele não trabalha com input, ou seja, para pegar algo de uma action ele tem que dar cast para aquela action, entendeu?
nao necessariamente... vc pode acessar ActionContext.getContext()..getAlgumaCoisa que não me lembro que retorna um Map que é a input. faz tempo que nao uso WW e estou botando lenha da fogueira
O que é a consequence entao? Não é uma classe que processa o resultado? Igual ao result do ww... ou nao entendi...
Bom o WW ta bem mais avançado no ajax. Já tentei te ajudar mas nao deu muito certo da ultima vez Aquele ajax com a ajaxtags ja saiu?
acho que vc deveria investir mais no ajax... seria o pulo do gato
ele tem integração com jsf tb...isto pode atrair alguns usuarios interessados em usar alguns componentes na view
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/04/2007 07:51:34
|
velo
![[Avatar]](/images/avatar/7f39f8317fbdb1988ef4c628eba02591.jpg)
Joined: 16/02/2006 13:33:54
Messages: 1197
Location: Jaraguá do Sul - SC
Offline
|
ricardolecheta wrote:
Aquele ajax com a ajaxtags ja saiu?
Sir, yes sir.
VELO
|
_____________________________________
Mentawai Developer
"When the only tool you have is a hammer, everything looks like a nail"
http://en.wikipedia.org/wiki/Golden_hammer |
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/04/2007 07:55:42
|
ricardolecheta
Joined: 01/08/2005 21:14:08
Messages: 19
Offline
|
velo wrote:
ricardolecheta wrote:
Aquele ajax com a ajaxtags ja saiu?
Sir, yes sir.
VELO
legal.. só precisa criar uns docs.. só encontrei este aqui antigo:
http://www.mentaframework.org/ajaxintegration.jsp
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/04/2007 07:58:47
|
velo
![[Avatar]](/images/avatar/7f39f8317fbdb1988ef4c628eba02591.jpg)
Joined: 16/02/2006 13:33:54
Messages: 1197
Location: Jaraguá do Sul - SC
Offline
|
Farei...
Um dia, logo em breve, aguardem, heheheh
VELO
|
_____________________________________
Mentawai Developer
"When the only tool you have is a hammer, everything looks like a nail"
http://en.wikipedia.org/wiki/Golden_hammer |
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/04/2007 08:34:28
|
saoj
Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline
|
acho que vc deveria investir mais no ajax... seria o pulo do gato
Concordo plenamente! Eu mesmo preciso dar uma boa estudada em DWR e essas coisas...
|
Sergio Oliveira
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/04/2007 15:24:47
|
cassio
![[Avatar]](/images/avatar/b1d10e7bafa4421218a51b1e1f1b0ba2.jpg)
Joined: 17/12/2006 11:55:58
Messages: 91
Offline
|
Pessoal, já fiz muita coisa com o DWR e o Mentawai juntos. Em geral a única coisa que eu faço que depende diretamente do Mentawai é quando chamo alguma action com redirect e carrego um documento (com conteúdo dinâmico gerado pelo Menta) dentro de um div, por exemplo. É legal para carregar tabelas ou formulários, por exemplo. Outras coisas com Ajax e o DWR, eu acabo fazendo a partir de algumas classes de negócio mesmo, não passa pelas actions...
Se quiserem posso preparar algo para documentação com esse tipo de exemplo que citei...
|
Cássio Marques
Computação Científica - Universidade de Taubaté
/*codificando*/
 |
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 17/04/2007 15:32:07
|
saoj
Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline
|
cassio wrote:
Pessoal, já fiz muita coisa com o DWR e o Mentawai juntos. Em geral a única coisa que eu faço que depende diretamente do Mentawai é quando chamo alguma action com redirect e carrego um documento (com conteúdo dinâmico gerado pelo Menta) dentro de um div, por exemplo. É legal para carregar tabelas ou formulários, por exemplo. Outras coisas com Ajax e o DWR, eu acabo fazendo a partir de algumas classes de negócio mesmo, não passa pelas actions...
Se quiserem posso preparar algo para documentação com esse tipo de exemplo que citei...
Putz, seria muito bom !!!! Alguma exemplo prático de como usar o Menta com DWR, por exemplo.
Com certeza disponibilizaríamos aqui no site do menta...
|
Sergio Oliveira
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 18/04/2007 05:55:37
|
cassio
![[Avatar]](/images/avatar/b1d10e7bafa4421218a51b1e1f1b0ba2.jpg)
Joined: 17/12/2006 11:55:58
Messages: 91
Offline
|
Vou ver se preparo alguma coisa aqui e envio ainda essa semana
|
Cássio Marques
Computação Científica - Universidade de Taubaté
/*codificando*/
 |
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/11/2007 08:20:55
|
saoj
Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline
|
no ww2 qualquer classe é uma action, nao precisa fazer extends de nada e nem ter input, output...
http://forum.mentaframework.org/posts/list/1188.page
|
Sergio Oliveira
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 10/12/2007 07:37:51
|
Rodolfo_C
![[Avatar]](/images/avatar/941e1aaaba585b952b62c14a3a175a61.jpg)
Joined: 10/12/2007 07:34:14
Messages: 2
Offline
|
Interessante este post, pois estou realizando meu trabalho de conclusão de curso em cima disso, uma comparação prática entre dois frameworks, no meu caso escolhi Mentawai vs Struts2, só preciso definir o sistema a ser implementado e aplicar
=D
|
|
 |
|
|
|