I am using BlazeDS java client to get info from this page.
This page has a form in the middle that when you select a type, the location combo on the button gets updated.
I am trying to use BlazeDS to get those values in java.
I have been using Charles web proxy to debug, and this are the screenshots from the request and the response:
My code so far is the following:
// Create the AMF connection.
AMFConnection amfConnection = new AMFConnection();
// Connect to the remote url.
String url = "http://orlandoinfo.com/flex2gateway/";
try
{
amfConnection.connect(url);
}
catch (ClientStatusException cse)
{
System.out.println(cse);
return;
}
// Make a remoting call and retrieve the result.
try
{
// amfConnection.registerAlias("flex.messaging.io.ArrayCollection", "flex.messaging.io.ArrayCollection");
amfConnection.call("ColdFusion.getLocations", new Object[] {"consumer", "attractions", "ATTR"});
}
catch (ClientStatusException cse)
{
System.out.println(cse);
}
catch (ServerStatusException sse)
{
System.out.println(sse);
}
// Close the connection.
amfConnection.close();
When I run it I get a:
ServerStatusException
data: ASObject(15401342){message=Unable to find source to invoke, rootCause=null, details=null, code=Server.Processing}
HttpResponseInfo: HttpResponseInfo
code: 200
message: OK
Can anyone spot what's wrong?
Thanks for reading!
I ended up using Charles Web Proxy. Sniffing AMF parameters and running my code with -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888
I compare both calls and modify to look alike.
The working code looks like this:
String url = "http://www.theGateWayurl.com";
// Generates the connection to the amf gateway.
AMFConnection amfConnection = new AMFConnection();
// Must register the class that this library will use to load the
// AMF object information.
// The library will read AMF object variables and use setters from
// the java bean stated in this line.
AMFConnection.registerAlias("", new LabelData().getClass().getName());
try {
// Do the connection.
amfConnection.connect(url);
// This page requires a certain headers to function.
// The Content-type is used to sniff with Charles Web Proxy.
amfConnection.addHttpRequestHeader("Content-type", "application/x-amf");
// The Referer is used by the webpage to allow gathering information.
amfConnection.addHttpRequestHeader("Referer", "http://orlandoinfo.com/ws/b2c/sitesearch/customtags/comSearch.swf");
// The rest of the HTTP POST sent by this library is wrapped
// inside a RemotingMessage.
// Prepare the msg to send.
RemotingMessage msg = new RemotingMessage();
// The method called in the server.
msg.setOperation("getLocations");
// Where the request came from. Similar to referer.
msg.setSource("ws.b2c.sitesearch.components.myService");
// The destination is a needed parameter.
msg.setDestination("ColdFusion");
// Create the body with the parameters needed to call the
// operation set with setOperation()
msg.setBody(new Object[] {"consumer", "attractions"});
// This is needed but not used.
msg.setMessageId("xxxxxxxxxx");
// Send the msg.
AcknowledgeMessage reply = (AcknowledgeMessage) amfConnection.call("null", msg);
// Parse the reply from the server.
ArrayCollection body = (ArrayCollection) reply.getBody();
for (Object obj : body) {
LabelData location = (LabelData) obj;
// Do something with the info.
}
} catch (ClientStatusException cse) {
// Do something with the exception.
} catch (ServerStatusException sse) {
// Do something with the exception.
} finally {
amfConnection.close();
}
The LabelData is just a java bean with with two vars: Data and Label.
I tried to comment every line for a better understanding.
Take into account what Stu mention in previous comments about crossdomain.xml to see if you have the rights to do this kind of things.
Related
I work on university project in java. I have to download attachments from new emails using GMAIL API.
I successfully connected to gmail account using OAuth 2.0 authorization.
private static final List<String> SCOPES = Collections.singletonList(GmailScopes.GMAIL_READONLY);
I tried to get unseen mails using
ListMessagesResponse listMessageResponse = service.users().messages().list(user).setQ("is:unseen").execute();
listMessageResponse is not null but when I call method .getResultSizeEstimate() it returns 0
also I tried to convert listMessageResponse to List < Message > (I guess this is more usable) using
List<Message> list = listMessageResponse.getMessages();
But list launches NullPointerException
Then tried to get each attachment with
for(Message m : list) {
List<MessagePart> part = m.getPayload().getParts();
for(MessagePart p: part) {
if(p.getFilename()!=null && p.getFilename().length()>0) {
System.out.println(p.getFilename()); // Just to check attachment filename
}
}
}
Is my approach correct (if not how to fix it) and how should I download those attachments.
EDIT 1:
Fixed q parameter, I mistakenly wrote is:unseen instead of is:unread.
Now app reaches unread mails successfully.
(For example there was two unread mails and both successfully reached, I can get theirs IDs easy).
Now this part trows NullPointerException
List<MessagePart> part = m.getPayload().getParts();
Both messages have attachments and m is not null (I get ID with .getID())
Any ideas how to overcome this and download attachment?
EDIT 2:
Attachments Downloading part
for(MessagePart p : parts) {
if ((p.getFilename() != null && p.getFilename().length() > 0)) {
String filename = p.getFilename();
String attId = p.getBody().getAttachmentId();
MessagePartBody attachPart;
FileOutputStream fileOutFile = null;
try {
attachPart = service.users().messages().attachments().get("me", p.getPartId(), attId).execute();
byte[] fileByteArray = Base64.decodeBase64(attachPart.getData());
fileOutFile = new FileOutputStream(filename); // Or any other dir
fileOutFile.write(fileByteArray);
fileOutFile.close();
}catch (IOException e) {
System.out.println("IO Exception processing attachment: " + filename);
} finally {
if (fileOutFile != null) {
try {
fileOutFile.close();
} catch (IOException e) {
// probably doesn't matter
}
}
}
}
}
Downloading working like charm, tested app with different type of emails.
Only thing left is to change label of unread message (that was reached by app) to read. Any tips how to do it?
And one tiny question:
I want this app to fetch mails on every 10 minutes using TimerTask abstract class. Is there need for manual "closing" of connection with gmail or that's done automatically after run() method iteration ends?
#Override
public void run(){
// Some fancy code
service.close(); // Something like that if even exists
}
I don't think ListMessagesResponse ever becomes null. Even if there are no messages that match your query, at least resultSizeEstimate will get populated in the resulting response: see Users.messages: list > Response.
I think you are using the correct approach, just that there is no message that matches your query. Actually, I never saw is:unseen before. Did you mean is:unread instead?
Update:
When using Users.messages: list only the id and the threadId of each message is populated, so you cannot access the message payload. In order to get the full message resource, you have to use Users.messages: get instead, as you can see in the referenced link:
Note that each message resource contains only an id and a threadId. Additional message details can be fetched using the messages.get method.
So in this case, after getting the list of messages, you have to iterate through the list, and do the following for each message in the list:
Get the message id via m.getId().
Once you have retrieved the message id, use it to call Gmail.Users.Messages.Get and get the full message resource. The retrieved message should have all fields populated, including payload, and you should be able to access the corresponding attachments.
Code sample:
List<Message> list = listMessageResponse.getMessages();
for(Message m : list) {
Message message = service.users().messages().get(user, m.getId()).execute();
List<MessagePart> part = message.getPayload().getParts();
// Rest of code
}
Reference:
Class ListMessagesResponse
Users.messages: list > Response
please, this is y concern: I'll like to know how to query a web service defined as in the below code using postman for test purposes.
PS: I can't change the method signature
I have a web service like this :
#POST
#Path("/uploadOpenAccountRequestFiles/{requestId}")
#Consumes({MediaType.APPLICATION_JSON,MediaType.MULTIPART_FORM_DATA})
public Response uploadOpenAccountRequestFiles(#PathParam("requestId") String requestId,
MultipartFormDataInput multipartFormDataInput)
throws JsonGenerationException, JsonMappingException, IOException {
initContext();
logger.info("DIGIBANK : uploadOpenAccountRequestFiles END: ");
String msge = "";
try {
digiBean.saveToserver(requestId, multipartFormDataInput);
} catch (Exception e) {
msge = e.getMessage();
e.printStackTrace();
}
org.af.webservice.Response resp = new org.af.webservice.Response(
request.getSession().getId(), "uploadOpenAccountRequestFiles", "",
msge.equalsIgnoreCase("OK") ? true : false, msge.equalsIgnoreCase("OK") ? false : true, "",
msge.equalsIgnoreCase("OK") ? true : false, "Boolean", msge);
logger.info("DIGIBANK : uploadOpenAccountRequestFiles END: ");
return Response.ok().entity(mapper.writeValueAsString(resp)).build();
}
this is are images of my configurations:
enter image description here
enter image description here
For calling that service, you need to pass requestId like below:
http://localhost:8080/uploadOpenAccountRequestFiles/requestId-value-here
For sending MultiPart data such as a file, you need to select form-data option in the body section in Postman and select the file by selecting the File dropdown. Also, make sure to set the appropriate headers for the request.
Check the below stackoverflow answer for more details:
Tool for sending multipart/form-data request
The steps of uploading a file through postman along with passing some input data along with the multipart request is very well discussed in below blog along with the screenshot. In this blog, the api code is written in node js. You can go through it once. It may give some information.
https://jksnu.blogspot.com/2021/09/how-to-create-post-request-with.html
I am using Spark framework for my application.
I have a middleware which checks (among other things) if the body is of JSON format:
// Middleware
before((req, res) -> {
// Method check
if (!req.requestMethod().equals("POST")) {
halt(403, "{\"result\":\"ERR\",\"errMsg\":\"Only POST allowed!\",\"code\":403}");
}
// JSON Check
JSONObject body_json = new JSONObject();
try {
body_json = new JSONObject(req.body());
} catch (JSONException e) {
halt(403, "{\"result\":\"ERR\",\"errMsg\":\"No valid JSON!\",\"code\":403}");
}
// At this point (end of middleware) the request body is still unchanged !
});
Then I have my normal function for processing POST requests:
post("/post_some_data", (req, res) -> {
String body = req.body() // This string is empty !!
int length = req.contentLength(); // This remain unchanged
});
But the request body suddenly becomes empty (other attributes and headers remain unchanged).
Is that a bug or am I doing something wrong ??
There was a bug in the spark framework. Updating the library to the 2.1 version will solve this and all of the similar problems.
I'm using the SoapUI API as part of an existing java project.
The application should save the request and response XML in an specific report file.
I wonder if it's possible to get those requests and responses via the API.
The method invoking the TestCaseRunner looks like this
protected void checkTestCase(TestCase testCase) {
TestCaseRunner tr = testCase.run(null, false);
for (TestStepResult tcr : tr.getResults()) {
String status = tcr.getStatus();
String time = tcr.getTimeTaken() + "ms";
/* How to get XML messages?
* String request =
* String response =
*/
}
}
Depending on exactly what kind of test steps you have they might be an instance of a MessageExchange. Casting the TestStepResult to a MessageExchange and calling getRequestContent / getResponseContent might do the trick.
String request = ((MessageExchange)tcr).getRequestContent();
String response = ((MessageExchange)tcr).getResponseContent();
I have used the following way to get the response from the API CAll performed:
runner = testRunner.runTestStepByName("Your Test Case name");
// Here we take the response in ms of the API call
timeTaken = runner.response.timeTaken;
// here we get the HTTP response code.
responseCode = runner.getResponseHeaders()."#status#";
// here we get the response content
String response = runner.getResponseContent();
// here we get the API call endpoint -> in case you need to print it out.
String endPoint = runner.getEndpoint();
I'm implementing a client to a web service (and the guys maintaining the web service have been a litte unresponsive..) I've used axis and WSDL2Java to generate java classes and I can call their login-method on their authentication-service ok, and get a sessionId back (eg z4zojhiqkw40lj55kgtn1oya). However, it seems that i cannot use this sessionId as a parameter anywhere. Even a call to their hasSession()-method directly after login returned false. I managed to solve this by setting setMaintainSession(true) on the Locator-object for this service. But the problem is, that this first service, the Authentication-service, is only used for authentification. If I then call setMaintainSession(true) on eg ProductServiceLocator, and call some method on it, I will get an error because of unauthenticated session. I have to find a way to share the session between the services on the client side.
Looking on their php code example-it seeems like they are storing the session in a cookie. How can I mimic this behaviour in my java client?
php-code:
$authentication = new SoapClient ( "https://webservices.24sevenoffice.com/authenticate/authenticate.asmx?wsdl", $options );
// log into 24SevenOffice if we don't have any active session. No point doing this more than once.
$login = true;
if (!empty($_SESSION['ASP.NET_SessionId'])){
$authentication->__setCookie("ASP.NET_SessionId", $_SESSION['ASP.NET_SessionId']);
try{
$login = !($authentication->HasSession()->HasSessionResult);
}
catch ( SoapFault $fault ) {
$login = true;
}
}
if( $login ){
$result = ($temp = $authentication->Login($params));
// set the session id for next time we call this page
$_SESSION['ASP.NET_SessionId'] = $result->LoginResult;
// each seperate webservice need the cookie set
$authentication->__setCookie("ASP.NET_SessionId", $_SESSION['ASP.NET_SessionId']);
// throw an error if the login is unsuccessful
if($authentication->HasSession()->HasSessionResult == false)
throw new SoapFault("0", "Invalid credential information.");
}
My code is the following:
AuthenticateLocator al = new AuthenticateLocator();
al.setMaintainSession(true);
Credential c = new Credential(CredentialType.Community,username,password,guid);
AuthenticateSoap s = al.getAuthenticateSoap();
String sessionId = s.login(c);
System.out.println("Session id was: "+sessionId);
System.out.println("Has Session: "+s.hasSession()); //Hooray, now works after setMaintainSession(true)
//And now trying to call another Service
CompanyServiceLocator cl = new CompanyServiceLocator();
cl.setMaintainSession(true);
CompanyServiceSoap css = cl.getCompanyServiceSoap();
css.getCountryList(); //FAILS!
So what can I do to make this work?
Hooray, I finally solved it myself :-D
Thanx a lot to the excellent article at http://www.nsftools.com/stubby/ApacheAxisClientTips.htm
I had to do the following with my code to make it work:
CompanyServiceLocator cl = new CompanyServiceLocator();
cl.setMaintainSession(true);
CompanyServiceSoap css = cl.getCompanyServiceSoap();
((Stub)css)._setProperty(HTTPConstants.HEADER_COOKIE, "ASP.NET_SessionId="+sessionId); //New line that does the magic
css.getCountryList(); //SUCCESS :-D
Operating in the high-level abstraction of the autogenerated classes, it was unknown to me that casting the service classes to Stub would expose more methods and properties that could be set. Good to know for later I guess :-)