I have developed a Web Service using JAX-WS (v2.1.3 - Sun JDK 1.6.0_05) that works just fine when I use a Java client or SoapUI or other Web Services testing tools. I need to consume this service using 2005 Microsoft SQL Server Reporting Services and I get the following error
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Client</faultcode>
<faultstring>Couldn't create SOAP message due to exception: XML reader error: unexpected character content:
"?"
</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>
If I use a HTTP proxy to sniff out what SSRS is sending, I see EF BB BF as the beginning of the post body and JAX-WS doesn't like that. If I remove the special characters and resubmit the request using Fiddler, then the web-service invocation works.
My question is why does SSRS introduce these special characters and how can I make it stop? If I can't stop it, how can I get JAX-WS to ignore them? Here is my SSRS query:
<Query>
<Method Name="getOneUser" Namespace="http://vinny.com" >
</Method>
</Query>
I've also tried a query like this below:
<Query>
<Method Name="getOneUser" Namespace="http://vinny.com" >
</Method>
<SoapAction>http://vinny.com/getOneUser</SoapAction>
<ElementPath IgnoreNamespaces="true">*</ElementPath>
</Query>
Does anyone have any ideas on what I can try? I've tried several different types of annotations on the JAX-WS side to change the type of SOAPBinding, etc. but nothing seem to make it work with Microsoft SSRS.
The "Special characters" are the "Byte order marker" (BOM) indicating that the post body is UTF-8. http://unicode.org/faq/utf_bom.html#BOM
The Java service should be smart enough not to puke on these characters; I'm afraid I don't know how to help it.
Related
I am using MTOM to stream the attached file from client to the server.
The MTOM gets applied and the file is streamed as binary. But the root Content-Type was always "text/xml" which should be "application/xml+xop".
The problems occurs only in websphere. The content type was set as "text/xml" in websphere.
In websphere liberity profile, the content type was set as "application/xml+xop"
------=_Part_7283_-2062365125.1458743649653
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <511212039242.1458743649653.IBM.WEBSERVICES#lsrv4665.linux.rabobank.nl>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
</soapenv:Header>
<soapenv:Body>
<Content><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:58cf03d2-322f-4819-80fb-3b001f497d12%40www.test.com"/>
</Content>
</soapenv:Body>
</soapenv:Envelope>
Content-Type: application/pdf; name=attachment.pdf
Content-Transfer-Encoding: binary
I have gathered couple of answers. Hope first answer will be fit for you. For precautions, i have also added some other answer with links. Hope it will save you.
Ans-1:
server side (JAX-WS in Weblogic)
use #MTOM annotation or mtom.xml policy
client side (JAX-WS in Weblogic)
Pass MTOMFeature() as argument:
MtomService port = service.getMailServicePort(new MTOMFeature());
MTOM attachment via SOAPUI, 3 steps:
Set Enable MTOM = true in the request properties
Upload the attachment (e.g.. A3.pdf), notice the contentID
Set the MTOM contentID in the xml request
Here is a full example with images with weblogic. Hope it will fit with your issue.(link for Sending attachment: MTOM / XOP vs SWA and inline attachment)
Another Resource Link:
Steps to Use MTOM/XOP to Send Binary Data
Error consuming webservice, content type “application/xop+xml” does
not match expected type “text/xml”
Ans-2:
Pulling in saaj-impl 1.3.23 and preferring application classes for javax.xml.soap.* resolved this issue.
Resource Link: https://jira.spring.io/browse/SWS-855
Ans-3:
From mkyong's tutorial, it can be solved enabling mtom on client and server.
Enabling MTOM on server:
Enable server to send attachment via MTOM is very easy, just annotate the web service implementation class with javax.xml.ws.soap.MTOM.
Enabling MTOM on client:
Enable client to send attachment via MTOM to server is required some extra efforts, see following example :
//codes enable MTOM in client
BindingProvider bp = (BindingProvider) imageServer;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
Ans-4
Credit goes to #BalusC. He has given an awesome answer with his great tutorial.
The meta tag is ignored when the page is served over HTTP.
When using JSP,
you should put <%# page pageEncoding="UTF-8" %> in top.
When using Servlet,
you should do response.setCharacterEncoding("UTF-8");.
Both will implicitly set the right charset in the content type header. You may find this article useful: Unicode - How to get characters right?. For JSP/Servlet solutions, start at this chapter.
Resource Link:
How to set the "Content-Type ... charset" in the request header using a HTML link
For research, you can go through followings
For a Java servlet, you should have the line
response.setContentType("text/html");
at the top of your doGet or doPost method, where response is a reference to the HttpServletResponse.
Related Link:
How to set up your server to send the correct MIME types
Character Encoding problem with IBM's JSF and Ajax
Another answer
I've figured out what is causing the issue, but I do not understand why. The behavior exhibits itself when there is an on-error action on the request. Attached is a zip of a simple MPG with a request, response, and error rule that demonstrate this. The request has an on-error action, a simple xform that does a dp:reject (to force the error), and a results action. The error rule has a results action and a set var action. If you leave the on-error in, the response content-type is returned as "text/xml". If you remove the on-error, the content-type correctly returns "application/json". (Copied from following resource link)
Resource Link:
How to set header Content-Type in error rule
Able to resolve this issue by using saaj-impl jar.
pom.xml
<dependency>
<groupId>com.sun.xml.messaging.saaj</groupId>
<artifactId>saaj-impl</artifactId>
<version>1.3.16</version>
<scope>provided</scope>
</dependency>
dispatcher-servlet.xml
<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="messageFactory">
<bean class="com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl" />
</property>
</bean>
1.I created web services in netbeans using jboss 7, n i testing by typing the url into the browser and it came up like this..
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>
No such operation: null (HTTP GET PATH_INFO: /UnitConversion11/UnitConversion11null)
</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
So does anybody knows what the problem is because I have no idea.Is there anything about the xml file? and where is the xml fil :(
I think this is because your SOAP request wasn't correctly formulated. You normally use this SOAP by posting ugly blobs of XML everywhere. Your simple GET request probably isn't handled by the application you wrote.
From my hazy memory, there is a field in the request called something like soap:operation that identifies which bit of code will end up processing the request and this is of course missing from the GET request.
You could try testing your app using something like SOAPUI, curl, httprequester (..etc) to send a properly formulated SOAP request via POST or you could adapt your code to properly handle the GET request (possibly identified by having a null soap:operation?)
HTH
I'm using an Axis2 client to access an external Webservice, whose WSDL starts with the following content:
<?xml version="1.0" encoding="UTF-8"?><!--Created by TIBCO WSDL--><wsdl:definitions xmlns:wsdl=...
My call to sendReceive crashes with the following error:
com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character 'C' (code 67) in prolog; expected '<'
The 'C' is the first character on the comment in the WSDL. Without that comment everything works fine, but as far as my knowledge of basic XML dictates that comment is correct. My question would be: Is this a bug in Axis2 or is the accessed WSDL malformed? Is there any way to prevent Axis2 from crashing under these circumstances?
You should use wsdl documentation for it.Check the following links:
http://www.w3.org/TR/wsdl#_documentation
http://www.ws-i.org/Profiles/BasicProfile-1.1.html#WSDL_documentation_Element
After debugging the communications, I found out that the "C" was a red herring, and in fact the supplier's server was responding with the following text error message: Can not get operation configuration - invalid soapAction for input message.
The problem was that the soapAction header was not being sent in the HTTP request, after adding it everything worked fine.
I am confused about how SOAP messages and WSDL fit together? I have started looking into SOAP messages such as:
POST /InStock HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/stock">
<m:GetStockPrice>
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
Are all SOAP messages WSDL's? Is SOAP a protocol that accepts its own 'SOAP messages' or 'WSDL's? If they are different, then when should I use SOAP messages and when should I use WSDL's?
Some clarification around this would be awesome.
A SOAP document is sent per request. Say we were a book store, and had a remote server we queried to learn the current price of a particular book. Say we needed to pass the Book's title, number of pages and ISBN number to the server.
Whenever we wanted to know the price, we'd send a unique SOAP message. It'd look something like this;
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:GetBookPrice xmlns:m="http://namespaces.my-example-book-info.com">
<ISBN>978-0451524935</ISBN>
<Title>1984</Title>
<NumPages>328</NumPages>
</m:GetBookPrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And we expect to get a SOAP response message back like;
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:GetBookPriceResponse xmlns:m="http://namespaces.my-example-book-info.com">
<CurrentPrice>8.99</CurrentPrice>
<Currency>USD</Currency>
</m:GetBookPriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The WSDL then describes how to handle/process this message when a server receives it. In our case, it describes what types the Title, NumPages & ISBN would be, whether we should expect a response from the GetBookPrice message and what that response should look like.
The types would look like this;
<wsdl:types>
<!-- all type declarations are in a chunk of xsd -->
<xsd:schema targetNamespace="http://namespaces.my-example-book-info.com"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<xsd:element name="GetBookPrice">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ISBN" type="string"/>
<xsd:element name="Title" type="string"/>
<xsd:element name="NumPages" type="integer"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="GetBookPriceResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CurrentPrice" type="decimal" />
<xsd:element name="Currency" type="string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
But the WSDL also contains more information, about which functions link together to make operations, and what operations are avaliable in the service, and whereabouts on a network you can access the service/operations.
See also W3 Annotated WSDL Examples
A SOAP message is an XML document which is used to transmit your data. WSDL is an XML document which describes how to connect and make requests to your web service.
Basically SOAP messages are the data you transmit, WSDL tells you what you can do and how to make the calls.
A quick search in Google will yield many sources for additional reading (previous book link now dead, to combat this will put any new recommendations in comments)
Just noting your specific questions:
Are all SOAP messages WSDL's? No, they are not the same thing at all.
Is SOAP a protocol that accepts its own 'SOAP messages' or 'WSDL's? No - reading required as this is far off.
If they are different, then when should I use SOAP messages and when should I use WSDL's? Soap is structure you apply to your message/data for transfer. WSDLs are used only to determine how to make calls to the service in the first place. Often this is a one time thing when you first add code to make a call to a particular webservice.
We need to define what is a web service before telling what are the difference between the SOAP and WSDL where the two (SOAP and WSDL) are components of a web service
Most applications are developed to interact with users, the user enters or searches for data through an interface and the application then responds to the user's input.
A Web service does more or less the same thing except that a Web service application communicates only from machine to machine or application to application. There is often no direct user interaction.
A Web service basically is a collection of open protocols that is used to exchange data between applications. The use of open protocols enables Web services to be platform independent. Software that are written in different programming languages and that run on different platforms can use Web services to exchange data over computer networks such as the Internet. In other words, Windows applications can talk to PHP, Java and Perl applications and many others, which in normal circumstances would not be possible.
How Do Web Services Work?
Because different applications are written in different programming languages, they often cannot communicate with each other. A Web service enables this communication by using a combination of open protocols and standards, chiefly XML, SOAP and WSDL. A Web service uses XML to tag data, SOAP to transfer a message and finally WSDL to describe the availability of services. Let's take a look at these three main components of a Web service application.
Simple Object Access Protocol (SOAP)
The Simple Object Access Protocol or SOAP is a protocol for sending and receiving messages between applications without confronting interoperability issues (interoperability meaning the platform that a Web service is running on becomes irrelevant). Another protocol that has a similar function is HTTP. It is used to access Web pages or to surf the Net. HTTP ensures that you do not have to worry about what kind of Web server -- whether Apache or IIS or any other -- serves you the pages you are viewing or whether the pages you view were created in ASP.NET or HTML.
Because SOAP is used both for requesting and responding, its contents vary slightly depending on its purpose.
Below is an example of a SOAP request and response message
SOAP Request:
POST /InStock HTTP/1.1
Host: www.bookshop.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.bookshop.org/prices">
<m:GetBookPrice>
<m:BookName>The Fleamarket</m:BookName>
</m:GetBookPrice>
</soap:Body>
</soap:Envelope>
SOAP Response:
POST /InStock HTTP/1.1
Host: www.bookshop.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body xmlns:m="http://www.bookshop.org/prices">
<m:GetBookPriceResponse>
<m: Price>10.95</m: Price>
</m:GetBookPriceResponse>
</soap:Body>
</soap:Envelope>
Although both messages look the same, they carry out different methods. For instance looking at the above examples you can see that the requesting message uses the GetBookPrice method to get the book price. The response is carried out by the GetBookPriceResponse method, which is going to be the message that you as the "requestor" will see. You can also see that the messages are composed using XML.
Web Services Description Language or WSDL
WSDL is a document that describes a Web service and also tells you how to access and use its methods.
WSDL takes care of how do you know what methods are available in a Web service that you stumble across on the Internet.
Take a look at a sample WSDL file:
<?xml version="1.0" encoding="UTF-8"?>
<definitions name ="DayOfWeek"
targetNamespace="http://www.roguewave.com/soapworx/examples/DayOfWeek.wsdl"
xmlns:tns="http://www.roguewave.com/soapworx/examples/DayOfWeek.wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<message name="DayOfWeekInput">
<part name="date" type="xsd:date"/>
</message>
<message name="DayOfWeekResponse">
<part name="dayOfWeek" type="xsd:string"/>
</message>
<portType name="DayOfWeekPortType">
<operation name="GetDayOfWeek">
<input message="tns:DayOfWeekInput"/>
<output message="tns:DayOfWeekResponse"/>
</operation>
</portType>
<binding name="DayOfWeekBinding" type="tns:DayOfWeekPortType">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetDayOfWeek">
<soap:operation soapAction="getdayofweek"/>
<input>
<soap:body use="encoded"
namespace="http://www.roguewave.com/soapworx/examples"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded"
namespace="http://www.roguewave.com/soapworx/examples"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="DayOfWeekService" >
<documentation>
Returns the day-of-week name for a given date
</documentation>
<port name="DayOfWeekPort" binding="tns:DayOfWeekBinding">
<soap:address location="http://localhost:8090/dayofweek/DayOfWeek"/>
</port>
</service>
</definitions>
The main things to remember about a WSDL file are that it provides you with:
A description of a Web service
The methods a Web service uses and the parameters that it takes
A way to locate Web services
A WSDL (Web Service Definition Language) is a meta-data file that describes the web service.
Things like operation name, parameters etc.
The soap messages are the actual payloads
Better analogy than the telephone call: Ordering products via postal mail from a mail-order service.
The WSDL document is like the instructions that explain how to create the kind of order forms that the service provider will accept.
A SOAP message is like an envelope with a standard design (size, shape, construction) that every post office around the world knows how to handle. You put your order form into such an envelope. The network (e.g. the internet) is the postal service. You put your envelope into the mail. The employees of the postal service do not look inside the envelope.
The payload XML is the order form that you have enclosed in the envelope. After the post office delivers the envelope, the web service provider opens the envelope and processes the order form. If you have created and filled out the form correctly, they will mail the product that you ordered back to you.
In a simple terms if you have a web service of calculator. WSDL tells about the functions that you can implement or exposed to the client. For example: add, delete, subtract and so on. Where as using SOAP you actually perform actions like doDelete(), doSubtract(), doAdd(). So SOAP and WSDL are apples and oranges. We should not compare them. They both have their own different functionality.
SOAP :
It's an open standard XML based Communication protocol which is used to exchange information from the user to web service or vice versa.
The soap is just the document in which the data are organized in some Manner.
For every request and response separate soap may be present.
WSDL:
In soap the data are organized in some manner and this organization is specified in WSDL, The data type which has to be used are also specified here.
For request and response single WSDL will be present
WSDL act as an interface between sender and receiver.
SOAP message is request and response in xml format.
comparing with java RMI
WSDL is the interface class
SOAP message is marshaled request and response message.
The WSDL is a kind of contract between API provider and the client it's describe the web service : the public function , optional/required field ...
But The soap message is a data transferred between client and provider (payload)
We can consider a telephone call In that Number is wsdl and exchange of information is soap.
WSDL is description how to connect with communication server.SOAP is have communication messages.
Here is my requirement.
I have a client that was sending a specific message format to some software service provider(ABC) using what ever network protocol.
Now this client is switching software service provider (XYZ) but does not want to change their software and wants to continue sending the same message of ABC provider.
Provider ABC uses some sort of positional based message format over some archaic network protocol
Provider XYZ uses XML over HTTP(s) web service not SOA just simple POST with XML
Some values can be directly mapped while others must be recalculated or modified. For instance converting client's account number from ABC Provider to account number of XYZ provider. this is for request and response.
The archaic network protocol will be converted to TCPI/IP at the network level so that is not an issue.
The client expect a response in real time. I.e: Client makes request, XYZ does what ever and response back to client.
So I need to create some sort of tunnel that accepts TCP/IP converts the message to XML, sends it HTTP(s) POST to XYZ, get back XML response, convert back to positional based, reply back through TCPI/IP to the client.
Is this an ESB type thing, should I just write some sort JAVA server app that will do this?
You have too many options. Starting from Python, Perl.. there are libraries/modules that provide your TCP/HTTP/telnet/... support. Using that you can do this.
ESB might be an overkill for this, it's a big framework for big integrations, but yes you can write your BCs (Binding Components) and do it. Performance I'm not sure if ESB would be as good as something more primitive like .pl/.py
In short there are too many options. You have to take the call based on the environment in which you have to deploy it.
E.g. you said "Some values can be directly mapped while others must be recalculated or modified. For instance converting client's account number from ABC Provider to account number of XYZ provider. this is for request and response.", if ABC-A/c-num to XYZ-A/c-num mapping is only available via a remote EJB call then you might want to consider writing the whole thing in J2EE. If you "calculations" need some specific libs you have to factor that in as well...
Hope this doesn't make your problem worse.. :)
PS: You should start accepting answers to your previous questions. as Home said.
Tried Mule ESB it's very light weight. I would say even more so then some of it's competition. I like how it's not particularly bound to SOA or soap. So you can construct any kind of end point from plain TCP/IP, HTTP, File, to Email to anything really it has more then a dozen connectors and you can even write your own. I also like the fact that the message can be anything. I could be wrong but even when others claim they have various connectors and message formats they seem to have SOAP somewhere hidden under the hood and it seems icky lol Some others seem good, but have poor docs. Didn't like the fact that some basic JDBC functionality is only available in the enterprise edition. I.e: To get Output parameters from your stored proc call you need the enterprise edition.
In reality I could have picked any server API that allowed me to create a server to receive HTTP, then write my code to transform a message, open a client connection to the next service send it off, receive the response, re-transform it back and return to the client. All while making sure threads and queues are behaving correctly within the server. Maybe I could have just used jetty and a servlet and do everything in one request. It's an option, but if I have to switch to TCP/IP then I just change the config a bit. Waiting to see what the client says.
The ESB is basically the glue and plumbing. All I had to do was write three custom transformer classes as the messages I deal with are proprietary banking formats and don't exactly map to simple XSLT/XML transforms... And about a 20 XML tags to put it all together...
This is all I needed to get this out of Mule (not including the tags to build my datasource and SQL query)...
<flow name="myFlow">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" />
<object-to-string-transformer />
<custom-transformer class="com.mycom.transformer.MyTransformer" />
<enricher target="#[variable:client]">
<jdbc:outbound-endpoint queryKey="getClientConfig" exchange-pattern="request-response" />
</enricher>
<custom-transformer class="com.MyCom.transformer.MyOtherTransformer" />
<http:outbound-endpoint exchange-pattern="request-response" host="xxx.xxx.xxx.xxx" port="80" path="some path" method="POST"/>
<custom-transformer class="com.MyCom.transformer.BackToOtherFormat" />
</flow>
So basically...
1- receive HTTP(s) with custom message
2- Parse message to get client number
3- Lookup client number in database to get client number for the other service...
4- Create the new message
5- Send off to other service
6- Transform response back
7- Return to client
<flow name="FileTransferFlow1" doc:name="FileTransferFlow1">
<file:inbound-endpoint path="C:\mule_projects\filetransfer\in" responseTimeout="10000" doc:name="IncomingFile"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" doc:name="HTTP" responseTransformer-refs="Java"/>
<custom-transformer class="com.Transformer" doc:name="Java"/>
<file:outbound-endpoint path="C:\mule_projects\filetransfer\out" responseTimeout="10000" doc:name="OutgoingFile"/>
</flow>