====== JAXB / JAX-WS / JAX-RS ======
* [[stackoverflow>76595|SOAP or REST for Web Services?]]
* [[stackoverflow>2185640|Jersey v.s. Spring 3.0]]
* [[http://redrata.com/restful-uri-design/|REST-ful URI design]]
* [[http://www.oracle.com/technetwork/articles/javase/index-137171.html|RESTful Web Services]]
* [[web_service|Creating a SOAP Web Service using Java 6]]
===== Questions answered =====
==== JAX-RS ====
* [[http://docs.jboss.org/seam/3/rest/latest/reference/en-US/html/rest.validation.html|RestEasy bean validation]]
=== How to implement dynamic content negotiation? ===
From [[javaee>tutorial/doc/gkqbq.html|Runtime content negotiation]]:
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.Variant;
import org.springframework.stereotype.Controller;
@Controller
public class Controller {
private static final List SUPPORTED_MEDIA_TYPES = Variant
.mediaTypes(MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_JSON_TYPE, MediaType.TEXT_PLAIN_TYPE)
.build();
@GET
@Path("/process")
public Response process(@Context Request request) {
Variant variant = request.selectVariant(SUPPORTED_MEDIA_TYPES);
if (variant == null) {
return Response.notAcceptable(SUPPORTED_MEDIA_TYPES).build();
}
Object bean = ...; // some POJO, e.g. JAXB-annotated
// XML or JSON are marshalled by the container, but plain text is evaluated somehow differently:
return Response.ok(variant.getMediaType() == MediaType.TEXT_PLAIN_TYPE ? bean.toString() : bean, variant.getMediaType().withCharset("UTF-8")).
build();
}
}
==== JAX-WS ====
=== The sources are generated OK, but I get the compilation problem. ===
The error reported might look like:
DocumentInquiryService.java:[68,20] cannot find symbol
symbol : method getPort(javax.xml.namespace.QName,java.lang.Class,javax.xml.ws.WebServiceFeature[])
location: class javax.xml.ws.Service
JAX-WS v2.1 refers some new classes and annotations, which are not part of JDK prior to v1.6.0_04. You need to put ''jaxb-api.jar'' and ''jaxws-api-2.1.jar'' to ''$JAVA_HOME/lib/endorsed'' (e.g. for Windows it might be ''C:\Program Files\JAVA\jdk1.6.0_03\jre\lib\endorsed\''). Make sure maven is using this very Java installation.
=== What JDK versions include what JAX-WS API version? ===
* JDK 1.6.0 includes JAX-WS 2.0 API.
* JDK 1.6.0_04 includes JAXB and JAX-WS 2.1 API. It is back-compatible with JAX-WS 2.0. You can use v2.1.x XJC generator and with minor efforts port it to JAXB 2.0 API (''@XmlElementRef'' was added an extra attribute, ''javax.xml.ws.Service'' implementations have more extended interface, ...).
* JDK 1.6.0_14 includes JAXB 2.1.10 and JAX-WS 2.1.6 runtime.
* JDK 7 includes JAXP 1.4.5, JAXB 2.2.4, JAX-WS 2.2.4.
* JDK 8 includes JAXB 2.2.8.
More information:
* [[https://jaxb.dev.java.net/nonav/2.2/docs/changelog2.html|JAXB 2.0 Changelog]]
* [[https://jaxb.dev.java.net/guide/Migrating_JAXB_2_0_applications_to_JavaSE_6.html#Using_JAXB_2_1_or_JAXB_2_2_with_JavaSE_6|Migrating JAXB 2.0 applications to JavaSE 6]]
=== [[http://java.net/projects/saaj|Sun SAAJ implementation]] is not compatible with IBM JDK ===
It is known problem, as Sun SAAJ implementation depends on reallocated Xerces classes. See [[javanettracker>SAAJ-7|Ref Impl does not work with IBM JDK]], [[apachetracker>AXIS2-4228|SAAJ test cases no longer work with IBM's SDK]].
Alternative SOAP implementations are listed in [[stackoverflow>questions/9249072|Alternative to Sun SAAJ SOAP implementation]].
=== How to use catalogs with JAX-WS? ===
* [[http://metro.java.net/guide/Developing_client_application_with_locally_packaged_WSDL.html#Xml_Catalog|Developing client application with locally packaged WSDL]]
* [[http://nzpcmad.blogspot.com/2009/10/metro-jax-ws-catalogue.html|Metro: JAX-WS catalogue]]
* [[http://download.oracle.com/docs/cd/E15051_01/wls/docs103/webserv_adv/xml.html|Using XML Catalogs]]
* [[http://old.nabble.com/Resolve-the-schema-location-from-the-classpath--td7372851.html|Resolve the schema location from the classpath for maven-jaxb2-plugin]]
=== When I use ''wsimport'' I got the error message //"src-resolve: Cannot resolve the name 'soapenc:Array' to a(n) 'type definition' component".// ===
JAX-WS doesn't support soap-encoded WSDL (see [[stackoverflow>2455218|Cannot resolve the name 'soapenc:Array']] and [[http://java.net/projects/jax-ws/lists/users/archive/2007-07/message/11|JAX-WS client generation fails for Amazon WSDL]]).
=== Why JAX-WS generates ''faultInfo''? ===
From [[http://www.ibm.com/developerworks/webservices/library/ws-jaxws-faults/index.html#listing4|Faults and exceptions in JAX-WS]]:
JAX-WS generator generates the exception, and the JAXB generator generates the Java bean containing the exception's data.
=== How to use proxy with ''jaxws-maven-plugin''? ===
Due to [[jaxwsctracker>57|issue#57]] ''httpproxy'' configuration option is not correctly passed to ''wsimport''. Workarounds are:
* To use ''args'' configuration option to pass the setting correctly:
...
-httpproxy:proxy:8080
* To define JVM-wide proxy at maven execution or define system property ''%%MAVEN_OPTS="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"%%''
=== How to define connection and request timeouts for the client? ===
In fact, the proxy returned by any ''getPort()'' function is an instance of ''com.sun.xml.ws.client.sei.SEIStub'' and implements ''javax.xml.ws.BindingProvider'':
import javax.xml.ws.BindingProvider;
import com.sun.xml.ws.developer.JAXWSProperties;
// 3 seconds (in milliseconds) to open a connection:
private static final Integer CONNECT_TIMEOUT = Integer.valueOf(3000);
// 10 seconds (in milliseconds) to retrieve the data from connection:
private static final Integer REQUEST_TIMEOUT = Integer.valueOf(10000);
...
MyPortType myPort = new MyService().getMyPort();
Map context = ((BindingProvider) myPort).getResponseContext();
context.put(JAXWSProperties.CONNECT_TIMEOUT, CONNECT_TIMEOUT);
context.put(JAXWSProperties.REQUEST_TIMEOUT, REQUEST_TIMEOUT);
----
=== How to get attachments for the received response? ===
In fact, the proxy returned by any ''getPort()'' function is an instance of ''com.sun.xml.ws.client.sei.SEIStub'' and implements ''javax.xml.ws.BindingProvider'':
import javax.activation.DataHandler;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;
MyPortType myPort = new MyService().getMyPort();
Map attachments = (Map) ((BindingProvider) myPort).getResponseContext().get(MessageContext.INBOUND_MESSAGE_ATTACHMENTS);
DataHandler dataHandler = attachments.values().iterator().next();
... = dataHandler.getInputStream();
=== How to deal with large MIME attachments in SOAP messages? ===
Starting from SAAJ RI 1.3.4 it is possible to enable [[http://mimepull.dev.java.net/|MimePull]] parser via ''%%System.setProperty("saaj.use.mimepull", "true")%%''. See [[http://weblogs.java.net/blog/kumarjayanti/archive/2009/12/10/summary-proprietary-features-saaj-ri-134|Creating SOAPMessages with Very Large XML Payload]] and [[javanettracker>SAAJ-31#action_38639|SAAJ-31]].
=== How can I see the SOAP messages send between client and server? Is there any way to dump them? ===
For client part enable system property ''-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true'', for server part ''-Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true''
=== How can I intersect SOAP messages send between client and server and pipe them to another client? ===
Check [[stackoverflow>9121129|Is it possible to use jax-ws to generate xml, but not send it out]].
=== Are JAX-WS client proxies thread safe? ===
[[http://cxf.apache.org/faq.html#FAQ-AreJAXWSclientproxiesthreadsafe%3F|Generally not]] (check [[http://jaxb.java.net/faq/index.html#threadSafety|here]] as well). Pooling client proxies is far from perfect workaround, as [[javanettracker>JAX_WS-942|JAX-WS runtime model is not shared among client proxies]] (which means you will loose memory not even per WSDL, but per WS operation).
=== How can I test the newly developed WebService? ===
* You can use Spring [[http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/remoting.html#remoting-web-services-jaxws-export-standalone|SimpleJaxWsServiceExporter]] helper bean to export your WebService endpoints for example:
Internally above approach uses [[http://download.oracle.com/javase/6/docs/jre/api/net/httpserver/spec/com/sun/net/httpserver/HttpServer.html|build-in HttpServer]]. You can benefit from it, if you have developed you WebServers using e.g. Axis.
[[https://jira.springframework.org/browse/SPR-7412|Starting from Spring 3.0.4]], the default values are inherited from ''@WebService'' annotation on ''MyProviderAPI'' interface. But due to [[jaxwstracker>890]], the annotation meta-information should be manually enhanced to make everything working.
* You can use [[software:tomcat#quick_deployment_of_web_application|Jetty]] to deploy the backed WAR file + Spring for the client.
==== JAXB ====
=== What is "//XPath evaluation of ... results in empty target node//"? ===
This happens when XPath expression in your customization has not matched any node (the expression is incorrect or you are trying to match in the wrong schema file) ([[https://jaxb.dev.java.net/guide/Dealing_with_errors.html#XPath_evaluation_of_____results_in_empty_target_node|see here]] some more information)
=== How to customize package names / class prefix or suffix? ===
You can define the package name per XSD (e.g. per namespace). From [[stackoverflow>6214576]]:
=== How to refer the XSD from JAR in JAXB customization? ===
Suppose the schema is taken from JAR dependency as shown in this example:
org.jvnet.jaxb2.maven2
maven-jaxb2-plugin
0.8.1
...
com.test
schemas
1.10-SNAPSHOT
schemas/schema.xsd
...
How to refer a specific schema from customization file?
From [[stackoverflowa>9524520/267197|JAXB Bindings to schemas in a JAR]] and [[http://jaxb.java.net/guide/Using_SCD_for_customizations.html|Using SCD for customizations]] the solution is to use SCD to point the schema by target namespace:
=== How to automatically make collection properties plural (e.g. ''country'' -> ''countries'')? ===
Have a look at [[http://jaxb.java.net/nonav/jaxb20-fcs/docs/vendorCustomizations.html#simple|simple binding mode]]:
=== How to define custom interface / class that specific JAXB bean should implement / extend? ===
Check [[http://confluence.highsource.org/display/J2B/Inheritance+plugin|Inheritance plugin]].
=== Where can I find the DTD/XSD describing JAXB customizations file? ===
Check this: ''[[http://mirrors.ibiblio.org/pub/mirrors/maven2/com/sun/xml/bind/jaxb-xjc/2.1.7/jaxb-xjc-2.1.7.jar|jaxb-xjc.jar]]/com\sun\tools\xjc\reader\xmlschema\bindinfo\binding.xsd''
----
=== How to unmarshal part of XML? ===
From [[stackoverflowa>8526353/267197|Suppress outer tag for nested objects]]: Use ''StreamFilter'' to suppress XML nodes which should not be fed to JAXB .
From [[stackoverflowa>9260039/267197|Can JAXB parse large XML files in chunks]]: Use custom ''XMLStreamReader'' or some logic around it to skip uninteresting elements.
=== How to marshal JAXB fragment without default namespaces generated for each fragment? ===
From [[stackoverflowa>9314867/267197|JAXB fragment marshal w/o namespace]]: Use ''XMLStreamWriter'' or NS-aware DOM.
=== How to create immutable objects? ===
From [[http://blog.bdoughan.com/2010/12/jaxb-and-immutable-objects.html|JAXB and Immutable Objects]]: Use ''XmlAdapter''.
=== How to make the property unmarshalled, but ignored during the marshalling? ===
From [[stackoverflowa>10211564/267197|Annotation @XmlElement write only]]:
Mark your property using ''@XmlReadOnly''.
=== How to tell JAXB to ignore the properties from the parent class? ===
There are two solutions for this (from [[stackoverflow>9285370|here]]):
* Mark you parent class with ''@XmlTransient''. In this case all class properties will be populated to parent classes, but class itself will be excluded from domain model (so you cannot marshall/unmarshall it).
* Mark you parent class with ''@XmlAccessorType(XmlAccessType.NONE)''. You will have to duplicate both property setters and getters in your child class:
public String getComment() {
return super.getComment();
}
public void setComment(String comment) {
super.setComment(comment);
}
or one can create ''package-info.java'' with the following content:
@XmlAccessorType(XmlAccessType.NONE)
package test.sub;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
=== How to split JAXB model compilation into several parts? ===
In JAXB these parts are called episodes. See:
* [[github>highsource/maven-jaxb2-plugin/wiki/Modular-Schema-Compilation|Modular Schema Compilation]]
* [[http://confluence.highsource.org/display/MJIIP/User+Guide#UserGuide-Separateschemacompilation|Separate schema compilation]]
* [[https://community.oracle.com/blogs/kohsuke/2006/09/05/separate-compilation-jaxb-ri-21|Separate compilation]]
=== How to workaround ''com.sun.istack.SAXException2: unable to marshal type "..." as an element because it is missing an @XmlRootElement annotation'' problem? ===
This happens when the given object represents XSD type (not a concrete element). As in [[stackoverflowa>4147079/267197|this example]] you need to wrap the given object into ''JAXBElement''. ''ObjectFactory'' should have at least one factory method to do so.
{{tag>JAXB JAX-WS JAX-RS REST Jersey Spring}}