Zobrazují se příspěvky se štítkemJAX-RS. Zobrazit všechny příspěvky
Zobrazují se příspěvky se štítkemJAX-RS. Zobrazit všechny příspěvky

pondělí 3. března 2014

Ovlivnění generovaného WADL

Při buildování REST aplikací, s využitím implementace Jersey, se automaticky generuje i WADL. Tento je možné částečně doplňovat. Nyní ukáži postup přidávání dokumentačních elementů do generovaného WADL.

1) Vytvořím soubor application-doc.xml, tento soubor obsahuje stručný popis aplikace. Příklad:

 <applicationDocs targetNamespace="http://wadl.dev.java.net/2009/02">  
     <doc title="Post Code" xml:lang="en">Title and high level description</doc>  
 </applicationDocs>

2) Vytvořím soubor application-grammars.xml obsahující umístění vlastních XML schemat. Příklad:
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>  
 <grammars xmlns="http://wadl.dev.java.net/2009/02"   xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xi="http://www.w3.org/1999/XML/xinclude">  
   <include href="../xsd/schema.xsd" />  
 </grammars>  

3) Vytvořím potomka třídy WadlGeneratorConfig, v kterém budou uvedeny oba XML soubory vytvořené v předchozích krocích. Navíc je přidán soubor resourcedoc.xml, který bude vygenerován.

 package biz.prodejna.rest  
 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 java.util.List;  
 public class MyWadlGeneratorConfig extends WadlGeneratorConfig {  
   @Override  
   public List<WadlGeneratorDescription> configure() {  
     return generator( WadlGeneratorApplicationDoc.class )  
      .prop( "applicationDocsStream", "application-doc.xml" )  
      .generator( WadlGeneratorGrammarsSupport.class )  
      .prop( "grammarsStream", "application-grammars.xml" )  
      .generator( WadlGeneratorResourceDocSupport.class )  
      .prop( "resourceDocStream", "resourcedoc.xml" )  
      .descriptions();  
   }  
 }  

4) Třídu vytvořenou v předchozím kroku uvedu jako inicializační parametr JerseyServletu ve web.xml

 <servlet>  
     <servlet-name>JerseyServlet</servlet-name>  
     <servlet-class>  
       com.sun.jersey.spi.container.servlet.ServletContainer  
     </servlet-class>  
     <init-param>  
       <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>  
       <param-value>true</param-value>  
     </init-param>  
     <init-param>  
       <param-name>com.sun.jersey.config.property.WadlGeneratorConfig</param-name>  
       <param-value>biz.prodejna.rest.MyWadlGeneratorConfig</param-value>  
     </init-param>  
     <load-on-startup>1</load-on-startup>  
 </servlet>  

5) Aby byl vygenerován soubor resourcedoc.xml je třeba do pom.xml přidat maven javadoc plugin s docletem com.sun.jersey.wadl.resourcedoc.ResourceDoclet.

 <plugin>  
    <groupId>org.apache.maven.plugins</groupId>  
    <artifactId>maven-javadoc-plugin</artifactId>  
    <version>2.9.1</version>  
    <executions>  
        <execution>  
            <goals>  
                <goal>javadoc</goal>  
            </goals>  
            <phase>compile</phase>  
        </execution>  
    </executions>  
    <configuration>  
        <encoding>UTF-8</encoding>  
        <verbose>false</verbose>  
        <show>public</show>  
        <subpackages>biz.prodejna.rest</subpackages>  
        <doclet>com.sun.jersey.wadl.resourcedoc.ResourceDoclet</doclet>  
        <docletPath>${path.separator}${project.build.outputDirectory}</docletPath>  
        <docletArtifacts>  
            <docletArtifact>  
            <groupId>com.sun.jersey.contribs</groupId>  
            <artifactId>wadl-resourcedoc-doclet</artifactId>  
            <version>${jersey-release-version}</version>  
        </docletArtifact>  
        <docletArtifact>  
            <groupId>com.sun.jersey</groupId>  
            <artifactId>jersey-server</artifactId>  
            <version>${jersey-release-version}</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>  

6) Aby se generovaly doc elementy i k jednotlivým parametrům je do pom.xml třeba přidat závislost

 <dependency>  
   <groupId>javax.ws.rs</groupId>  
   <artifactId>javax.ws.rs-api</artifactId>  
   <version>2.0</version>  
 </dependency>  

Nyní by celé řešení mělo být funkční. Pokud přijdete na to jak v elementech parametrů generovat atribut required můžete mi o tom dát vědět do diskuze níže. Nebo máte jiný způsob jak co nepřesněji definovat REST API? I o tom se rád dočtu.

čtvrtek 31. května 2012

RESTful webová služba 1. díl

  1. Nainstaluji si server glassfish. Ten je možné zdarma získat např. zde. Stačit vám bude ale i Tomcat nebo jiný servletový kontejner.
  2. Vytvořím si v Netbeans novou webovou aplikaci:
  3. V tomto okně je třeba dát Add a následně vybrat nainstalovaný servletový kontejner.
  4. Nyní je třeba nakonfigurovat aplikaci. To je možné dvěma způsoby:

    1.  Prostřednictvím souboru web.xml
    2.  <?xml version="1.0" encoding="UTF-8"?>  
       <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">  
         <servlet>  
           <servlet-name>JerseyServlet</servlet-name>  
           <servlet-class>  
             com.sun.jersey.spi.container.servlet.ServletContainer  
           </servlet-class>  
           <load-on-startup>1</load-on-startup>  
         </servlet>  
         <servlet-mapping>  
           <servlet-name>JerseyServlet</servlet-name>  
           <url-pattern>/resources/*</url-pattern>  
         </servlet-mapping>  
       </web-app>  
      

    3. Pomocí anotace @ApplicationPath
    4. 1:  package biz.prodejna.examples.rest;  
      2:    
      3:  import javax.ws.rs.ApplicationPath;  
      4:  import javax.ws.rs.core.Application;  
      5:    
      6:  @ApplicationPath("resources")  
      7:  public class JaxRsConfig extends Application {  
      8:  }  
      

  5. A nyní konečně mohu napsat nějakou svoji třídu.
  6. RESTful webovou službu mohu volat jako bezparametrickou nebo s parametry. V druhém případě mám v podstatě 3 možnosti, jak parametry vkládat:
    • Jako součást URL. Příklad: http://localhost:8080/example-rest/resources/names/jmeno/prijmeni
    • Jako parametry metody GET. Příklad: http://localhost:8080/example-rest/resources/names?jmeno=Adam&prijmeni=Oliva
    • V těle HTTP requestu. Zde mohou být parametry naformátovány v libovolném MIME typu.

    V tomto bodě ukáži pouze první případ. Další případy si nechám do některého z dalších dílů.

    1:  package biz.prodejna.examples.rest;  
    2:    
    3:  import javax.ws.rs.GET;  
    4:  import javax.ws.rs.Path;  
    5:  import javax.ws.rs.PathParam;  
    6:  import javax.ws.rs.Produces;  
    7:    
    8:  @Path("names")  
    9:  public class Names {  
    10:    
    11:    @GET  
    12:    @Path("{first}/{last}")  
    13:    @Produces("text/plain")  
    14:    public String getFullName(  
    15:        @PathParam("first") String firstName, @PathParam("last") String lastName) {  
    16:      return firstName + " " + lastName;  
    17:    }  
    18:  }  
    

    Vysvětlím jednotlivé anotace:
    @Path u třídy udává, pod jakou URL bude služba dostupná.
    @GET definuje, jaká bude použita HTTP metoda.
    @Path u metody definuje, jaké bude pořadí parametrů. Nebo přesněji: jaký tvar bude mít zbytek URL.
    @Produces udává MIME typ v těle HTTP odpovědi.
    @PathParam mapuje parametry metody na části v anotaci @Path

  7. Nyní je už možné aplikaci deployovat na server a zkusit ji zavolat např. z webového prohlížeče: http://localhost:8080/example-rest/resources/names/Adam/Oliva

  8. Proč URL vypadá právě takhle? Vysvětlím:
    example-rest -název aplikace
    resources -definováno ve web.xml nebo anotací @ApplicationPath
    names -definováno anotací třídy @Path
Pokud máte zájem o pokračování tohoto blogu, informujte mě o tom. Co lze očekávat příště:
  • služba vracející odpověď jako xml
  • služba očekávající parametry jako parametry URL
  • tvorba klienta s využitím implementace Jersey.
  • služba očekávající na vstupu XML dokument.