I have been working on a REST web service using Jersey for a few days now, and managed to have all CRUD operations working, with several exchange formats: XML, JSON, Google Protobuf.
However I am facing some issues related to automatically generated WADL and XSD.
Context
To define the objects exchanged in these three formats, I have followed a "contract-first" approach:
from a XSD I wrote, I generated my model classes using JAXB;
from an equivalent proto file I wrote, I generated the Google Protobuf classes (and internally have a way to convert these to the JAXB-generated objects, in order to have one unique model).
However, as I would like my users to be able to generate their classes too, I would like to share these schema files (.xsd and .proto) and have them well integrated with the automatically generated WADL.
For that purpose, thanks to this wiki page:
I have exposed the two files under
/schema/schema.xsd
/schema/schema.proto
I have added an application-grammar file:
<?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/schema.xsd" />
</grammars>
I have added a customized WADL generator:
public class RichWadlGeneratorConfig extends WadlGeneratorConfig {
#Override
public List<WadlGeneratorDescription> configure() {
return generator(WadlGeneratorApplicationDoc.class)
.prop("applicationDocsStream", "application-doc.xml")
.generator(WadlGeneratorGrammarsSupport.class)
.prop("grammarsStream", "application-grammars.xml")
.descriptions();
}
}
This way the below appears in the WADL, when I hit /rest/application.wadl:
<grammars>
<include href="../schema/schema.xsd"/>
<include href="application.wadl/xsd0.xsd">
<doc title="Generated" xml:lang="en"/>
</include>
</grammars>
Problem
/rest/application.wadl/xsd0.xsd is automatically generated from my classes, but is quite different from what I initially had in schema.xsd.
In addition to that, calling a tool like wadl2java on this WADL fails miserably, presumably because
/schema/schema.xsd, and
/rest/application.wadl/xsd0.xsd
are now conflicting (two definitions for the same objects).
Questions
Is there a way to disable the generation and diffusion of this automatically generated XSD?
(As I don't need it since I'm following this "contract-first" approach)
If not, is there a way to "override" its content with my manually written XSD when /rest/application.wadl/xsd0.xsd is hit?
(I have googled around and found about WadlResource, to generate customized WADL, but found nothing about the XSD generation itself)
Thanks in advance for your help!
M.
Edit
1) I raised the issue to the Jersey team and got a reply:
http://java.net/projects/jersey/lists/users/archive/2012-06/message/8
2) I raised a ticket (JERSEY-1230), according to Pavel's instructions.
I am currently following up to either submit a fix myself or get a fix from the Jersey team.
1.14-SNAPSHOT should allow you to do this:
public class SampleWadlGeneratorConfig extends WadlGeneratorConfig {
#Override
public List<WadlGeneratorDescription> configure() {
return generator( WadlGeneratorApplicationDoc.class )
.prop( "applicationDocsStream", "application-doc.xml" )
.generator( WadlGeneratorGrammarsSupport.class )
.prop( "grammarsStream", "application-grammars.xml" )
.prop("overrideGrammars", true) // !!!
.generator( WadlGeneratorResourceDocSupport.class )
.prop( "resourceDocStream", "resourcedoc.xml" )
.descriptions();
}
}
when overrideGrammars is set to true, Jersey generated grammars won't be included in returned WADL.
Related
I have created a new method
#WebMethod(operationName = "getTot")
public String getTot
when i do
https://host/webserviceMachin/toto?wsdl
it succeeded because i can read in this file
message name="getTot" ...
but i don't know how the former computer programming have succeeded to add xsd :
xsd:import namespace="http://machinn/Wrappers
schemaLocation="https://host:443/webserviceMachin/toto?xsd=1
in the https://host/webserviceMachin/toto?wsdl
I don't how glassfish recognize "xsd" or annotation xsd, there is no file (physical) xsd. There is a toto.wsdl but it is not used by glassfish, i changed it and the https://host:443/webserviceMachin/toto.wsdl don't change, it is somewhere in the code, i have searched for annotation,
Do you have some idea...?
In most of my previous projects I have two domain models, one with JAXB annotations and the other one with JPA annotations. I know they can combined into one model with both annotations in the same class, but in my experiences the tradeoffs with this approach always came to the conclusion to separate them. Another advantage of a separate approach is the ability to create the JAXB classes with a XSD and easily link in XSDs from other projects.
In most cases I need factory classes being able for flexible creation of JAXB representations of my entities, e.g.
public class UserFactory
{
public UserFactory(User queryUser, String lang)
{
this.queryUser=queryUser;
this.lang=lang;
}
public JaxbUser getUser(JpaUser jpaUser)
{
JaxbUser jaxbUser = new JaxbUser();
if(queryUser.isSetId()){jaxbUser.setId(jpaUser.getId());}
if(queryUser.isSetEmail()){jaxbUser.setEmail(jpaUser.getEmail());}
if(queryUser.isSetRoles())
{
RolesFactory f = new RolesFactory(queryUser.getRoles(),lang);
jaxbUser.setRoles(f.getRoles(jpaUser.getRoles()));
}
return jaxbUser;
}
}
I create a UserFactory with an individual template queryUser and the desired lang for entities supporting different languages. The template is checked during creation of the result for specific fields or additional factories and the resulting object is created. The query is defined in a XML file like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<query lang="en">
<user id="1">
<roles>
<role code="code"/>
</roles>
</user>
</query>
With this methodology I have a powerful and flexible tool to create customized XML, despite all drawback of maintaining two domain models and the factory classes. I know there are many frameworks or libraries available which I never have heard about, so here my question:
Is there something available similar to my approach?
There are basically two options:
JPA and JAXB annotations on the same classes (see Hyperjaxb3 or DataNucleus)
Or you keepm the separated and write code to map one onto another
I personally do not see much added value in the cross-model mapping code. Usage of factories also does not seem too innovative, it is just a question of programming technique which you use to map one onto another.
I'm using Enunciate to generate a SOAP endpoint for a Wicket web application I am working on and I have a couple of questions that I haven't figured out the solution to yet.
1 How do I change the name of the xsd files? I've looked through the FAQ and it tells me to do something similar to this:
<xml>
<schema namespace="http://api.example.com/data" file="data.xsd"/>
</xml>
However, I haven't quite figured out how to set the targetNamespace for my data objects. I've done this for my service via #WebService ( targetNamespace="blah" ), but how do I annotate my data objects to let Enunciate know which namespace they should belong to?
2 Enunciate generates my XSDs just fine, but I don't particularily like the element names it uses. I have a ServiceRequest and ServiceResponse object. The ServiceRequest object has a List of User objects. The ServiceResponse has a list of Group objects. Enunciate suggests that every "User" object within the ServiceRequest should be using the tag "<users>". I feel that it would make more sense to use the singular form, "<user>" since the tag does in fact only contain a single user. Is it possible to change this behaviour, and if so, how?
Thanks in advance.
So just to be clear, with the exception of the question about naming your schema files, your questions are really more about JAXB than they are about Enunciate. JAXB is the spec that defines how your Java objects are (de)serialized to/from XML and Enunciate conforms to that spec.
Anyway, the easiest way to apply a namespace to your Java objects is with a package-info.java file in the package of your Java classes. Annotate your package with #XmlSchema and set the namespace to be the value you want.
Customizing how your accessors are serialized to/from XML can be done with the #XmlElement annotation, e.g.:
public class MyClass {
...
#XmlElement (name="user")
List<User> users;
...
}
Here are the JAXB javadocs
https://jaxb.dev.java.net/nonav/2.1.9/docs/api/
Or google for a good JAXB tutorial.
Guys I'm new to xml in Java.
I have the following task. I need to parse some xml files (specificallyh xcb-proto [X11]) to generate the equivalent request protocol in java. There is already a well defined xsd and the respective xml for the protocol. What is the best and easiest approach/parser to solve this?
Example of existant xml content:
<request name="SetScreenSaver" opcode="107">
<pad bytes="1" />
<field type="INT16" name="timeout" />
<field type="INT16" name="interval" />
<field type="CARD8" name="prefer_blanking" enum="Blanking" />
<field type="CARD8" name="allow_exposures" enum="Exposures" />
</request>
This will generate a Java DOM (?) Object. And them with this I need to generate the given code in Java. For this case is:
Desired output:
public void setScreenSaver(int timeout, int interval, int preferBlanking, int allowExposures) {
RequestOutputStream o = outputStream;
synchronized (o) {
o.beginRequest(107, 0, 1); // Major Opcode , Minor Opcode, ReqLength
o.writeInt16(timeout);
o.writeInt16(interval);
o.writeInt8(preferBlanking);
o.writeInt8(allowExposures);
o.send();
}
}
It seems that XSOM is the one that gives the easier approach...
PS: I have never manipulated xml files in Java :3
You should look into JAXB. It comes with a utility that will generate all your Java code using the .XSD file to determine the structure.
Even with an XSD parser, this is never going to be an easy task, especially if the schema uses some of the more difficult aspects of the XSD language.
If this is a once-off task and the XSDs are not huge, then you are probably better of just writing the Java code by hand.
EDIT
I can think of one roundabout approach using Eclipse / EMF that might simplify things:
Use the EMF tooling to create a EMF ECore model from the XSD. This gives you an in-memory "object model" analogous to simple UML.
Using EMF infrastructure (e.g. JET), create a custom generator that traverses the ECore model and generates your target code.
The XSD to ECore also gives you (for free) generated classes for representing your XML in memory, editing it in a tree editor and reading/writing the XML. Associated technologies deal with persistence in a database, validation, model-to-model transformation, and other things.
I need to decide which configuration framework to use. At the moment I am thinking between using properties files and XML files. My configuration needs to have some primitive grouping, e.g. in XML format would be something like:
<configuration>
<group name="abc">
<param1>value1</param1>
<param2>value2</param2>
</group>
<group name="def">
<param3>value3</param3>
<param4>value4</param4>
</group>
</configuration>
or a properties file (something similar to log4j.properties):
group.abc.param1 = value1
group.abc.param2 = value2
group.def.param3 = value3
group.def.param4 = value4
I need bi-directional (read and write) configuration library/framework. Nice feature would be - that I could read out somehow different configuration groups as different objects, so I could later pass them to different places, e.g. - reading everything what belongs to group "abc" as one object and "def" as another. If that is not possible I can always split single configuration object into smaller ones myself in the application initialization part of course.
Which framework would best fit for me?
Since you are saying that it is possible to also store objects in the config, I would suggest this:
http://commons.apache.org/configuration/
The simplest way to do this would be to use Simple XML. It can bind XML to Java POJOs in a very simple manner. Also, it is much faster than other such XML binding frameworks.
http://simple.sourceforge.net
Only 270K with no dependencies.
Please take a look at this URL: http://issues.apache.org/jira/browse/CONFIGURATION-394
The Configuration framework which we're looking for it is something on top of Apache Commons Configuration and must support Concurrency Issues, JMX issues and most of stores(e.g .properties file, .xml files or PreferencesAPI).
What weblogic team provides on 'Administration Console' is intersting which through it you can have transactional(atomic) updates on configurations so that are registered listeners be notified.
The Apache guys insist that this project is out of scopes of Commons Configuration, maybe!
I've attached a simple configuration framework, take look please