Spring Web service SoapMessage.writeTo(OutputStream o) - spring-ws

We are trying to convert SoapMessage to String value, In our code, we are writing the SoapMessage to ByteArrayOutputStream. But with ByteArrayOutputStream, there is lot of issues like memory leakage issue and performance issues
Please find below our code:
MessageContext messageContext;
SoapMessage requestSoapMessage = (SoapMessage)messageContext.getRequest();
SoapMessage responseSoapMessage = (SoapMessage)messageContext.getResponse();
//Getting request
ByteArrayOutputStream baos_req = new ByteArrayOutputStream();
requestSoapMessage.WriteTo(baos_req);
String soapReqMsg = baos_req.toString();
//Getting response
ByteArrayOutputStream baos_resp = new ByteArrayOutputStream();
responseSoapMessage.WriteTo(baos_resp);
String soapRespMsg = baos_resp.toString();
Please any one guide me,
Is there any way of getting Soap request and response in String without using OutputStream.
Thanks in advance!!!!

There is no other way than using a ByteArrayOutputStream. In fact, that is the same technique I use in Spring-WS myself. Though I would recommend using a UTF-8 character encoding:
ByteArrayOutputStream bos = new ByteArrayOutputStream();
message.writeTo(bos);
return bos.toString("UTF-8");
I am not sure what you mean with "memory leakage and performance issues", I am not aware that the BAOS has any.

Related

Android YouTube V3 API not working

I am hitting the following url from my android device.
URL : https://www.googleapis.com/youtube/v3/search?key=MY_KEY&channelId=UCoWgc1mqe-bcfb_lem7EyOg&part=snippet,id&order=date&maxResults=50
Response: ������������������]�r�8�}ϯ#e?䋕�}ɗ j����%OO(#�q3���*b�a"�g�o�K��%Y]�em�,uGd8m�ātu��]������/�c���W�_����B���M��;v�������q:��fA�[8KR�����lZ?[t]�඘JL���`�������G1����h䬑��T[}E�y�]qt�_xl��.��e/v�o���H
For getting the YouTube Videos List.It was working fine before but sometimes its response is not valid while hitting from browsers it works well.
Please help me !!
I found the solution i was using the loop j library (for http request) old version
just changes
compile 'com.loopj.android:android-async-http:1.4.8'
to
compile 'com.loopj.android:android-async-http:1.4.9'
it solved my problem
Please see my related question here (but in C#) and the answers on it in order to understand what I mean. Then you have to search example fordecompress gzip android and look at the existing resources to accomplish this.
Please keep in mind, that the API does not always send the response in gzip-format or not. So please do a check if the response is really in gzip.
For the plain decompression you can use the following method:
public static String decompress(byte[] compressed) throws IOException {
final int BUFFER_SIZE = 32;
ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
GZIPInputStream gis = new GZIPInputStream(bis, BUFFER_SIZE);
StringBuilder s = new StringBuilder();
byte[] data = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = gis.read(data)) != -1) {
s.append(new String(data, 0, bytesRead));
}
gis.close();
bis.close();
return s.toString();
}
(this code was taken from Vyshnavi's answer)

Http Post a Stream in F# without reading into a Byte Array

With C# I can use the System.Net.Http Library to post a stream directly like so:
private async Task UploadFileAsync(Uri uri, string filename)
{
using (var stream = File.OpenRead(filename))
using (var client = new HttpClient())
{
await client.PostAsync(uri, new StreamContent(stream));
}
}
Is there a way to do this in F# in a functionally idiomatic way?
FSharp.Data.Http.Request lets you post Binary data but requires a byte array to do so, which means reading the stream into memory. I'd like to avoid this as I am posting > 20Mb.
Doing this in a functionally idiomatic way would involve some kind of IO monad. As F# is a mixed paradigm language e.g.
let uploadFile (uri: Uri) fileName =
async {
use stream = File.OpenRead fileName
use client = new HttpClient()
return! client.PostAsync(uri, new StreamContent(stream)) |> Async.AwaitTask
}
is perfectly acceptable IMHO.

Returning a JSON stream from an ApiController

I've got a large JSON Object which I need to return from an MVC ApiController.
I can't simply return the JSON Object as the internal serializer barfs on the serialized contents being too long.
I don't want to serialize to string and then return the string as we could be dealing 5-6MB of data and that seems like a waste of memory for no purpose.
What I want to do is use the Newtonsoft JSON Serializer to write to the response stream directly.
Dim Ret = Client.Search(Model) ''Get the results object
Dim Response As New HttpResponseMessage()
Using MemoryStream As New IO.MemoryStream
Using StreamWriter As New StreamWriter(MemoryStream)
Using JsonWriter As JsonWriter = New JsonTextWriter(StreamWriter)
Dim Serializer As New JsonSerializer
Serializer.Serialize(JsonWriter, Ret)
End Using
End Using
Response.Content = New StreamContent(MemoryStream)
Return Response
End Using
Unfortunately, this results in the connection being reset unexpectedly - I'm guessing this is due to the stream being disposed of before it's finished sending the result?
Even if I strip out all the Using blocks and just leave everything for the GC as here:
Dim Ret = Client.Search(Model)
Dim Response As New HttpResponseMessage()
Dim MemoryStream As New IO.MemoryStream
Dim StreamWriter As New StreamWriter(MemoryStream)
Dim JsonWriter As JsonWriter = New JsonTextWriter(StreamWriter)
Dim Serializer As New JsonSerializer
Serializer.Serialize(JsonWriter, Ret)
Response.Content = New StreamContent(MemoryStream)
Return Response
I get a 0-byte response instead. Can someone please point me in the right direction?
Have you tried checking timeout settings in web.config/machine.config? Maybe IIS decides that it's taking too long to get Response.Content.
Anyhow, you should check this issue out with Failed Requests Using Tracing - that should point you in the right direction.
It turns out this was a silly mistake on my part... I wasn't flushing the writer and resetting the stream position...
JsonWriter.Flush()
MemoryStream.Seek(0, StreamPosition.Beginning)
Solved the problem

Blackberry-not getting soap response xml

I am trying to consume SOAP response xml by passing request xml in a string, using BlackBerry Java plugin for Eclipse. I have been struck on this for the past two days looking for a way to solve it.
I have attached the sample code below.
public String CheckXml()
{
final String requestXml="<SOAP:Envelope xmlns:SOAP=\"http://schemas.xmlsoap.org/soap/envelope/\"><header xmlns=\"http://schemas.cordys.com/General/1.0/\"></header><SOAP:Body><authenticateAgainstOID xmlns=\"http://schemas.cordys.com/OIDAuthentication\"><stringParam>HEMANTS_MUM013</stringParam><stringParam1>TATA2012</stringParam1></authenticateAgainstOID></SOAP:Body></SOAP:Envelope>";
final String HOST_ADDRESS = "http://xyz.com/cordys/com.eibus.web.soap.Gateway.wcp?organization=o=B2C,cn=cordys,cn=cbop,o=tatamotors.com&SAMLart=MDFn+8e5dRDaRMRIwMY7nI84eEccbx+lIiV0VhsOQ7u+SKG6n5+WNB58";
String result="";
try {
HttpConnection url=(HttpConnection)Connector.open(HOST_ADDRESS);
url.setRequestProperty("Content-Type", "text/xml");
url.setRequestMethod(HttpConnection.GET);
OutputStreamWriter writer=new OutputStreamWriter(url.openOutputStream());
writer.write(requestXml);
writer.flush();
writer.close();
StringBuffer buffer1=new StringBuffer();
InputStreamReader reader=new InputStreamReader(url.openInputStream());
StringBuffer buffer=new StringBuffer();
char[] cbuf=new char[2048];
int num;
while (-1 != (num = reader.read(cbuf))) {
buffer.append(cbuf, 0, num);
}
String result1 = buffer.toString();
} catch (Exception e) {
System.out.println(e);
}
return result;
}
I think the main issue that you aren't asking http. getResponseCode(). I think BB doesn't do any interaction until you call it.
I would also be careful with this code on the real devices. Search for correct opening connection on the BlackBerries.
I noticed that you are not including the SoapAction header in the request.
SOAP Web services usually have a fixed URL, and the differents methods are selected with the SoapAction header. You can check the header by opening the WSDL in a browser and inspecting the format for the method you want to invoke.
Once you know which action to select, set it as a regular http header:
url.setRequestProperty("SOAPAction", <your action here>);
Another source of problems in your code is that you are using the old HttpConnection class that requires appending a suffix to the URL depending on the transport type (MDS, BIS, Wi-Fi, etc). You don't need to use this legacy class unless you are targeting OS 4.5 and lower. So have a look at ConnectionFactory class, which is much easier to use. It is available since OS 5.0.

call birt report from action class

I am developing a project in Java EE Struts 2 and Hibernate for airline reservations. Now my all work is done and I have to generate a ticket. Instead of generating a simple JSP or HTML ticket, I want to generate a downloadable report (like Crystal Reports in Java). I have my entire ticket info in a session that (as on internet) I can get on BIRT report using script.
I am totally new to BIRT and wanted to know how I can generate a BIRT report or maybe call its execution engine from one of my action classes. Any ready example will be a great help.
I guess you're trying to send PDF ticket to customers. Please create your template and pass parameters using these lines:
ReportAdminServiceRemote birtAdmService = (ReportAdminServiceRemote)MXServer.getMXServer().lookup(“BIRTREPORT”);
byte[] abyte0 = birtAdmService .runReport(userInfo, reportName, appName, parameterData, filename, “pdf”);
Once you have the bytes generated you can do this way:
public String actionDownload() throws Exception{
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Content-Disposition","attachment; filename=\"" + example.pdf+ "\"");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayInputStream bis = new ByteArrayInputStream(abyte0);
inputStream = bis;
return SUCCESS;
}
All the credits goes to authors on these pages:
http://www.maximonews.com/?p=65
http://www.coderanch.com/t/432713/Struts/Struts-Files-DownLoad-Streaming-as

Resources