Dando continuidade à
Parte 1 deste artigo, na qual criamos a estrutura dos projetos
AplicaçãoServidor e
AplicacaoCliente, vamos estabelecer a comunicação entre ambos.
No projeto web
AplicaçãoServidor crie um pacote chamado
controle. Dentro desse pacote crie 4 classes cujos nomes são os que seguem:
- ActionClasses
- MyControllerCallBack
- XMLResources
- MyActions
Observe a estrutura na aba de projetos do NetBeans:
O código das classes MyControllerCallBack e XMLResources é um padrão do OpenSwing e não varia, é, portanto, sempre o mesmo para qualquer aplicação.
A interface org.openswing.swing.server.Action é quem recebe diretamente a requisição do cliente. Ela assina dois métodos: executeCommand() e getRequestName(), este último retorna uma string com o nome da implementação, de modo que o cliente use este nome como parâmetro, indicando que a requisição deve ir para esta classe. O desenvolvedor pode criar quantas implementações quiser para Action, de acordo com as regras de negócio estabelecidas.
Para o projeto AplicaçãoServidor, o código das classes deve ser exatamente como que segue:
package controle;
import javax.servlet.ServletContext;
import org.openswing.swing.server.ControllerCallbacks;
/**
*
* @author OS
*
* class of type org.openswing.swing.server.ControllerCallbacks , an application specific class that contains additional initialization logic for the web application.
* The afterInit() method of this interfacce is automatically invoked by the Controller servlet after its initialization and can be used to add further logic,
* that depends on the specific application.
*/
public class MyControllerCallBack extends ControllerCallbacks{
public MyControllerCallBack() {
}
@Override
public void afterInit(ServletContext context) {
}
}
XMLResources.java
package controle;
import org.openswing.swing.internationalization.java.XMLResourcesFactory;
import org.openswing.swing.internationalization.server.ServerResourcesFactory;
import java.util.Hashtable;
import org.openswing.swing.internationalization.java.Resources;
import javax.servlet.ServletContext;
/**
* Internacionalizacao suporte
*/
public class XMLResources extends ServerResourcesFactory {
private XMLResourcesFactory factory = null;
public XMLResources() {
}
/**
* Method called by the server controller (Controller object) to initialize the factory.
* @param context
*/
@Override
public void init(ServletContext context) {
Hashtable xmlFiles = new Hashtable();
//xmlFiles.put("EN",this.getClass().getResource("/").getPath()+"Resources_en.xml");
//xmlFiles.put("IT",this.getClass().getResource("/").getPath()+"Resources_it.xml");
factory = new XMLResourcesFactory(xmlFiles,true);
}
/**
* Load dictionary, according to the specified language id.
* @param langId language id identifier
*/
@Override
public final void setLanguage(String langId) throws UnsupportedOperationException {
factory.setLanguage(langId);
}
/**
* @return internationalization settings, according with the current language
*/
@Override
public final Resources getResources() {
return factory.getResources();
}
/**
* @param langId language id identifier
* @return internationalization settings, according with the language specified
*/
@Override
public final Resources getResources(String langId) throws UnsupportedOperationException {
return factory.getResources(langId);
}
}
A classe
org.openswing.swing.server.ActionsCollections estende
Hashtable. Cada implementação da interface
Action deve ser inserida nesta
Collection, onde a chave é definida pelo retorno do método
getRequestName(), e o valor é a própria instancia de
Action.
ActionClasses.java:
package controle;
import org.openswing.swing.server.Action;
import org.openswing.swing.server.ActionsCollection;
public class ActionClasses extends ActionsCollection {
public ActionClasses() {
Action action = null;
action = new MyActions();
put(action.getRequestName(), action);
}
}
Como foi dito, você pode criar quantas implementações quiser para a interface Action, de acordo com as regras de negócio da aplicação. Neste exemplo, a regra é retornar ao cliente um objeto do tipo org.openswing.swing.message.receive.java.Response que encapsula a string Hello World From Server!.
MyActions.java
package controle;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.openswing.swing.message.receive.java.Response;
import org.openswing.swing.message.receive.java.TextResponse;
import org.openswing.swing.server.Action;
import org.openswing.swing.server.UserSessionParameters;
public class MyActions implements Action{
@Override
public Response executeCommand(Object inputPar,
UserSessionParameters userSessionPars,
HttpServletRequest request,
HttpServletResponse response, HttpSession userSession, ServletContext context) {
Object[] clientParams = (Object[]) inputPar;
String methodName = (String) clientParams[0];
if(methodName.equals("enviarHelloWorld")){
//sempre uma implementação da classe abstrata Response deve ser retornada ao cliente
return new TextResponse("Hello World From Server!");
}
return null;
}
@Override
public String getRequestName() {
return "MyActions";
}
}
Agora você deve definir a implementação dessas classes como parêmetros de inicialização da
Servlet controller do OpenSwing, adicionando as tags corespondentes ao arquivo
web.xml. Veja como fica a versão final do mesmo:
controller
org.openswing.swing.server.Controller
sessionIdGenerator
org.openswing.swing.server.DefaultSessionIdGenerator
logger
org.openswing.swing.logger.server.ConsoleLogger
objectsReceiver
org.openswing.swing.util.server.HessianObjectReceiver
connectionSource
org.openswing.swing.server.PoolerConnectionSource
controllerCallback
controle.MyControllerCallBack
resourceFactory
controle.XMLResources
actionClasses
controle.ActionClasses
1
50
controller
/controller
Aplicação Cliente
O projeto
AplicacaoCliente envia uma requisição ao servidor, se tudo correr bem, recebe de volta um objeto do tipo
org.openswing.swing.message.receive.java.Response que encapsula a mensagem
Hello WorldFrom Server! em um painel de diálogo.
No pacote
cliente do projeto crie a classe principal
ClientApplication. O código é como segue:
package cliente;
import java.util.Hashtable;
import java.util.Properties;
import javax.swing.JOptionPane;
import org.openswing.swing.internationalization.java.BrazilianPortugueseOnlyResourceFactory;
import org.openswing.swing.message.receive.java.Response;
import org.openswing.swing.message.receive.java.TextResponse;
import org.openswing.swing.util.client.ClientSettings;
import org.openswing.swing.util.client.ClientUtils;
import org.openswing.swing.util.client.HessianObjectSender;
public class ClientApplication {
public static void main(String[] args) throws Exception{
//url do servidor
String serverUrl = "http://localhost:8082/AplicacaoServidor/controller";
setConexaoServidor(serverUrl);
String serverSideActionClassName = "MyActions";
String methodName = "enviarHelloWorld";
Response serverResponse = ClientUtils.getData(serversideActionClassName, new Object[]{methodName});
if(serverResponse.isError())
throw new Exception("Erro ao conectar o servidor");
//recebe o texto de resposta
String serverMessage = ((TextResponse)serverResponse).getMessage();
JOptionPane.showMessageDialog(null, serverMessage);
}
//configura a conxão remota
private static void setConexaoServidor(String serverUrl) {
System.setProperty("SERVERURL", serverUrl);
ClientUtils.setObjectSender(new HessianObjectSender());
ClientSettings clientSettings =
new ClientSettings(
new BrazilianPortugueseOnlyResourceFactory(new Properties(), false),
new Hashtable()
);
}
}
Execute o projeto
AplicacaoCliente para exibir a mensagem recebida:
Para uma referência mais detalhada, consulte a página do
OpenSwing.