Mit JAX-RS (Java™ API for RESTful Web Services) können Sie einen angepassten Entitätsprovider
zur Anwendung hinzufügen. Verwenden Sie angepasste Entitätsprovider, wenn Sie Java-Typen verwenden möchten,
um eingehende und abgehende Antwortnachrichtentexte darzustellen. Durch das Hinzufügen eines angepassten Entitätsproviders können Sie angepasste Java-Typen
aus Nachrichtentexten entserialisieren und alle Medientypen als Nachrichtentexte serialisieren.
Informationen zu diesem Vorgang
Ein angepasster Entitätsprovider wird erstellt, indem eine Klasse mit einer Annotation des Typs
"javax.ws.rs.ext.Provider" versehen wird. Die Klasse muss die Schnittstellen "javax.ws.rs.ext.MessageBodyReader" und/oder
"javax.ws.rs.ext.MessageBodyWriter" implementieren. Sie müssen die Providerklasse zur Liste der Klassen hinzufügen, die in der Methode getClasses()
der Unterklasse "javax.ws.rs.core.Application" zurückgegeben werden.
Vorgehensweise
- Erstellen Sie eine neue Java-Klasse, die Ihr neuer angepasster Entitätsprovider ist. In dieser Prozedur erstellt der Beispielcode einen Reader und einen Writer für com.ibm.json.java.JSONObject-Typen,
daher können Sie den com.ibm.json.java.JSONObject-Typ als eingehenden Anforderungsentitätsparameter und als Rückgabetyp
für die Antwortentität verwenden.
public class MyEntityProvider {
}
- Fügen Sie die Annotation "@javax.ws.rs.ext.Provider" hinzu. Wenn Sie diese Annotation hinzufügen, zeigen Sie der JAX-RS-Laufzeitumgebung damit an, dass diese Klasse ein JAX-RS-Provider ist. Wird diese
Providerannotation nicht angegeben, kann die Laufzeitumgebung nicht feststellen, dass die Klasse ein angepasster Provider ist.
@javax.ws.rs.ext.Provider
public class MyEntityProvider {
}
- Optional: Fügen Sie eine @javax.ws.rs.Consumes- oder eine @javax.ws.rs.Produces-Annotation hinzu, wenn Sie die Medientypen, die der Entitätsprovider
unterstützt, begrenzen möchten. Im folgenden Codeausschnitt wird der Provider nur aufgerufen, wenn der eingehende bzw. abgehende Inhaltstyp (Content-Type)
application/json ist.
@javax.ws.rs.ext.Provider
@javax.ws.rs.Consumes("application/json")
@javax.ws.rs.Produces("application/json")
public class MyEntityProvider {
}
- Implementieren Sie javax.ws.rs.ext.MessageBodyReader<T>, wenn der Entitätsprovider einen Nachrichtentext entserialisieren muss.
Sie können den generischen Typ <T> verwenden, um die Typen, die vom Entitätsprovider unterstützt werden, zu begrenzen.
Wenn Sie
javax.ws.rs.ext.MessageBodyReader<com.ibm.json.java.JSONObject> als Reader des Nachrichtentextes definieren,
weiß die JAX-RS-Laufzeitumgebung, dass nur com.ibm.json.java.JSONObject-Objekte erstellt werden können.
Wenn ein Entitätsprovider eine komplexe Typengruppe unterstützen muss, sollten Sie die Implementierung von
javax.ws.rs.ext.MessageBodyReader<Object> in Erwägung ziehen.
@javax.ws.rs.ext.Provider
@javax.ws.rs.Consumes("application/json")
@javax.ws.rs.Produces("application/json")
public class MyEntityProvider implements
javax.ws.rs.ext.MessageBodyReader<com.ibm.json.java.JSONObject> {
public boolean isReadable(Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType) {
return com.ibm.json.java.JSONObject.class == type;
}
public com.ibm.json.java.JSONObject readFrom(Class<com.ibm.json.java.JSONObject> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream) throws IOException, WebApplicationException {
/* Dieser Eingabedatenstrom (InputStream) liest aus dem Entitätsdatenstrom (entityStream) und erstellt das Objekt. */
com.ibm.json.java.JSONObject retObj = com.ibm.json.java.JSONObject.parse(entityStream);
return retObj;
}
}
- Implementieren Sie javax.ws.rs.ext.MessageBodyWriter<T>, wenn der Entitätsprovider einen Nachrichtentext serialisieren muss. Sie können die Schnittstellen "MessageBodyReader<T>" und "MessageBodyWriter<T>" in derselben Java-Klasse
implementieren. Im folgenden Codeausschnitt wird nur die MessageBodyWriter-Implementierung gezeigt.
@Provider
public class MyEntityProvider implements
MessageBodyWriter<Object> {
public long getSize(Object t,
Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType) {
/* Gibt -1 zurück, wenn die Länge des Inhalts nicht bestimmt werden kann. */
return -1;
}
public boolean isWriteable(Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType) {
return MyType.class == type;
}
public void writeTo(Object t,
Class<?> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders,
OutputStream entityStream) throws IOException, WebApplicationException {
entityStream.write(MyType.getBytes());
}
}
- Fügen Sie den angepassten Entitätsprovider zur Unterklasse javax.ws.rs.core.Application und den Provider
zur Gruppe der Klassen zurück, die von der Methode getClasses() zurückgegeben werden. Sie können mehrere angepasste Entitätsprovider zu der Gruppe der Klassen hinzufügen, die zurückgegeben wird.
public class MyApplication extends javax.ws.rs.core.Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(MyEntityProvider.class);
return classes;
}
}
Ergebnisse
Sie haben einen angepassten Entitätsprovider definiert und zu Ihrer JAX-RS-Webanwendung hinzugefügt.
Fehler vermeiden: Achten Sie auf die folgenden Hinweise, wenn Sie bei der Implementierung angepasster Entitätsformate allgemeine Fehler lösen möchten:
- Angepasste Provider werden nicht lokalisiert.
Gehen Sie wie folgt vor, um das Problem zu beheben:
- Vergewissern Sie sich, dass der Provider die Annotation "@javax.ws.rs.ext.Provider" aufweist. Eine
Klasse ohne Annotation wird nicht als Provider registriert.
- Vergewissern Sie sich, dass der Provider zur Gruppe der Klassen hinzugefügt wird, die von der Methode
getClasses() für die Unterklassen der Klasse "javax.ws.rs.core.Application" zurückgegeben wird.
- Vergewissern Sie sich, dass der Wert für "@javax.ws.rs.Produces" bzw. "@javax.ws.rs.Consumes"
für die Providerklasse richtig ist.
- Vergewissern Sie sich, dass die Methode "javax.ws.rs.ext.MessageBodyReader#isReadable"
und "javax.ws.rs.ext.MessageBodyWriter#isWritable" richtig implementiert sind und bei Verwendung den Wert
true zurückgeben.
- Header oder Ausgabe des angepassten Entitätsproviders "MessageBodyWriter" ist falsch.
Gehen Sie wie folgt vor, um das Problem zu beheben:
- Vergewissern Sie sich, dass der Größenwert für die Antwort "javax.ws.rs.ext.MessageBodyWriter#getSize"
entweder -1 lautet (bei nicht bekannter Größe) oder die richtige Größe angibt. Ist der Größenwert falsch angegeben,
wird die Antwort von Clients möglicherweise abgeschnitten.
- Wenn HTTP-Header in der Methode "javax.ws.rs.ext.MessageBodyWriter#writeTo" definiert sind, müssen Sie die Header
vor dem Senden der restlichen HTTP-Antwort definieren. HTTP-Header werden zu Beginn einer Antwort gesendet. Daher wäre es zu spät, Antwortheader
erst zu senden, wenn der Hauptteil der Antwortnachricht bereits an den Client gesendet wird.
gotcha