2016-03-22 4 views
2

Ich baue einen RESTful-Service, bei dem Endpunkte basierend auf der Ressourcendateibeschreibung generiert werden sollen. Das Registrieren von Ressourcen mit implizitem Methoden-Builder-Handler funktioniert einwandfrei, aber wenn ich versuche, den impliziten Handler durch explizite zu ersetzen, stoße ich gegen eine Wand.Custom jersey Inflector

Im folgenden Beispiel habe ich den impliziten Handler Inflector durch die explizite Implementierung von ItemInflector ersetzt. String-Ergebnis wird nach der Ausführung erwartet.

final Resource.Builder resourceBuilder = Resource.builder(); 
resourceBuilder.path("api/myservice/item"); 
final ResourceMethod.Builder methodBuilder = resourceBuilder.addMethod("GET"); 

methodBuilder.produces(MediaType.TEXT_PLAIN_TYPE) 
    .handledBy(new ItemInflector<ContainerRequestContext, String>(String.class)); 

final Resource resource = resourceBuilder.build(); 
registerResources(resource); 

ItenInflector Umsetzung:

public class ItemInflector<DATA extends ContainerRequestContext, RESULT> implements Inflector<DATA, RESULT> { 

    private Class<RESULT> type; 

    public ItemInflector(Class<RESULT> type) { 
     this.type = type; 
    } 

    @Override 
    public RESULT apply(DATA data) { 
     return type.cast("Half programmatically generated endpoint"); 
    } 
} 

Zur Laufzeit wird der folgende Fehler ausgelöst wird, wenn ich versuche, Endpunkt zu treffen.

Caused by: java.lang.IllegalArgumentException: Type parameter RESULT not a class or parameterized type whose raw type is a class 

Könnte jemand klären, was mache ich falsch in der Inflector-Implementierung? Wie parametriere oder definiere RESULT Typ?

Antwort

1

Der Typparameter (<ContainerRequestContext, String>), der während der Instanzerstellung ItemInflector angegeben wurde, geht zur Laufzeit verloren. Der Grund ist Javas type erasure Verhalten. Sie müssen den Typ in einer Unterklasse angeben oder hier anonyme Klassen verwenden.

Option 1, anonyme Klasse (ja, jetzt der Compiler die Typinformationen hält):

methodBuilder.produces(MediaType.TEXT_PLAIN_TYPE) 
    .handledBy(new Inflector<ContainerRequestContext, String>(){ 
     ... 
    }); 

Option 2, geben Sie Typ in einem sublcass:

public class ItemInflector implements Inflector<ContainerRequestContext, String> { 
.... 
} 

Hier eine sehr detaillierte Information bezüglich des Typs Löschverhalten: Java generics - type erasure - when and what happens

+0

Würde es Ihnen etwas ausmachen, zu aktualisieren die zweiten Links, es ist kaputt. – Maxim

+0

bereits erledigt :) –