Category Archive: Seam framework

RESTful веб-сервис в Seam Framework

Seam Framework уже включает в себя реализацию спецификации JAX-RS под названием RESTEasy. В библиотеках Seam вы можете увидеть три jar-файла, относящихся к RESTEasy:
  • jaxrs-api.jar
  • resteasy-jaxrs.jar
  • jboss-seam-resteasy.jar
Настройка В вашем проекте найдите и откройте файл components.xml. К корневому элементу components добавьте следующее пространство имен:
xmlns:resteasy="http://jboss.com/products/seam/resteasy"
Также необходимо добавить объявление префикса:
<resteasy:application resource-path-prefix="/restv1"/>
В нашем случае префикс будет restv1. Префикс обычно используется для версионности. Вид components.xml после внесения наших изменений:
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
            xmlns:core="http://jboss.com/products/seam/core"
            xmlns:drools="http://jboss.com/products/seam/drools"
            xmlns:mail="http://jboss.com/products/seam/mail"
            xmlns:persistence="http://jboss.com/products/seam/persistence"
            xmlns:security="http://jboss.com/products/seam/security"
            xmlns:web="http://jboss.com/products/seam/web"
            ...
            xmlns:resteasy="http://jboss.com/products/seam/resteasy"><!--Добавлено-->
            ....
            <resteasy:application resource-path-prefix="/restv1"/><!--Добавлено-->
</components>
Объявим наш класс, который будет обрабатывать REST-запросы:
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
@Path("/ttt")
public class Test {
    @GET
    public Response echo(){
        String msg = "Hello, World!!!";
        System.out.println(msg);
        return Response.status(200).entity(msg).build();
    }
}
Что делает этот класс? По пути /ttt принимает GET-запрос и выводит сообщение "Hello, World!!!" в лог и возвращает его же в качестве ответа. Сервис доступен по адресу: http://<Сервер>:<Порт>/<Имя веб-приложения>/seam/resource/restv1/ttt Если ввести в браузер этот адрес, то в лог и в браузер будет выведено сообщение: "Hello, World!!!" Более полную информацию смотрите в документации к Seam Framework: 24.4. RESTful HTTP webservices with RESTEasy

Шаблоны для построения интерфейса на Seam Framework 2.2.0 с использоватеним RichFaces 3.3.3

template.xhtml - шаблон, который будут использовать другие страницы
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:rich="http://richfaces.org/rich"
      xmlns:a="http://richfaces.org/a4j"
      xmlns:s="http://jboss.com/products/seam/taglib">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>#{interface['system.name']}</title>
    <link rel="shortcut icon" href="#{facesContext.externalContext.requestContextPath}/img/favicon.ico" type="image/x-icon"/>
    <link href="#{facesContext.externalContext.requestContextPath}/css/theme.css" rel="stylesheet" type="text/css"/>
    <ui:insert name="scripts"/>
</head>
<body>
 
<noscript style="text-align: center; font-size:9pt; color:red;">
    <div>
        <br/>
        <strong>Для корректной работы необходим браузер с поддержкой JavaScript</strong>
    </div>
</noscript>
 
<TABLE width="100%" cellpadding="0" cellspacing="0">
    <ui:insert name="body"/>
</TABLE>
 
</body>
</html>

Страница, использующая шаблон
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:s="http://jboss.com/products/seam/taglib"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:rich="http://richfaces.org/rich"
                xmlns:a="http://richfaces.org/a4j"
                template="../layout/template.xhtml">
    <ui:define name="body">
        <rich:panel>
            <f:facet name="header">#{interface['page.name']}</f:facet>
            <h:messages globalOnly="true" styleClass="message"/>
            <h:form>
 
            </h:form>
        </rich:panel>
    </ui:define>
</ui:composition>

Вывод таблицы
<rich:dataTable id="tableList"
	rowKeyVar="rowIndex" var="req"
	value="#{workManager.foundRequestList}">
 
</rich:dataTable>

Вывод таблицы постранично
<rich:datascroller align="center" for="tableList" maxPages="10"
				   page="#{workManager.dataTableScrollerBean.currentPage}"
				   style="width:100%;" fastStep="5" fastControls="auto"
				   renderIfSinglePage="false">
	<f:facet name="first">
		<h:outputText value="#{interface['first.page']}"/>
	</f:facet>
	<f:facet name="last">
		<h:outputText value="#{interface['last.page']}"/>
	</f:facet>
	<f:facet name="previous">
		<h:outputText value="#{interface['previous.page']}"/>
	</f:facet>
	<f:facet name="next">
		<h:outputText value="#{interface['next.page']}"/>
	</f:facet>
	<f:facet name="fastrewind">
		<h:outputText value="-5"/>
	</f:facet>
	<f:facet name="fastforward">
		<h:outputText value="+5"/>
	</f:facet>
</rich:datascroller>
 
<rich:dataTable id="tableList"
	rowKeyVar="rowIndex" var="req" rows="10"
	value="#{workManager.foundRequestList}">
 
</rich:dataTable>

Вывод сообщения о том, что в таблице нет записей
<s:div rendered="#{empty workManager.foundRequestList}"
	   styleClass="nodata">
	<h:outputText value="#{interface['list.is.empty']}"/>
</s:div>

Два JBoss 4.2.2 на одном сервере

Опишу сначала ситуацию: Два приложения на Seam Framework (два war-ника) нужно было запустить на одном сервере, но т.к. в приложениях многие seam-компоненты, которые были созданы, имели одинаковые имена, был конфликт. Можно, конечно, добиться уникальности названий компонентов, но это нужно переписать кучу кода и в дальнейшем следить за уникальностью названий в обоих приложениях. Я пошел по этому пути, и приложения запускались и работал без ошибок, но при работе с сервисами возникли проблемы, т.к. jboss путался в компонентах. Тогда пришло решение запустить приложения на разных jboss'ах. Запустить два jboss'а на одном сервере относительно просто: нужно добиться того, чтобы jboss'ы не использовали одинаковые порты, а этих портов не мало. И чтобы не путаться в портах, к портам одного их jboss'ов можно добавлять единичку. Это выглядит так: 8009 -> 18009, 1099 -> 11099, 1098 -> 11098 и т.д. Я делал следующим образом: запускал один jboss, после его полной загрузки запускал второй и смотрел какие порты конфликтуют, заменял эти порты, потом еще раз перезапускал второй jboss до тех пор, пока второй jboss стартовал без конфликтов портов. Ниже приведу список файлом и замен портов (конфигурация default):
bin\run.bat 8787 -> 18787
server\default\conf\jboss-service.xml 8083 -> 18083 1099 -> 11099 1098 -> 11098 4444 -> 14444 4445 -> 14445 4446 -> 14446
server\default\deploy\ejb3.deployer\META-INF\jboss-service.xml 3873 -> 13873 (этот порт встречается дважды в файле)
server\default\deploy\jboss-web.deployer\server.xml 8080 -> 8085 (порты через, которые будет работать web) 443 -> 1443 5443 -> 15443 8009 -> 18009
server\default\deploy\jms\uil2-service.xml 8093 -> 18093
Также нужно учесть, что теперь debug первого приложения будет по порту 8787, а второго по порту 18787.