| Author |
Message |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 06/04/2006 15:48:40
|
Lobo
![[Avatar]](/images/avatar/093f65e080a295f8076b1c5722a46aa2.jpg)
Joined: 23/01/2006 02:17:14
Messages: 841
Location: Fortaleza-CE
Offline
|
Caros vou postar o código que estou usando para evitar o lance do F5 , botão de reload do browser ressubimissão de form. fiz um lance meio "tenho que dar um jeito logo nisso" mas seria interessante algo elegante estilo mentawai.
Mas to sem tempo galera... tirei umas coisas na minha cabeça e outras achei soltas na internet mas tá funcionando que é uma beleza :]
Na action:
---------------------------------------------------------------------------
String token = input.getStringValue("token");
InputRequest ir = (InputRequest)input;
HttpSession session = ir.getRequest().getSession();
if (token != null){
if (session.getAttribute("token") == null){
session.setAttribute("token", token);
}
else{
if (session.getAttribute("token").equals(token)){
output.setValue("erro", "Mandar o form novamente ? isso não te pertence mais !!");
return ERROR;
}
else{
session.setAttribute("token", token);
}
}
}
===========================================
no jsp :
--------------------------------------------------------------------------
<%@ taglib prefix="lobo" uri="/WEB-INF/lobo.tld" %>
<lobo:TokenForm idSession="<%=request.getSession().getId()%>"/>
===========================================
Uma classe:
import java.security.MessageDigest;
public class TokenForm {
private String token;
public TokenForm(String idSession) throws Exception{
long systime = System.currentTimeMillis();
byte[] time = new Long(systime).toString().getBytes();
byte[] id = idSession.getBytes();
try{
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(id);
md5.update(time);
token = toHex(md5.digest());
}
catch(Exception e){
throw new Exception(e);
}
}
private String toHex(byte[] digest) {
StringBuffer buf = new StringBuffer();
for(int i = 0;i < digest.length;i++)
buf.append(Integer.toHexString(digest[i] & 0x00ff));
return buf.toString();
}
public String toString() {
return token;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
=====================================
A classe que representa a tag:
package util;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import util.TokenForm;
public class TokenFormTag extends TagSupport
{
private String idSession;
public int doStartTag() throws JspException {
try{
TokenForm tokenForm = new TokenForm(idSession);
pageContext.getOut().print("<input type='hidden' name='token' value='"+ tokenForm +"'>");
}
catch(Exception e){
throw new JspException(e);
}
return SKIP_BODY;
}
public String getIdSession(){
return idSession;
}
public void setIdSession(String string) {
idSession = string;
}
}
==========================================
O TLD da tag
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>lobo</short-name>
<display-name>lobo</display-name>
<description>lobo</description>
<tag>
<name>TokenForm</name>
<tag-class>util.TokenFormTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>idSession</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
=========================================
Atenciosamente,
Hélio Frota
|
Atenciosamente,
Hélio Frota
Helio Frota
10+ Java Programmer
heliofrota.com
Mentawai Developer |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 06/04/2006 15:56:17
|
andre_guitar7
![[Avatar]](/images/avatar/f033ab37c30201f73f142449d037028d.jpg)
Joined: 21/03/2006 12:03:21
Messages: 259
Location: Curitiba - PR
Offline
|
Cara, eu preciso muuuuuuuuuuuuuuuito disso!!
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 07:51:27
|
alexandre
Joined: 23/02/2006 11:48:04
Messages: 33
Location: São José dos Pinhais - PR
Offline
|
Uma solução que pensei agora seria colocar o System.currentTimeMillis(); em uma variavel no cookies ( é melhor do que ficar colocando em session no servidor, que pode comprometer a performance dependendo dos acessos)
e na action que escreve no banco o result do form faz assim :
Se não existir o cookie ou ele for diferente do que veio no input aceita o form e escreve a variavel no cookie.
Se for igual a que veio na input é porque é enviou duas vezes então deve-se aplicar sua logica.
Deve funcionar o que vocês acham ?
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 08:31:38
|
alexandre
Joined: 23/02/2006 11:48:04
Messages: 33
Location: São José dos Pinhais - PR
Offline
|
Funcionou !!
na action :
Code:
if ( cookies.getAttribute("_time") != null ){
long a = 0;
long b = 0;
try{
a = Long.parseLong( (String) cookies.getAttribute("_time") );
b = Long.parseLong( input.getStringValue("_time") );
}catch (Exception e) {}
if(a == b){
addError("Formulário já enviado anteriormente.");
return ERROR;
}
}
cookies.setAttribute("_time", input.getValue("_time"));
no form :
Code:
<input type="hidden" name="_time" value="<%=System.currentTimeMillis()%>" />
Não sei como se pega em jstl o System.currentTimeMillis() mas assim funciona blz !!
Abraço.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 09:05:56
|
Lobo
![[Avatar]](/images/avatar/093f65e080a295f8076b1c5722a46aa2.jpg)
Joined: 23/01/2006 02:17:14
Messages: 841
Location: Fortaleza-CE
Offline
|
não vou criticar de maneira alguma sua solução :]]
so quero saber se por acaso eu desabilitar cookies no browser ainda vai funcionar. se sim vou fazer refactor em todos os sistemas que estão usando mentawai.
mas foi massa a idéia é essa Alexandre, eu fiz um lance pra ter que consertar meu problema mas queria mesmo que todo mundo ajudasse já que o mentawai ta ajudando muita gente
Valeu cara
Atenciosamente,
Hélio Frota
|
Atenciosamente,
Hélio Frota
Helio Frota
10+ Java Programmer
heliofrota.com
Mentawai Developer |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 09:28:10
|
alexandre
Joined: 23/02/2006 11:48:04
Messages: 33
Location: São José dos Pinhais - PR
Offline
|
Se a pessoa estiver com cookies desabilitado vai aceitar a resubimissão sim.
Acredito que ninguem desabilite os cookies, só se sua idéia é que possa haver um usuário mal intencionado, ai acho melhor mudar para session mesmo.
Mas é facil no meu código mesmo é só modificar onde tem cookies para session.
Acho que a melhor maneira de fazer isso é criar um filter e uma tag lib.
ia ser o menos doloroso pra mudar todos seus programas.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 11:45:40
|
alexandre
Joined: 23/02/2006 11:48:04
Messages: 33
Location: São José dos Pinhais - PR
Offline
|
Com filtro fica assim :
Code:
import org.mentawai.core.Action;
import org.mentawai.core.Context;
import org.mentawai.core.Filter;
import org.mentawai.core.InvocationChain;
import org.mentawai.i18n.LocaleManager;
import org.mentawai.message.ClassMessageContext;
import org.mentawai.message.DefaultMessage;
import org.mentawai.message.FileMessageContext;
import org.mentawai.message.MessageContext;
import org.mentawai.message.MessageManager;
public class SubmitFilter implements Filter{
private MessageContext msgContext;
private String error = "Formulário já enviado.";
public SubmitFilter(){
if (LocaleManager.isUseMasterForEverything()) {
msgContext = new FileMessageContext(LocaleManager.getMaster(), "");
} else {
msgContext = new ClassMessageContext(this.getClass());
}
}
public SubmitFilter(String error){
this();
this.error = error;
}
@SuppressWarnings("unchecked")
public String filter(InvocationChain chain) throws Exception {
Action action = chain.getAction();
Context cookies = action.getCookies();
if ( cookies.getAttribute("_time") != null ){
String a = "";
String b = "";
try{
a = (String) cookies.getAttribute("_time");
b = action.getInput().getStringValue("_time");
}catch (Exception e) {}
if(a.equals(b)){
MessageManager.getErrors(action, true).add(new DefaultMessage(error, msgContext,null));
return Action.ERROR;
}
}
cookies.setAttribute("_time", action.getInput().getValue("_time"));
return chain.invoke();
}
public void destroy() { }
}
ai no ApplicationManager colocase :
Code:
.filter(new SubmitFilter())
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 12:03:01
|
saoj
Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline
|
Excelente idéia, Alexandre.
Estou pensando aqui: Qual seria o lugar certo para esse filtro pegar a mensagem de erro ???
SubmitFilter_loc.i18n ?
ActionName_loc.i18n (acho que não!)
master_loc.i18n ???
Tua classe não ficou simples, e isso é contra a filosofia do Mentawai.
Precisamos de um filtro de validação geral, além do já existente filtro de validação de formulário.
Esse filtro vai prover maneiras simples de adicionar uma mensagem de erro/sucesso, como o BaseAction faz.
Quer tentar fazer Alexandre ???
Assim a sua classe extenderia esse filtro ao invés de implementar Filter e ficaria bem mais limpa do que está agora.
|
Sergio Oliveira
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 15:21:29
|
alexandre
Joined: 23/02/2006 11:48:04
Messages: 33
Location: São José dos Pinhais - PR
Offline
|
Humm blz, boa ideia.
Posso tentar fazer, mas ai só na segunda
Gostei da internacionalização em SubmitFilter_loc.i18n.
Abraço
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 18:05:38
|
Lobo
![[Avatar]](/images/avatar/093f65e080a295f8076b1c5722a46aa2.jpg)
Joined: 23/01/2006 02:17:14
Messages: 841
Location: Fortaleza-CE
Offline
|
Acho que a melhor maneira de fazer isso é criar um filter e uma tag lib.
ia ser o menos doloroso pra mudar todos seus programas
Certo é isso que estou fazendo mas gostaria de saber se o oficial para o mentawai vai ser com cookies ou session
Pelo menos mais um problema resolvido pro mentawai. :]
Atenciosamente,
Hélio Frota
|
Atenciosamente,
Hélio Frota
Helio Frota
10+ Java Programmer
heliofrota.com
Mentawai Developer |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 18:13:36
|
saoj
Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline
|
Pode ser configurável para session ou cookie.
Se o cara desabilita os cookies a session funciona ?????
Nunca testei isso. Deveria funcionar via url rewrite mas tenho minhas dúvidas...
Session me parece mais seguro mesmo...
|
Sergio Oliveira
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 07/04/2006 19:27:34
|
saoj
Joined: 01/07/2005 09:59:17
Messages: 2846
Location: Rio de Janeiro, RJ
Offline
|
Posso tentar fazer, mas ai só na segunda
Pô, vc que deu a idéia, que por sinal é boa, e agora está fazendo corpo mole pra fazê-la? A madrugada tá aí pra isso! Peque por excesso mas nunca por omissão.
|
Sergio Oliveira
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 20/04/2006 17:14:01
|
Lobo
![[Avatar]](/images/avatar/093f65e080a295f8076b1c5722a46aa2.jpg)
Joined: 23/01/2006 02:17:14
Messages: 841
Location: Fortaleza-CE
Offline
|
Code:
package filter;
import org.mentawai.core.Action;
import org.mentawai.core.Filter;
import org.mentawai.core.Input;
import org.mentawai.core.InvocationChain;
import org.mentawai.core.Output;
public class SubmissionFilter implements Filter{
public SubmissionFilter() {
}
public String filter(InvocationChain chain) throws Exception {
Action action = chain.getAction();
Input input = action.getInput();
Output output = action.getOutput();
String token = input.getStringValue("token");
if (token != null){
if (action.getSession().getAttribute("token") == null){
action.getSession().setAttribute("token", token);
}
else{
if (action.getSession().getAttribute("token").equals(token)){
//A mensagem aqui eu deixei fixa.
output.setValue("erro", "....");
return Action.ERROR;
}
else{
action.getSession().setAttribute("token", token);
}
}
}
return chain.invoke();
}
public void destroy() { }
}
-o método isTokenValid no struts tem comentado que recebe o token da sessão é so ver o código na classe TokenProcessor
-o Rifers citado em outro tópico parece usar veja o exemplo de formulário passo a passo que tem lá. Ao olhar o codigo fonte da página tem isso aqui
<input name="contid" type="hidden" value="fad5eee60ed96af2219ab6ee56e72210" />
Essa string maluca deve ser sem dúvida o id da sessão se não for é prima dela :]
no webwork tem isso escrito :
-TokenSessionStoreInterceptor, can provide much better logic for when invalid tokens are found.
-o Wicket também citado em outro tópico aqui, não encontrei exemplo rodando no site deles apenas screenshot dos exemplos :/ mas baixei o código fonte gorduroso do projeto e tem uma classe RequestCycle que não conheço mas to com suspeitas de que usa a mesma abordagem de token na sessão.
Atenciosamente,
Hélio Frota
|
Atenciosamente,
Hélio Frota
Helio Frota
10+ Java Programmer
heliofrota.com
Mentawai Developer |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 16/08/2006 18:03:30
|
velo
![[Avatar]](/images/avatar/7f39f8317fbdb1988ef4c628eba02591.jpg)
Joined: 16/02/2006 13:33:54
Messages: 1197
Location: Jaraguá do Sul - SC
Offline
|
Isso foi parar dentro do menta?
Com que nome?
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) 16/08/2006 20:19:06
|
Lobo
![[Avatar]](/images/avatar/093f65e080a295f8076b1c5722a46aa2.jpg)
Joined: 23/01/2006 02:17:14
Messages: 841
Location: Fortaleza-CE
Offline
|
Cara mandei a solução caseira pro Rubem pra ver se ele ajeita pro menta mas não sei como ficou, até porque nem comentei nada no código, como sempre ando sem dormir.
Atenciosamente,
Hélio Frota
|
Atenciosamente,
Hélio Frota
Helio Frota
10+ Java Programmer
heliofrota.com
Mentawai Developer |
|
|
 |
|
|