2013-03-29 6 views
6

Ich kämpfe für ein paar Tage jetzt mit dem folgenden Problem. Ich habe ziemlich viel nach einer Antwort gesucht, hier in SO, in Jersey-Mailinglisten und dem Netz im Allgemeinen, aber ich war nicht in der Lage, eine Antwort auf diese spezielle Frage zu finden.Generierte WADL für eine Liste von Ressourcen

das Problem Domain einrichten ...

Ich verwende Jersey 1,16 innerhalb Tomcat 7.

Ich habe eine einfache JAX-RS-Ressource erstellt wie folgt aussehen:

@Path("/") 
@Produces({ "application/xml", "text/plain" }) 
public class ExampleResource { 

    @GET 
    public List<Thing> getThings() { 
     List<Thing> list = new ArrayList<>(); 
     list.add(new Thing("a thing 1", "a thing description 1")); 
     list.add(new Thing("a thing 2", "a thing description 2")); 

     return list; 
    } 

} 

Thing ist ein mit JAXB annotierter POJO, der wie folgt aussieht

 @XmlRootElement(name = "thing") 
     public class Thing { 
      private String name;   
      private String description; 
// getters, setters and @XmlElement annotations ommited for brevity 

Ich habe auch WadlGeneratorJAXBGrammarGenerator.class

konfiguriert Und wenn ich für GET http://localhost:8092/rest fragen funktioniert es wie ein Zauber - schön formatierte Sammlung von Thing zurückgegeben.

Die automatisch generierte WADL http://localhost:8092/rest/application.wadl ist fast perfekt, es sieht wie folgt aus:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<application xmlns="http://wadl.dev.java.net/2009/02"> 
    <doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 1.16 11/28/2012 02:09 PM" /> 
    <grammars> 
     <include href="application.wadl/xsd0.xsd"> 
      <doc title="Generated" xml:lang="en" /> 
     </include> 
    </grammars> 
    <resources base="http://localhost:8092/rest/"> 
     <resource path="/"> 
      <method id="getThings" name="GET"> 
       <response> 
        <ns2:representation xmlns:ns2="http://wadl.dev.java.net/2009/02" 
         xmlns="" element="thing" mediaType="application/xml" /> 
        <representation mediaType="text/plain" /> 
       </response> 
      </method> 
     </resource> 
    </resources> 
</application> 

Wie ich schon sagte, fast perfekt, und darin liegt das Problem.

<ns2:representation xmlns:ns2="http://wadl.dev.java.net/2009/02" 
          xmlns="" element="thing" mediaType="application/xml" /> 

Die WADL beschreibt, ist nicht, dass /getThings eine List<Thing> zurückgibt. Es sieht eher so aus, als ob es sich auf ein einzelnes Element thing in der xsd0.xsd bezieht. Also, wenn ich es z. wadl2java, generiert es untypisierte Client. Um ein List<Thing> ich manuell codieren, es zu bekommen, so etwas wie

List<Thing> asXml = root().getAsXml(new GenericType<List<Thing>>(){});

Weiß jemand, ob es möglich ist, die automatische WADL Generation zu haben, die irgendwie zeigen würden, dass diese bestimmte Ressource eine Liste zurückkehrt von Ressourcen eines bestimmten Typs?

Und ich nicht möchte zusätzliche "ThingList" JAXB-annotierte Klasse erstellen und diese stattdessen in meinem Jersey Ressource zurückgeben.

ich fast da bin mit dem „perfekten“ WADL zu erzeugen, ist es gerade dieses (hoffentlich) kleine Stück, das ich fehle ...

Vielen Dank!

+0

ich mit WADL nicht allzu vertraut bin, aber, was (XML) Wert für diese Linie optimal wäre Sie zitiert? In wsdls werden Listen und einfache Objekte fast auf die gleiche Weise dargestellt. – acdcjunior

+0

Es kam mir nicht in den Sinn, mich mit WSDL zu vergleichen, da ich fast keine Erfahrung damit habe. Du hast also einen guten Punkt. Wie das aussehen soll, darüber bin ich mir auch nicht so sicher. Können Sie vielleicht ein Beispiel geben, wie es in WSDL aussehen würde? – Svilen

+0

In einer WSDL wird eine Entität (z. B. "Person") zu einem "xs: complexType" mit einem Element für jede Eigenschaft, die sie hat. Eine Eigenschaft, etwa 'String name', sieht wie folgt aus: ' (die 'minOccurs = '0'' impliziert, dass dies ein optionales Feld ist). Eine Eigenschaft, die eine Liste ist, sagen 'String [] Nicknames' würde etwa so aussehen: ' '. Wie Sie sehen können, ist der einzige Unterschied von einem einfachen Feld zu einer Liste 'maxOccurs =' unbounded '. – acdcjunior

Antwort

4

Ich habe das gleiche Problem und löste es, indem ich mein eigenes WADL erzeugte.

Dazu geben Sie die folgenden Dateien in Ihrem Projekt

anwendungs ​​doc.xml für hohe WADL Übersicht hinzufügen müssen, kommentiert

anwendungs ​​Programmierern.XML, die den Speicherort Ihres Schemas definiert (mit Ihren Things und Thing-Elementen und komplexenTypen)

resourcedoc.xml, dies wird von einem Maven-Plugin generiert und es liest Ihre Jersey-Klassen, die Ihr Antwortelement Javadoc-Annotationen enthält.

fügen Sie einfach diese HrWadlGeneratorConfig Klasse zu Ihrem Projekt und diese

<init-param> 
     <param-name>com.sun.jersey.config.property.WadlGeneratorConfig</param-name> 
     <param-value>nl.amis.hr.wadl.HrWadlGeneratorConfig</param-value> 
    </init-param> 

Klasse

package nl.amis.hr.wadl;                       

import com.sun.jersey.api.wadl.config.WadlGeneratorConfig;              
import com.sun.jersey.api.wadl.config.WadlGeneratorDescription;             
import com.sun.jersey.server.wadl.generators.WadlGeneratorApplicationDoc;          
import com.sun.jersey.server.wadl.generators.WadlGeneratorGrammarsSupport;          
import com.sun.jersey.server.wadl.generators.resourcedoc.WadlGeneratorResourceDocSupport;      
import com.sun.research.ws.wadl.Grammars;                  
import com.sun.research.ws.wadl.Include;                   
import com.sun.research.ws.wadl.ObjectFactory;                 

import java.util.List;                       

public class HrWadlGeneratorConfig extends WadlGeneratorConfig {             

    @Override                         
    public List<WadlGeneratorDescription> configure() {               
     ObjectFactory obj = new ObjectFactory() ;                
     Grammars gram = obj.createGrammars();                 
     Include e = obj.createInclude();                   
     e.setHref("schema.xsd");                     
     gram.getInclude().add(e);                    

     WadlGeneratorConfigDescriptionBuilder builder = generator(WadlGeneratorApplicationDoc.class)    
     .prop("applicationDocsStream", "application-doc.xml")             
     .generator(WadlGeneratorGrammarsSupport.class)               
     .prop("grammarsStream", "application-grammars.xml")             
     .generator(WadlGeneratorResourceDocSupport.class)              
     .prop("resourceDocStream", "resourcedoc.xml");               

     return builder.descriptions();                   

    }                           

}                            

Hier ist ein Ausschnitt der Jersey-Klasse und die @response zum Trikot-Servlet als init param hinzuzufügen. representation.200.qname verweist auf das Element in Ihrem eigenen Schema.

/** 
    * Returns the item if existing. 
    * 
    * @response.representation.200.qname employees 
    * @response.representation.200.mediaType application/xml,application/json 
    * @response.representation.200.doc This is the representation returned by default 
    * @response.representation.200.example {@link EmployeeExample#SAMPLE_ITEM} 
    * 
    * 
    * @return the requested item if this service is available 
    */ 
    @GET 
    public List<Employee> getEmployees() { 
    return hrBean.getEmployeesFindAll(); 
    } 

und der maven pom, der die resourcedoc.xml erzeugt, die wir vom WADL-Generator verwenden.

<pluginManagement> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-javadoc-plugin</artifactId> 
       <version>2.4</version> 
      </plugin> 
     </plugins> 
    </pluginManagement>                             

     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-javadoc-plugin</artifactId> 
      <executions> 
       <execution> 
        <goals> 
         <goal>javadoc</goal> 
        </goals> 
        <phase>compile</phase> 
       </execution> 
      </executions> 
      <configuration> 
       <encoding>UTF-8</encoding> 
       <verbose>false</verbose> 
       <show>public</show> 
       <subpackages>nl.amis.hr.restful</subpackages> 
       <doclet>com.sun.jersey.wadl.resourcedoc.ResourceDoclet</doclet> 
        <docletPath>${path.separator}${project.build.outputDirectory}</docletPath> 
        <docletArtifacts> 
        <docletArtifact> 
          <groupId>nl.amis.hr</groupId> 
          <artifactId>Model</artifactId> 
          <version>1.0-SNAPSHOT</version> 
        </docletArtifact> 
        <docletArtifact> 
         <groupId>com.sun.jersey.contribs</groupId> 
         <artifactId>wadl-resourcedoc-doclet</artifactId> 
         <version>1.17.1</version> 
        </docletArtifact> 
        <docletArtifact> 
         <groupId>com.sun.jersey</groupId> 
         <artifactId>jersey-server</artifactId> 
         <version>1.17.1</version> 
        </docletArtifact> 
        <docletArtifact> 
         <groupId>xerces</groupId> 
         <artifactId>xercesImpl</artifactId> 
         <version>2.6.1</version> 
        </docletArtifact> 
       </docletArtifacts> 
       <!-- the following option is required as a work around for 
        version 2.5 of the javadoc plugin which will be used 
        by a maven version > 2.0.9 --> 
       <useStandardDocletOptions>false</useStandardDocletOptions> 
       <additionalparam>-output ${project.build.outputDirectory}/resourcedoc.xml</additionalparam> 
      </configuration> 
     </plugin> 

hier ist die vollständige Beispiel auf Github https://github.com/biemond/JDeveloper12c_12.1.2/tree/master/RestFulOWSM/WebService

Verwandte Themen