====== 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: * [[https://github.com/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}}