Статьи

Errai Советы


Тестирование JBoss, основанное на GWT, основанная на сообщениях
инфраструктура Errai, может быть намного более гладкой с некоторыми лучшими практиками, которые недавно
опубликовал Анил Салдхана, ведущий архитектор безопасности JBoss. Errai объединяет парадигму программирования, ориентированной на сообщения, с
RPC и Push-сообщениями. Фреймворк основан на Google Web Toolkit и построен на ErraiBus, который поддерживает модель программирования, которая пронизывает и клиента, и сервер. Это также основная идея шаблона проектирования SOA. В прошлом месяце у
DZone было интервью с Майком Броком , руководителем проекта Errai. В этом месяце Майк добавил
новые API-интерфейсы для асинхронных задачErrai, который в настоящее время в версии 1.0. Вот некоторые выдержки, которые помогут вам начать работу с Errai:

Не
создавайте
консоль GWT с нуля.

По сути, иногда это просто не стоит, говорит Салдхана. Errai Workspaces уже предоставляет вам многократно используемую инфраструктуру для макетов, виджетов и многого другого. Вот как вы добавляете инструменты в рабочую область:

@LoadTool(name = "Users", group = "Administration")                          (1)

public class UserManagement implements WidgetProvider
{
public void provideWidget(final ProvisioningCallback callback) { (2)
callback.onSuccess(new UserManagementWidget());
}

class UserManagementWidget extends LayoutPanel (3)
{
[...]
}

}

Получите свои виджеты пользовательского интерфейса от GWT Mosaic

Проект GWT Mosaic предлагает множество виджетов, которые обеспечивают хороший пользовательский опыт. Просто отсканируйте список ошибок для соответствующего проекта, потому что некоторые виджеты не очень стабильны. Возможно, вам придется использовать основные компоненты GWT, если виджеты Mosaic слишком глючат.

Код сервера перед кодом клиента

Поскольку сборка и отладка в GWT занимает некоторое время, сначала необходимо написать код сервера и тщательно протестировать его. Затем вы можете разрабатывать клиентские компоненты по мере необходимости. Салдхана говорит, что это сделает вас гораздо более продуктивным.

Объявите подписчика в клиенте (виджете) перед отправкой сообщения на сервер

В этом примере сообщение отправляется на сервер, принимая виджет на стороне клиента. Сначала вы подписываетесь на шину с «TokenProviderList» в качестве темы:

bus.subscribe("TokenProviderList", new MessageCallback()
{
public void callback(Message message)
{
//We got response from server
}
});


//Send a message to the server
MessageBuilder.createMessage()
.toSubject("TokenProviderService")
.command( TokenProviderConfigurationCommands.TOKEN_LIST )
.noErrorHandling().sendNowWith(bus);

Во-вторых, вы отправляете сообщение на сервер. Сервис называется «TokenProviderService». Порядок является существенным, потому что нет никаких подписчиков на «TokenProviderList» от шины errai. Вот фрагменты из TokenProviderService на стороне сервера:

@Service
@RequireRoles({"admin"})
public class TokenProviderService implements MessageCallback
{
private MessageBus bus;

@Inject
public TokenProviderService( MessageBus bus )
{
this.bus = bus;
}


public void callback(Message message)
{
String commandType = message.getCommandType();

if( commandType == null )
{
return;
}
String resultStr = "SUCCESS";

TokenProviderConfigurationHandler handler = new TokenProviderConfigurationHandler();

switch( TokenProviderConfigurationCommands.valueOf( commandType ) )
{
case TOKEN_ADD:
TokenProvider tokenProvider = message.get( TokenProvider.class , TokenProviderConfigurationParts.TokenProviderObj );
trace( tokenProvider );
try
{
handler.persist( tokenProvider );
message.set("RESULT", "SUCCESS" );
}
catch (Exception e)
{
log.error( "Unable to persist TokenProvider" );
resultStr = "FAILURE";
}
updateClient( message, resultStr );
break;

case TOKEN_DELETE:
String providerClass = message.get( String.class, TokenProviderConfigurationParts.ProviderClass );
Set<TokenProvider> tokenProviderSet;
try
{
tokenProviderSet = handler.getTokenProviders();
}
catch ( Exception e1)
{
log.error( "Unable to get list of token providers", e1 );
return;
}

Iterator<TokenProvider> iter = tokenProviderSet.iterator();

TokenProvider removeThisTokenProvider = null;

while( iter.hasNext() )
{
TokenProvider tp = iter.next();
if( tp.getProviderClassName().equals( providerClass ))
{
removeThisTokenProvider = tp;
break;
}
}

if( removeThisTokenProvider != null )
{
try
{
handler.remove(removeThisTokenProvider);
}
catch ( Exception e )
{
log.error( "Unable to remove TokenProvider", e);
}
}
break;

case TOKEN_UPDATE:
tokenProvider = message.get( TokenProvider.class , TokenProviderConfigurationParts.TokenProviderObj );
trace( tokenProvider );
try
{
handler.persist( tokenProvider );
}
catch (Exception e)
{
log.error( "Unable to persist TokenProvider", e);
resultStr = "FAILURE";
}
updateClient( message, resultStr );
break;

case TOKEN_LIST:
tokenProviderSet = new HashSet<TokenProvider>();
try
{
tokenProviderSet = handler.getTokenProviders();

System.out.println( "TOKEN PROVIDER LIST RECEIVED:" + tokenProviderSet.size());
}
catch ( Exception e)
{
log.error( "Unable to persist TokenProvider", e );
}
finally
{
MessageBuilder.createConversation(message)
.toSubject("TokenProviderList")
.signalling()
.with( TokenProviderConfigurationParts.TokenProviderList, tokenProviderSet )
.noErrorHandling().sendNowWith( bus );
}
break;
}
}

}

Вы можете проверить Errai
Documenation , чтобы лучше понять этот пример, или связаться с командой Errai и предложить DOCS изменения.

Выбор параметров обмена сообщениями

Ниже приведены способы выбора подходящего средства обмена сообщениями.

//SEND ONE PARAMETER  ("with" usage)
MessageBuilder.createMessage().toSubject("ClientBus")
.command(BusCommands.RemoteSubscribe)
.with(MessageParts.Subject, service)
.noErrorHandling().sendNowWith(bus);

// ZERO PARAMETERS
MessageBuilder.createMessage()
.toSubject("ClientBus")
.command(BusCommands.FinishStateSync)
.noErrorHandling().sendNowWith( bus);

//TWO PARAMETERS
MessageBuilder.createMessage()
.toSubject(remoteMonitorSubject)
.command(MonitorCommands.SubscribeEvent)
.with(MonitorParts.Time, System.currentTimeMillis())
.with(MonitorParts.MessageContent, subject)
.noErrorHandling().sendNowWith( bus );

Добавление сериализованных объектов

При добавлении сериализованных объектов в коллекции Java убедитесь, что нет дублирования объектов. Вы можете сделать это, убедившись, что методы правильно реализованы в IDE.

Вам также следует тщательно выбирать сериализованные объекты. Если у вас есть функция UserManagment, отправляющая объекты User с клиента на сервер, вам необходимо, чтобы ваш объект User был сериализуемым. Пользователь выполняет четыре операции: создание, обновление, удаление и чтение. Для создания и чтения вам необходимо передать весь объект User. Для обновления и удаления вам нужно всего лишь отправить идентификатор пользователя и поля, которые изменились.

Воспользуйтесь окном режима разработки.

Вы должны использовать окно режима разработки, чтобы просмотреть сгенерированный код Marshaller / Unmarshaller для сериализованных объектов:

Отслеживание сообщений с помощью Errai ActivityMonitor.

Этот инструмент визуализирует форматы сообщений и их содержимое, передаваемое с клиента на сервер. Это отличный инструмент для отладки тонких проблем.  

Чтобы получить ActivityMonitor:

1) Добавьте org.jboss.errai / errai-tools в качестве зависимости в ваш проект maven.

2) Установите параметр JVM «-Derrai.tools.bus_monitor_attach = true»

Maven pom:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.2.0-11137</version>
<configuration>
<inplace>true</inplace>
<logLevel>DEBUG</logLevel>
<runTarget>PicketLinkService.html</runTarget>
<warSourceDirectory>war</warSourceDirectory>
<extraJvmArgs>-Xmx512m -Derrai.tools.bus_monitor_attach=true</extraJvmArgs>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>

Вы можете узнать больше о Activity Monitor в блоге Майка Брока
.