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<Variant> 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(); } }
DocumentInquiryService.java:[68,20] cannot find symbol symbol : method getPort(javax.xml.namespace.QName,java.lang.Class<DocumentInquiryPortType>,javax.xml.ws.WebServiceFeature[]) location: class javax.xml.ws.Service
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.
@XmlElementRef
was added an extra attribute, javax.xml.ws.Service
implementations have more extended interface, …).More information:
Alternative SOAP implementations are listed in Alternative to Sun SAAJ SOAP implementation.
wsimport
I got the error message “src-resolve: Cannot resolve the name 'soapenc:Array' to a(n) 'type definition' component”.
faultInfo
? JAX-WS generator generates the exception, and the JAXB generator generates the Java bean containing the exception's data.
jaxws-maven-plugin
? httpproxy
configuration option is not correctly passed to wsimport
. Workarounds are:args
configuration option to pass the setting correctly: <configuration> ... <args> <arg>-httpproxy:proxy:8080</arg> </args> </configuration>
MAVEN_OPTS="-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080"
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<String, Object> context = ((BindingProvider) myPort).getResponseContext(); context.put(JAXWSProperties.CONNECT_TIMEOUT, CONNECT_TIMEOUT); context.put(JAXWSProperties.REQUEST_TIMEOUT, REQUEST_TIMEOUT);
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<String, DataHandler> attachments = (Map<String, DataHandler>) ((BindingProvider) myPort).getResponseContext().get(MessageContext.INBOUND_MESSAGE_ATTACHMENTS); DataHandler dataHandler = attachments.values().iterator().next(); ... = dataHandler.getInputStream();
System.setProperty("saaj.use.mimepull", "true")
. See Creating SOAPMessages with Very Large XML Payload and SAAJ-31.
-Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
, for server part -Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true
<?xml version="1.0"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- Instantiate the bean manually or you can use @Service annotation + <context:component-scan /> --> <bean name="providerWS" class="org.mycompany.ws.MyProviderImpl" /> <!-- This utility bean will scan all context beans for @WebService annotation and publish them on the given port: --> <bean class="org.springframework.remoting.jaxws.SimpleJaxWsServiceExporter"> <property name="baseAddress" value="http://localhost:8999/" /> </bean> <!-- The helper bean that is a factory of WS client instances that implement the given interface. Check WSDL file for concrete values for "serviceName" and "portName". --> <bean name="providerWSClient" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean"> <property name="serviceInterface" value="org.mycompany.ws.api.MyProviderAPI" /> <property name="wsdlDocumentUrl" value="http://localhost:8999/" /> <property name="namespaceUri" value="http://myservice.mycompany.org/" /> <property name="serviceName" value="MyProviderImplService" /> <property name="portName" value="MyProviderPort" /> </bean> </beans>
Internally above approach uses build-in HttpServer. You can benefit from it, if you have developed you WebServers using e.g. Axis.
@WebService
annotation on MyProviderAPI
interface. But due to 890, the annotation meta-information should be manually enhanced to make everything working.
<jaxb:bindings schemaLocation="../wsdl/address.xsd" node="//xsd:schema[@targetNamespace='http://mycompany.com/service']"> <jaxb:schemaBindings> <jaxb:package name="com.mycompany.project" /> <jaxb:nameXmlTransform> <jaxb:typeName prefix="Foo" suffix="Type" /> <jaxb:anonymousTypeName prefix="Foo" suffix="Type" /> <jaxb:elementName prefix="Foo" suffix="Element" /> </jaxb:nameXmlTransform> </jaxb:schemaBindings> </jaxb:bindings>
<plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <version>0.8.1</version> <executions>...</executions> <configuration> <schemas> <schema> <dependencyResource> <groupId>com.test</groupId> <artifactId>schemas</artifactId> <version>1.10-SNAPSHOT</version> <resource>schemas/schema.xsd</resource> </dependencyResource> </schema> </schemas> ... </configuration> </plugin>
How to refer a specific schema from customization file?
<jaxb:bindings scd="x-schema::tns" xmlns:tns="http://my.schema.target.namespace/"> <jaxb:schemaBindings> <jaxb:package name="org.jvnet.jaxb2.maven2.tests.po"/> </jaxb:schemaBindings> </jaxb:bindings>
country
→ countries
)? <jaxb:globalBindings> <xjc:simple /> </jaxb:globalBindings>
jaxb-xjc.jar/com\sun\tools\xjc\reader\xmlschema\bindinfo\binding.xsd
StreamFilter
to suppress XML nodes which should not be fed to JAXB .
From Can JAXB parse large XML files in chunks: Use custom XMLStreamReader
or some logic around it to skip uninteresting elements.
XMLStreamWriter
or NS-aware DOM.
XmlAdapter<AdaptedCustomer, Customer>
.
Mark your property using @XmlReadOnly
.
@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).@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;
com.sun.istack.SAXException2: unable to marshal type “…” as an element because it is missing an @XmlRootElement annotation
problem? JAXBElement
. ObjectFactory
should have at least one factory method to do so.