RESTEasy WADL Grammar Support
By Weinan Li | October 31, 2018
RESTEasy has added WADL grammar support by this PR:
The major change is that ResteasyWadlGrammar
is added into ResteasyWadlWriter
:
In addition, the ResteasyWadlWriter
is rewritten now, and all the static methods are now instance methods. It means users need to create an instance of ResteasyWadlWriter
and put it into per-deployment scope.
To avoid people to write the boilerplate code, the ResteasyWadlDefaultResource
can be used for deployment, and it can be put into the getSingleton()
method of Application
class:
@Provider
@ApplicationPath("/")
public class WadlTestApplication extends Application {
public static Set<Class<?>> classes = new HashSet<Class<?>>();
public static Set<Object> singletons = new HashSet<Object>();
...
@Override
public Set<Object> getSingletons() {
...
ResteasyWadlDefaultResource defaultResource = new ResteasyWadlDefaultResource();
singletons.add(defaultResource);
}
return singletons;
}
}
And then the URL /application.xml
is enabled by the methods inside ResteasyWadlDefaultResource
.
To enable the WADL Grammar support, users need to create an instance of ResteasyWadlGrammar
and put it into the instance of ResteasyWadlWriter
.
The recommended way is to use it with ResteasyWadlDefaultResource
. Here is an example:
ResteasyWadlDefaultResource defaultResource = new ResteasyWadlDefaultResource();
ResteasyWadlWriter.ResteasyWadlGrammar wadlGrammar = new ResteasyWadlWriter.ResteasyWadlGrammar();
wadlGrammar.enableSchemaGeneration();
defaultResource.getWadlWriter().setWadlGrammar(wadlGrammar);
As the code shown above, we have created an instance of ResteasyWadlGrammar
, and it’s injected into the ResteasyWadlWriter
instance included by ResteasyWadlDefaultResource
instance.
In addition, we have called the wadlGrammar.enableSchemaGeneration()
method, and it will scan the resources classes, and generate grammar files for JAXB annotated classes. Suppose we have entity class like this:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@XmlRootElement(name = "listType")
public class ListType {
private List <String> values;
@XmlElement
public List<String> getValues() {
return values;
}
public void setValues(List<String> values) {
this.values = values;
}
}
And it’s used in resource class:
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@Path("/extended")
public class ExtendedResource {
@POST
@Consumes({"application/xml"})
public String post(ListType income) {
return "foo";
}
}
And if we enable the grammar generation as shown above, then we will get sample output from /application.xml
like this:
$ http http://localhost:8081/application.xml
HTTP/1.1 200 OK
Content-type: application/xml;charset=UTF-8
Date: Wed, 31 Oct 2018 07:57:38 GMT
Transfer-encoding: chunked
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="
[http://wadl.dev.java.net/2009/02](http://wadl.dev.java.net/2009/02)
">
<grammars>
<include href="xsd0.xsd">
<doc title="Generated" xml:lang="en"/>
</include>
</grammars>
…
</application>
The above output shows that a grammar file is genrated, and it is called xsd0.xsd
. The instance of ResteasyWadlDefaultResource
will prepare a URL link named /wadl-extended
, and it will serve the generated grammar file. Here is the example:
$ http http://localhost:8081/wadl-extended/xsd0.xsd
HTTP/1.1 200 OK
Content-type: application/xml;charset=UTF-8
Date: Wed, 31 Oct 2018 07:58:53 GMT
Transfer-encoding: chunked
<?xml version="1.0" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="listType" type="listType"/>
<xs:complexType name="listType">
<xs:sequence>
<xs:element name="values" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
As shown in the above example, the grammar is generated for ListType
entity class. If you don’t want RESTEasy to generate the grammar file for you, you can use the includeGrammars()
method provided by the instance of ResteasyWadlGrammar
. Here is an example:
ResteasyWadlWriter.ResteasyWadlGrammar wadlGrammar = new ResteasyWadlWriter.ResteasyWadlGrammar();
wadlGrammar.includeGrammars(“application-grammars.xml”);
...
The application-grammars.xml
file is grammar descriptor file provided by yourself, and it should be put into your project’s classpath. Here is a sample of application-grammars.xml
:
<?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="schema.xsd" />
</grammars>
From above file we can see schema.xsd
is the included schema file, and it should also be provided by yourself. Here is a sample of schema.xsd
:
<?xml version=“1.0” encoding=“UTF-8” standalone=“yes”?>
<xs:schema version=“1.0” xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
<xs:element name=“listType” type=“listType”/>
<xs:complexType name=“listType”>
<xs:sequence>
<xs:element name=“values” type=“xs:string” minOccurs=“0” maxOccurs=“unbounded”/>
</xs:sequence>
</xs:complexType>
</xs:schema>
And if you have called wadlGrammar.includeGrammars(“application-grammars.xml”)
, then you will get the included section in /application.xml
:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
<grammars>
<include href="schema.xsd"/>
</grammars>
...
</application>
As the example shown above, the schema.xsd
is included, and it can be fetched by using /wadl-extended/schema.xsd
if you have registered the instance of ResteasyWadlDefaultResource
into your Application
and setup ResteasyWadlGrammar
properly:
$ http http://localhost:8081/wadl-extended/schema.xsd
HTTP/1.1 200 OK
Content-type: application/xml;charset=UTF-8
Date: Wed, 31 Oct 2018 08:12:56 GMT
Transfer-encoding: chunked
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="listType" type="listType"/>
<xs:complexType name="listType">
<xs:sequence>
<xs:element name="values" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Above is the description about the RESTEasy WADL Grammar feature.
The other change is that ResteasyWadlServlet
and ResteasyWadlServletWriter
is now deprecated, because it doesn’t support the grammar feature, and these two classes will be removed from master branch in the future. Using ResteasyWadlDefaultResource
is recommended to enable the WADL feature.
Useful Links
YourKit supports open source projects with innovative and intelligent tools for monitoring and profiling Java and .NET applications. YourKit is the creator of YourKit Java Profiler, YourKit .NET Profiler, and YourKit YouMonitor