Sie können Java™ Contexts
and Dependency Injection (JCDI) verwenden, um Interceptor und Dekoratoren für
JAX-RS-Ressourcentypen (Java API for RESTful Web
Services) zu schreiben. Mithilfe der Interceptor- und Dekoratorfunktionen von JCDI
können Sie beispielsweise Aufrufe einer bestimmten Klasse protokollieren oder Sicherheitsprüfungen
durchführen, bevor eine Methode aufgerufen wird, wenn
Webanwendungen, die JCDI unterstützen, mit JAX-RS verwendet werden.
Informationen zu diesem Vorgang
Es gibt zwei Methoden für das Hinzufügen von Cross-cutting Concerns in Ihrer Anwendung.
Interceptorbindungen erfordern eine angepasste Annotation. Die Annotation wird verwendet, um
die abzufangenden Methoden zu markieren.
Dekoratoren implementieren den Basistyp.
Anschließend können Sie mit einer injizierten @javax.decorator.Decorator-Instanz spezielle
Logik um die Aufrufe an den injizierten Beauftragten herum implementieren.
Vorgehensweise
- Erstellen Sie eine Annotation, um anzuzeigen, dass eine Methode abgefangen werden soll. Diese SecurityChecked-Annotation kennzeichnet eine Methode, in der einige Sicherheitsinformationen
geprüft werden.
Das folgende Beispiel veranschaulicht eine angepasste Annotation mit einer abgefangenen Methode:
package com.example.jaxrs;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.interceptor.InterceptorBinding;
@Inherited
@InterceptorBinding
@Target( {ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SecurityChecked {
}
- Erstellen Sie Ihre JAX-RS-Ressourcenklasse, und annotieren Sie alle Methoden, die abgefangen werden sollen, mit der Annotation
@com.example.jaxrs.SecurityChecked. Das folgende Beispiel veranschaulicht eine JAX-RS-Ressourcenklasse mit einer abgefangenen Methode:
package com.example.jaxrs;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Path;
import javax.ws.rs.GET;
@Path("exampleInterceptor")
@RequestScoped
public class MyResourceBean {
@GET
@com.example.jaxrs.SecurityChecked
public String echo(String hello) {
return "Hello world!";
}
}
- Schreiben Sie eine Interceptorklasse, die mit der Annotation
@javax.interceptor.Interceptor und mit der Interceptormarkierung
@com.example.jaxrs.SecurityChecked annotiert ist.
Fügen Sie anschließend eine Methode, die mit der Annotation @javax.interceptor.AroundInvoke
mit dem Parameter javax.interceptor.InvocationContext annotiert ist. Sie können die InvocationContext-Methoden verwenden, um den Methodenaufruf
zu prüfen und um zu bestimmen, ob der Aufruf fortgesetzt werden soll.
Das folgende Beispiel veranschaulicht einen Interceptor:
package com.example.jaxrs;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
@com.example.jaxrs.SecurityChecked
public class SecurityCheckInterceptor {
@AroundInvoke
public Object checkSecurity(InvocationContext context) throws Exception {
/* Parameter prüfen oder eine generische Sicherheitsprüfung vor dem Aufruf
der ursprünglichen Methode durchführen */
Object[] params = context.getParameters();
/* Wenn die Sicherheitsprüfung scheitert, können Sie eine Ausnahme auslösen */
/* Methode proceed() aufrufen, um die ursprüngliche Methode aufzurufen */
Object ret = context.proceed();
/* Alle erforderlichen Aufgaben nach dem Methodenaufruf ausführen */
return ret;
}
}
- Fügen Sie Ihrer Webanwendung (WAR-Datei) im Verzeichnis
WEB-INF einen Implementierungsdeskriptor beans.xml hinzu. Das Vorhandensein der Datei WEB-INF/beans.xml zeigt an, dass es sich bei dem Archiv
um ein Archiv handelt, das JCDI unterstützt.
Sie müssen einige Informationen für diese Instanz hinzufügen.
Das folgende Beispiel veranschaulicht eine Datei
WEB-INF/beans.xml mit einem aufgelisteten Interceptor:
<?xml version="1.0 encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http://
java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.example.jaxrs.SecurityCheckInterceptor</class>
</interceptors>
</beans>
In den vorherigen Schritten haben Sie eine Webanwendung
für die Verwendung von JCDI konfiguriert, eine angepasste Annotation hinzugefügt, um
abzufangende Methoden zu markieren, und einen Interceptor geschrieben.
Beim Aufruf einer markierten Methode wird der Interceptor verwendet, um zu bestimmen, ob die markierte
Methode aufgerufen werden soll und weitere Logik ausführen kann.
Sie müssen die Interceptor in Ihrem Implementierungsdeskriptor beans.xml auflisten.
In den verbleibenden Schritten erstellen und aktivieren Sie einen Dekorator
in einer Webanwendung, die JCDI unterstützt.
Interceptorbindungen erfordern eine Annotation, um die abzufangenden Methoden zu markieren.
Dekoratoren implementieren den allgemeinen Basistyp und können die Aufrufe einschließen.
- Suchen oder erstellen Sie den Basistyp, den der Dekorator implementieren muss. Der Basistyp kann beispielsweise eine Schnittstelle mit dem Namen Item sein.
Das folgende Beispiel veranschaulicht eine allgemeine Schnittstelle, die von einem Dekorator verwendet wird:
package com.example.jaxrs;
import javax.ws.rs.GET;
public interface Item {
@GET
public String getInformation();
}
- Erstelle Sie eine JAX-RS-Standardressourcenklasse, die den Basistyp implementiert. Das folgende Beispiel veranschaulicht eine JAX-RS-Ressourcenklasse, die dekoriert wird:
package com.example.jaxrs;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Path;
@Path("decoratedresource")
@RequestScoped
public class MyItem implements Item {
public String getInformation() {
/* return some information */
}
}
- Erstellen Sie eine Dekoratorklasse. Die Dekoratorklasse muss den Basistyp implementieren, in den alle Aufrufe eingeschlossen werden.
Der Dekorator muss mit der Annotation
@javax.decorator.Decorator annotiert werden.
Der Dekorator muss ein Sonderfeld, einen so genannten Injektionspunkt für den Beauftragten, mit dem Basistyp haben.
Das Feld kann einen beliebigen Namen haben, muss aber eine Annotation
@javax.inject.Inject und eine Annotation @javax.decorator.Delegate haben.
Dieses Feld ist das ursprüngliche Objekt, das dekoriert wird. Anschließend können Sie dieses dekorierte Objekte
in Ihren Implementierungsaufrufen verwenden.
Das folgende Beispiel veranschaulicht eine Basisdekoratorklasse:
package com.example.jaxrs;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.inject.Inject;
@Decorator
public class MyItemDecorator implements Item {
@Inject
@Delegate
private Item decoratedItem;
public String getInformation() {
/* perform some logging */
String info = decoratedItem.getInformation();
/* perform some more logging */
return info;
}
}
- Fügen Sie Ihrer Webanwendung (WAR-Datei) im Verzeichnis
WEB-INF einen Implementierungsdeskriptor beans.xml hinzu. Das Vorhandensein der Datei WEB-INF/beans.xml zeigt an, dass es sich bei dem Archiv
um ein Archiv handelt, das JCDI unterstützt.
Sie müssen einige Informationen zu den aktiven Dekoratorklassen für diese Instanz hinzufügen.
Das folgende Beispiel veranschaulicht eine Datei
WEB-INF/beans.xml mit einem aufgelisteten Dekorator:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http://
java.sun.com/xml/ns/javaee/beans_1_0.xsd">
<interceptors>
<class>com.example.jaxrs.SecurityCheckInterceptor</class>
</interceptors>
<decorators>
<class>com.example.jaxrs.MyItemDecorator</class>
</decorators>
</beans>
Ergebnisse
Sie haben eine Webanwendung für die Verwendung von JCDI konfiguriert, einen Methodeninterceptor für eine Ressource erstellt,
einen Dekorator erstellt und diesen für die Dekoration Ihrer Methodenaufrufe für eine zweite Ressource aktiviert.