Verifique a configuração no seu web.xml, para que seus .js sejam criados pelo Servlet do DWR. Note que passei as classes que serão utilizadas. As do pacote br.com.netra.jad são meus DTO, e as do pacote br.com.netra.jad.dwr são os meus Remote Proxy (classes que invocamos os métodos via ajax).
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>classes</param-name>
<param-value>
br.com.netra.jad.dwr.ArquivoDWR,
br.com.netra.jad.Arquivo,
br.com.netra.jad.Resultado,
br.com.netra.jad.Status,
br.com.netra.jad.Opcoes
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<session-config>
Lembre de anotar a sua classe Remote Proxy, e não esqueça de anotar os métodos que você quer permitir a chamada Ajax. Só um informativo: esta aplicação é um decompilador Java, utilizando JAD.
package br.com.netra.jad.dwr;
import br.com.netra.jad.Arquivo;
import br.com.netra.jad.Opcoes;
import br.com.netra.jad.Resultado;
import br.com.netra.jad.negocio.BOFactory;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.directwebremoting.WebContext;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
/**
* Classe responsável por apresentar a camada de negócio utilizando a tecnologia
* AJAX via DWR. Esta classe deve preparar os dados para serem enviados para
* o browser do cliente.
* @author Cleverson Sacramento (zyc@ig.com.br)
* @see <a href="http://getahead.org/dwr/">Direct Web Remoting</a>
*/
@RemoteProxy
public class ArquivoDWR {
/**
* Carrega as informações de um arquivo com base na sua identificação.
* @param id Identificação do arquivo.
* @return Arquivo carregado.
* @throws Exception
*/
@RemoteMethod
public Arquivo carrega(Long id) throws Exception {
Arquivo dto = BOFactory.getInstance().createArquivo().carregar(id);
return dto;
}
/**
* Analisa um determinado aquivo para decompilação com base na sua identificação.
* @param id Identificação do arquivo.
* @return Resultado da análise.
* @throws Exception
*/
@RemoteMethod
public Resultado analisa(Long id) throws Exception {
Arquivo dto = BOFactory.getInstance().createArquivo().carregar(id);
Resultado resultado =
BOFactory.getInstance().createDecompilacao().analisar(dto);
resultado.getArquivo().setConteudo(null);
return resultado;
}
/**
* Obtém todos os arquivos baseados na sessão do usuário.
* @return Lista de resultado com o arquivo preenchido, para manter a
* compatibilidade na apresentação das informações.
* @throws Exception
*/
@RemoteMethod
public List<Resultado> obterTodos() throws Exception {
List<Resultado> list = new ArrayList<Resultado>();
List<Arquivo> listAux =
BOFactory.getInstance().createArquivo().obterTodos();
String sid = this.getHttpServletRequest().getSession().getId();
for (Arquivo dto: listAux) {
if (dto.getCaminho().indexOf(sid) != -1) {
Resultado resultado =
BOFactory.getInstance().createDecompilacao().analisar(dto);
resultado.getArquivo().setConteudo(null);
list.add(resultado);
}
}
return list;
}
/**
* Remove um arquivo.
* @param dto Arquivo a ser removido.
* @return Arquivo removido para apresentar o resultado da remoção em tela.
* @throws Exception
*/
@RemoteMethod
public Arquivo excluir(Arquivo dto) throws Exception {
BOFactory.getInstance().createArquivo().excluir(dto);
return dto;
}
/**
* Decompila um determinado arquivo.
* @param arquivo Arquivo a ser decompilado.
* @param opcoes Opções de decompilação.
* @return Código-fonte do arquivo decompilado.
* @throws Exception
*/
@RemoteMethod
public Arquivo decompilar(Arquivo arquivo,
Opcoes opcoes) throws Exception {
arquivo =
BOFactory.getInstance().createArquivo().carregar(arquivo.getId());
Arquivo fonte =
BOFactory.getInstance().createDecompilacao().decompilar(arquivo,
opcoes);
arquivo.setFonte(fonte);
arquivo.setConteudo(null);
arquivo.getFonte().setConteudo(null);
return arquivo;
}
/**
* Artifício do DWR para obter o request do contexto.
* @return Escopo de request do usuário.
*/
private HttpServletRequest getHttpServletRequest() {
WebContext ctx = WebContextFactory.get();
return ctx.getHttpServletRequest();
}
}
Anote os seus DTO, caso você esteja trabalhando com tipos complexos:
package br.com.netra.jad;
import java.io.Serializable;
import org.directwebremoting.annotations.DataTransferObject;
import org.directwebremoting.annotations.RemoteProperty;
/**
* Objeto de transferência de dados que representa um arquivo a ser decompilado.
* Um arquivo pode representar uma referência local ou remota.
* @author Cleverson Sacramento (cleverson@netra.com.br)
* @version 13/04/2007 (dd/mm/yyyy)
*/
@DataTransferObject
public class Arquivo implements Serializable {
/**
* Identificação única do arquivo.
*/
@RemoteProperty
private Long id;
/**
* Nome completo do arquivo, composto pelo nome e extensão.
* Não deve conter o caminho para o arquivo.
*/
@RemoteProperty
private String nome;
/**
* Caminho completo ou relativo para o arquivo. Não deve conter o nome do
* arquivo.
*/
@RemoteProperty
private String caminho;
/**
* Conteúdo do arquivo para os casos de arquivo remoto. Deve ser utilizado
* apenas quando o arquivo do cliente precise ser replicado no servidor.
*/
private byte[] conteudo;
/**
* Tamanho do arquivo em byte.
*/
@RemoteProperty
private Long tamanho;
/**
* Tipo MIME do arquivo. Não representa a extensão do arquivo, que pode
* ser encontrada no nome do arquivo.
*/
@RemoteProperty
private String tipo;
/**
* Arquivo-fonte associado ao arquivo após o processo de decompilação.
*/
@RemoteProperty
private Arquivo fonte;
/**
* Define o nome completo do arquivo, composto pelo nome e extensão.
* Não deve conter o caminho para o arquivo.
* @param nome Nome do arquivo.
*/
public void setNome(String nome) {
this.nome = nome;
}
/**
* Obtém o nome completo do arquivo, composto pelo nome e extensão.
* Não deve conter o caminho para o arquivo.
* @return Nome do arquivo.
*/
public String getNome() {
return nome;
}
/**
* Define o caminho completo ou relativo para o arquivo. Não deve conter o nome do
* arquivo.
* @param caminho Caminho do arquivo.
*/
public void setCaminho(String caminho) {
this.caminho = caminho;
}
/**
* Obtém o caminho completo ou relativo para o arquivo. Não deve conter o nome do
* arquivo.
* @return Caminho do arquivo.
*/
public String getCaminho() {
return caminho;
}
/**
* Define o conteúdo do arquivo para os casos de arquivo remoto. Deve ser utilizado
* apenas quando o arquivo do cliente precise ser replicado no servidor.
* @param conteudo Conteúdo do arquivo.
*/
public void setConteudo(byte[] conteudo) {
this.conteudo = conteudo;
}
/**
* Obtém o conteúdo do arquivo para os casos de arquivo remoto. Deve ser utilizado
* apenas quando o arquivo do cliente precise ser replicado no servidor.
* @return Conteúdo do arquivo.
*/
public byte[] getConteudo() {
return conteudo;
}
/**
* Define o tamanho do arquivo em byte.
* @param tamanho Tamanho do arquivo em byte
*/
public void setTamanho(Long tamanho) {
this.tamanho = tamanho;
}
/**
* Obtém o tamanho do arquivo em byte.
* @return Tamanho do arquivo em byte
*/
public Long getTamanho() {
return tamanho;
}
/**
* Define a identificação única do arquivo.
* @param id Identificação única do arquivo.
*/
public void setId(Long id) {
this.id = id;
}
/**
* Obtém a identificação única do arquivo.
* @return Identificação única do arquivo
*/
public Long getId() {
return id;
}
/**
* Define o tipo MIME do arquivo. Não representa a extensão do arquivo, que pode
* ser encontrada no nome do arquivo.
* @see br.com.netra.jad.util.ConstanteJad#MIME_CLASS
* @see br.com.netra.jad.util.ConstanteJad#MIME_ZIP
* @see br.com.netra.jad.util.ConstanteJad#MIME_JAVA
* @param tipo Tipo MIME do arquivo.
*/
public void setTipo(String tipo) {
this.tipo = tipo;
}
/**
* Obtém o tipo MIME do arquivo. Não representa a extensão do arquivo, que pode
* ser encontrada no nome do arquivo.
* @see br.com.netra.jad.util.ConstanteJad#MIME_CLASS
* @see br.com.netra.jad.util.ConstanteJad#MIME_ZIP
* @see br.com.netra.jad.util.ConstanteJad#MIME_JAVA
* @return Tipo MIME do arquivo.
*/
public String getTipo() {
return tipo;
}
/**
* Define o arquivo-fonte associado ao arquivo após o processo de decompilação.
* @param fonte Arquivo-fonte associado ao arquivo.
*/
public void setFonte(Arquivo fonte) {
this.fonte = fonte;
}
/**
* Define o arquivo-fonte associado ao arquivo após o processo de decompilação.
* @return Arquivo-fonte associado ao arquivo.
*/
public Arquivo getFonte() {
return fonte;
}
}
No jsp basta importar os seguintes .js, gerados pelo Servlet do DWR que você configurou no seu web.xml.
<script type='text/javascript' src='dwr/interface/ArquivoDWR.js'></script>
<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/util.js'></script>
No javascript basta fazer a chamada ao seu Proxy, passando os parâmetros. Ao final da chamada coloque o nome do handle que processará o retorno assincrono do Ajax:
function excluir(){
var dtos = obterMarcados();
for(i = 0; i < dtos.length; i++){
[b]ArquivoDWR.excluir(dtos[i].arquivo, retornoExcluiArquivo);[/b]
}
}
[b]function retornoExcluiArquivo(dto){[/b]
var row = getRowByArquivoID(dto.id);
grid.deleteRow(row);
info("<u>" + dto.nome + "</u> excluído com sucesso.")
}
Esta implementação utilizando Anotações simplifica bastante a utilização do DWR. Logo, não será mais necessário o arquivo dwr.xml.
Espero que estes exemplos sejam úteis para você!