DougBreaux 270007SMYJ Visits (4826)
We've recently had a need to accept files submitted by a partner and perform some processing on them, with the partner returning later to retrieve the results. Rather than the "old", standard approach of using something like sftp and regularly kicking off a cron job to look for input files, this seemed like a good case for a Web Service.
And IMO REST style services are simpler to produce (particularly with standard APIs like JAX-RS), consume, and test, and further are a good fit for this particular scenario. (See the excellent book REST
I decided to support the URL "/batch", as an HTTP POST of standard "mul
I should say, I decided to propose this approach and then go see if I could make it happen in a straightforward way. I wasn't sure if submitting files this way was normal enough to be easily supported by JAX-RS and/or WebSphere.
It turns out this is supported by JAX-RS in WebSphere, with a few different mechanisms. Right there in the official IBM Knowledge Center documentation, (almost) everything I needed to know:
So go read that, I'm done :-)
... well, ok, I'll summarize and note a few things, while I'm here.
Generic JAX-RS approach
I generally prefer to stick to the specs, not using any server-specific or impl
With WebSphere, this uploads the file to a temporary location, and gives it a generated file name. (On my Windows development system, the location seems to be my Windows %TEMP% directory.)
However, I'd prefer to prescriptively set the upload directory (so I don't have to later copy it to a more "permanent" location), and I really want the original file's name (among other things, so I can detect when the same file is inadvertently submitted again).
Because of these requirements, I needed to look for another approach.
WebSphere-specific (Apache Wink) approach
It turns out the last example on that
This approach looks more like:
And involves looping through the parts and parsing the HTTP Headers to get the Cont
In addition to the above WebSphere link, also see Apac
I'll note a few problematic behaviors we discovered during the implementation and testing.
Internet Explorer and file input elements
Further, the java
Granted, this service won't normally be called from a browser and HTML page, but during testing, it sometimes is. And even there, using a different browser is acceptable. But still, if it wasn't too much work, I'd prefer to handle this more robustly "just in case".
.NET client error on the GET request
Our partner appears to be using a C# .NET client, and even after he had success submitting a file to our POST URL, he was getting this error upon calling our GET URL from Http
“The server committed a protocol violation. Sect
I've been trying to connect to a customer's Web Service (from within WebSphere 6.1, but that's a different topic) and having some problems getting the security to work (another different topic), so I've desperately wanted an https-capable traffic monitor/proxy.
After trying the one built into RAD (which successfully passes the https requests, but displays them as encrypted garbage), Apache tcpmon (no SSL), membrane-monitor (seemed to not respond at all and I couldn't tell why), and Wireshark (looked too tedious to get working with SSL), I eventually got soapUI's HTTP Monitor working, although not without some non-obvious setup there either. So I'm going to document that setup here.
Trust the Service Endpoint
First, you'll need a jks TrustStore where you can place the public key of the server which hosts the https-protected Service you're going to call. You can use a tool like the GUI ikeyman, included with WebSphere, or the command-line keytool, included with your JRE, to do this.
Launch the HTTP Monitor
Next, it seemed fairly obvious what to do in soapUI. Right-click on a project and "Launch HTTP Monitor". You're presented with the following dialog:
To do https/SSL, you need to select HTTP Tunnel rather than HTTP Proxy. Set the Port to the local port your client is going to hit, and the endpoint to the remote service URL you're ultimately calling.
Then go to the Security tab:
Initially, all I had was the aforementioned TrustStore configured here in the HTTP tunnel - TrustStore and TrustStore Password fields. This allows the HTTP Monitor to talk SSL to the remote Service.
However, when I started the monitor with those settings, I received a cryptic dialog, "Error starting monitor: C:\Program File
I suspected Windows authority problems or path problems, but nothing seemed to resolve those, so I tried running the soapui.bat script from a command-prompt rather than the soapUI desktop shortcut, and then I saw the following prompts:
jetty.ssl.password : jett
Ahah! Google does find something relevant there.
HTTP Monitor Server Certificate
HTTP Monitor needs its own SSL certificate (private key) and KeyStore in order to also talk SSL to your client application, which I should have realized. Then, of course, your client environment will have to import the public portion of that certificate into its TrustStore as well. But the less obvious detail is that this private key must use the alias "jetty" (as soapUI is using the Jetty server under the covers).
So again using keytool (or ikeyman), this time to generate a private/public key certificate pair with the alias "jetty", create the KeyStore that is referenced in the HTTP tunnel - KeyStore, Password, and KeyPassword fields. (Note the two properties listed in the prompts above.) Here's the keytool command I actually used:
jre\bin\keytool -genkeypair -alias jetty -keystore soapui.jks
Now complete the remaining Security fields and click "OK":
You'll have an SSL Tunnel listening on your local port, and you'll be able to see SOAP requests and responses sent through that local URL.
DougBreaux 270007SMYJ Visits (5215)
If you've ever wanted to know what kind of HTTP Request headers might be coming from a client or some intermediate proxy, here's a simple JSP you can manually deploy to your JEE Web Application to see a list.