SIwpas, Сервер приложений простого веб-профиля — это сервер, совместимый с веб-профилем Java EE, который содержит проекты Apache Software Foundation. Цель SIwpas — интегрировать проекты Apache Software Foundation (ASF) JavaTM, Enterprise Edition 6 (Java EE 6), связанные со спецификацией веб-профиля, в Apache Tomcat 7 для создания сервера, совместимого с веб-профилем Java EE 6.
В этой статье я покажу простой пример калькулятора JSF 2.0 с изложением:
- Как использовать EJB-компоненты в управляемых компонентах CDI с помощью внедрения зависимостей,
- Как использовать CDI Interceptors и Decorators для сессионных компонентов EJB
- Как использовать управляемые компоненты CDI в среде выполнения JSF 2
Если вы хотите попробовать пример, загрузите SIwpas с http://code.google.com/p/siwpas/ , пример веб-проекта Eclipse «siwpas-sample-collapse» с http://siwpas.googlecode.com/svn / trunk / samples / siwpas-sample-collapse / и развернуть его в SIwpas !. Нажмите на ссылку http: // localhost: 8080 / siwpas-sample-collapse / Calculate.jsf.
Примеры экранов
Начальный экран
Записать 5 в X и 5 в Y и нажать Рассчитать
Давайте начнем кодировать!
У нас будет страница JSF, которая добавляет два числа и печатает результат на странице.
JSF 2 CDI Managed Bean
У нас есть JSF CDI Managed bean, который мы будем использовать на нашей странице JSF через выражения EL. Наш управляемый bean-компонент имеет @RequestScoped, что означает, что он будет создан в начале запроса и отброшен в конце запроса контейнером CDI OpenWebBeans. Его имя — «калькулятор, который явно определен аннотацией @Named. Если нам нужно имя по умолчанию для нашего управляемого компонента, просто аннотируйте его, используя @Name без« значения ».
Наш управляемый бин внедряет сессионный EJB-компонент, используя два разных подхода;
- Использование аннотации @Inject: предоставляется CDI. Здесь OpenWebBeans внедряет сессионный компонент CDI, который проксирует фактический прокси экземпляра сессионного компонента.
- Использование аннотации @EJB: это обеспечивается Java EE. Здесь OpenWebBeans напрямую внедряет экземпляр прокси-сервера Session Beans.
Результат тот же. Обе инъекционные техники работают в SIwpas.
@Named(value="calculator")
@RequestScoped
public class CalculatorBean
{
//Inject using OpenWebBeans
private @Inject ICalculator calculator;
//Inject using @EJB with default interface type of field injection
private @EJB ICalculator injectViaEjbAnnotation;
private int x;
private int y;
private int result;
public String add()
{
this.result = calculator.add(x, y);
System.out.println(injectViaEjbAnnotation.add(x, y) == this.result);
return null;
}
public int getX()
{
return this.x;
}
public void setX(int x)
{
this.x = x;
}
public int getY()
{
return y;
}
public void setY(int y)
{
this.y = y;
}
public int getResult()
{
return this.result;
}
public void setResult(int rESULT)
{
this.result = rESULT;
}
}
Написание нашего сессионного компонента
У нас будет сессионный компонент без сохранения состояния. Сначала напишите локальный интерфейс,
@Local
public interface ICalculator
{
public int add(int x,int y);
}
Затем реализация
@Stateless
@Log
@Interceptors(value={OldTypeInterceptor.class})
public class Calculator implements ICalculator
{
private @Inject SimpleBean simpleBean;
public int add(int x, int y)
{
System.out.println(simpleBean);
return x+y;
}
@PostConstruct
public void postConstruct()
{
System.out.println("In post construct Bean");
}
}
Здесь вы видите некоторые аннотации на бине сеанса калькулятора @Stateless — это маркерная аннотация, в которой говорится, что класс является сессионным компонентом. @Interceptors определяется спецификацией EJB, которая добавляет перехватчики к сессионному компоненту.
CDI Interceptors
Интересная вещь здесь — аннотация @Log. @Log — аннотация привязки перехватчика CDI. Он добавляет связанный с CDI экземпляр перехватчика в стек перехватчика сессионного компонента. Он вызывается после экземпляра перехватчика старого типа.
Вот код для @Log
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.TYPE,ElementType.METHOD})
public @interface Log
{
}
@InterceptorBinding — это маркерная аннотация для привязок перехватчиков.
Давайте посмотрим на фактический перехватчик
@Interceptor
@Log
public class LogInterceptor
{
private @Inject SimpleBean simple;
@PostConstruct
public void postConstruct(InvocationContext context)
{
System.out.println(simple);
System.out.println("Post Construct");
}
@PreDestroy
public void preDestroy(InvocationContext context)
{
System.out.println("Pre Destroy");
}
@AroundInvoke
public Object around(InvocationContext ctx) throws Exception
{
System.out.println("Logging");
return ctx.proceed();
}
}
Это класс перехватчиков на основе CDI. Он аннотирован @Interceptor и @Log. Это относится ко всем bean-компонентам, аннотированным @Log, например, к нашему bean-компоненту калькулятора
CDI Декораторы
CDI-декораторы похожи на CDI-перехватчики. Основное отличие состоит в том, что их методы уникальны для некоторых классов бинов. Давайте посмотрим на класс декоратора
@Decorator
public class AddDecorator implements ICalculator
{
private @Inject @Delegate ICalculator calculator;
public int add(int x, int y)
{
return calculator.add(x, y);
}
}
Здесь мы аннотируем класс AddDecorator с помощью @Decorator. Класс AddDecorator реализует ICalculator и внедряет экземпляр делегата с помощью @Inject @Delegate. Здесь, @Delegate важен, потому что он предоставляет информацию контейнеру CDI относительно того, какие экземпляры бинов будут иметь этот декоратор в своем стеке декораторов. Здесь AddDecorator применяется ко всем экземплярам бинов, которые имеют ICalculator в своих типах API. Мы также можем добавить qulifier в точки ввода @Delegate. В этом случае декоратор будет доступен для bean-компонентов, имеющих одинаковый тип API и спецификатор. Если явного квалификатора нет, как указано выше, квалификатор — @Default.
CalculatorBean имеет тип API ICalculator и квалификатор @Default. Следовательно, AddDecorator добавляется в его стек декоратора. Декораторы называются после перехватчиков.
Включение Интерпреторов и Декораторов
Чтобы использовать перехватчики и декораторы, мы должны включить их в архиве компонентов. Поэтому мы включаем их в файл WEB-INF / beans.xml.
<beans>
<interceptors>
<class>siwpas.sample.interceptor.LogInterceptor</class>
</interceptors>
<decorators>
<class>siwpas.sample.decorator.AddDecorator</class>
</decorators>
</beans>
Теперь их можно использовать внутри архива бинов.
Наша страница JSF
Давайте посмотрим на нашу страницу JSF, посмотрим, как мы используем выражения EL с именем управляемого компонента, «калькулятор»
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Collapsed EAR</title>
</h:head>
<h:body>
<h:form>
<h:outputText>X :</h:outputText>
<h:inputText value="#{calculator.x}"></h:inputText>
<h:outputText>Y :</h:outputText>
<h:inputText value="#{calculator.y}"></h:inputText>
<h:commandButton value="Calculate" action="#{calculator.add}"></h:commandButton>
</h:form>
<div>
<h:outputText value="Result : #{calculator.result}"></h:outputText>
</div>
</h:body>
</html>
Наш web.xml для некоторых вещей JSF
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jsp</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
</web-app>
Как это работает
Когда запрос поступает из браузера, контейнер CDI ищет компонент с именем «калькулятор». Он находит CalculatorBean и смотрит его объем. В нашем примере наша область действия — @RequestScoped. Он создает свой экземпляр и сохраняет его в области запроса. Контейнер CDI внедряет все свои зависимости (как CDI, так и Java EE. Вы также можете добавить компоненты @Resource, @WebServiceRef, @PersistenceContext, @PersistenceUnit Java EE.)
Когда EL-метод «add» выполняется, контейнер CDI выполняет все перехватчики, декораторы EJB-компонента и, наконец, выполняет метод «add». После завершения запроса область действия запроса уничтожается, и все его экземпляры отбрасываются. Ответ отправляется в браузер.
Вывод
Java EE 6 упрощает разработку веб-приложений. Это основная мотивация Java EE 6! Он также предоставляет веб-профиль Java EE, содержащий только стандарты для реализации веб-приложений Java EE.
Дальнейшая информация
Страница SIwpas: http://code.google.com/p/siwpas/
Apache OpenWebBeans: http://openwebbeans.apache.org
Apache MyFaces: http://myfaces.apache.org
Apache OpenJPA: http://openjpa.apache.org
Apache OpenEJB: http://openejb.apache.org
Apache Tomcat: http://tomcat.apache.org
Веб-профиль Java EE 6: http://jcp.org/en/jsr/detail?id=316