Printing the body of a message - java

I am trying to make a program that will neatly print all the bodies of the messages of my inbox yet exchange web services is making it difficult. I seem to have easy access to everything except the body of the message. This is what I'm doing right now
static final int SIZE = 10;
public static void main(String [] args) throws Exception {
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
ExchangeCredentials credentials = new WebCredentials("USERNAME","PASS");
service.setCredentials(credentials);
service.setUrl(new URI("https://MY_DOMAIN/ews/exchange.asmx"));
ItemView view = new ItemView (SIZE);
FindItemsResults<Item> findResults = service.findItems(WellKnownFolderName.Inbox, view);
System.out.println(findResults.getItems().size() + "Messages");
for (int i = 0; i < SIZE; ++i) {
try {
Item item = findResults.getItems().get(i);
System.out.println("SUBJECT: " + item.getSubject());
System.out.println("TO: " + item.getDisplayTo());
System.out.println("BODY: " + item.getBody().toString());
} catch (IndexOutOfBoundsException e) {
break;
}
}
Of course, I have my credentials and domain filled out fittingly for my code. When I run this I get this message though.
Exception in thread "main" microsoft.exchange.webservices.data.ServiceObjectPropertyException: You must load or assign this property before you can read its value.
at microsoft.exchange.webservices.data.PropertyBag.getPropertyValueOrException(Unknown Source)
at microsoft.exchange.webservices.data.PropertyBag.getObjectFromPropertyDefinition(Unknown Source)
at microsoft.exchange.webservices.data.Item.getBody(Unknown Source)
at Main.main(Main.java:26)
Line 26 is the line where I try to print the body. What am I doing wrong?

The FindItem operation doesn't return the Body of a Message so you need to make a separate GetItem Request to the server to get this. In the Managed API you should be able to use Load method to do this so just change
Item item = findResults.getItems().get(i);
item.Load()
Cheers
Glen

I've figured it out actually. It looks like ExchangeService will close the connection after it is done pulling the needed info. to fix this I made a function
private static ExchangeService getService() throws Exception {
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010);
ExchangeCredentials credentials = new WebCredentials("USERNAME","PASS");
service.setCredentials(credentials);
service.setUrl(new URI("DOMAIN"));
return service;
}
I then call load like so
getService().loadPropertiesForItems(findResults, itempropertyset);
Where I define itempropertyset as such
PropertySet itempropertyset = new PropertySet(BasePropertySet.FirstClassProperties);
itempropertyset.setRequestedBodyType(BodyType.Text);
view.setPropertySet(itempropertyset);

Related

Spring Boot Thymeleaf JavaMail -"class path resource [images/logo.png] cannot be opened because it does not exist " with streams.foreach

I am using Spring Boot and Thymeleaf to send emails. I have one inline image as a signature in the email. Everything works fine if I send one email at a time. But, my use case is to send an individual email to a list of recipients. I am able to do that without the image. But, when I add the image, the first email is getting sent and for the second time I get class path resource [images/tp-logo.png] cannot be opened because it does not exist.
When I call emailService.send() from the stream.forEach() I get above error.
When I call it from a normal for loop, it works fine.
I understand that the streams are lazy, but why the resource is missing?
Working Caller method code:
for(ContactIfo contact : contactInfoList) {
ExecutorService emailExecutor = Executors.newCachedThreadPool();
emailExecutor.execute(() -> {
final String emailAddress = contact.getEmailAddress();
if (StringUtils.isNotBlank(emailAddress)) {
emailService.sendEmail(emailAddress);
}
});
}
Failing caller method code:
contactInfoList.parallelStream().forEach(contact -> {
ExecutorService emailExecutor = Executors.newCachedThreadPool();
emailExecutor.execute(() -> {
final String emailAddress = contact.getEmailAddress();
if (StringUtils.isNotBlank(emailAddress)) {
emailService.sendEmail(emailAddress);
}
});
});
Callee:
private void sendEmail(Mail mail) throws MessagingException {
MimeMessage message = emailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
StandardCharsets.UTF_8.name());
Context context = new Context();
context.setVariables(mail.getProps());
String html = templateEngine.process("me-event-update-template", context);
helper.setText(html , true);
helper.setTo(mail.getMailTo());
helper.setSubject(mail.getSubject());
helper.setFrom(mail.getFrom());
// adding inline resources with matching cId to the variable name/value
helper.addInline("logo", new ClassPathResource("images/logo.png"), "image/png");
emailSender.send(message);
}

YouTube API v3 Not Displaying Exceptions

I just started using YouTube API for Java and I'm having a tough time trying to figure out why things don't work since exception/stack trace is no where to be found. What I'm trying to do is to get list of videos uploaded by current user.
GoogleTokenResponse tokenFromExchange = new GoogleTokenResponse();
tokenFromExchange.setAccessToken(accessToken);
GoogleCredential credential = new GoogleCredential.Builder().setJsonFactory(JSON_FACTORY).setTransport(TRANSPORT).build();
credential.setFromTokenResponse(tokenFromExchange);
YouTube.Channels.List channelRequest = youtube.channels().list("contentDetails");
channelRequest.setMine(true);
channelRequest.setFields("items/contentDetails,nextPageToken,pageInfo");
ChannelListResponse channelResult = channelRequest.execute();
I don't see anything wrong with this code and also tried removing multiple things, but still not able to get it to work. Please let me know if you have run into a similar issue. The version of client library I'm using is v3-rev110-1.18.0-rc.
YouTube API has some working code and you can use it.
public static YouTubeService service;
public static String USER_FEED = "http://gdata.youtube.com/feeds/api/users/";
public static String CLIENT_ID = "...";
public static String DEVELOPER_KEY = "...";
public static int getVideoCountOf(String uploader) {
try {
service = new YouTubeService(CLIENT_ID, DEVELOPER_KEY);
String uploader = "UCK-H1e0S8jg-8qoqQ5N8jvw"; // sample user
String feedUrl = USER_FEED + uploader + "/uploads";
VideoFeed videoFeed = service.getFeed(new URL(feedUrl), VideoFeed.class);
return videoFeed.getTotalResults();
} catch (Exception ex) {
Logger.getLogger(YouTubeCore.class.getName()).log(Level.SEVERE, null, ex);
}
return 0;
}
This simple give you the number of videos a user has. You can read through videoFeed using printEntireVideoFeed prepared on their api page.

Using kSoap on Android to retrieve data, works on the first execution but return null on subsequent execution

I am working on an Android application which allow user to write feedback and then the articleID, ticketID and ticketnumber of the user will be generated by the server and be returned to the user.
There are two activity in this application. MainActivity allow the user to enter their details and a submit button will start Process activity that will send the details to the server and shows the articleID, ticketID and ticketnumber that are returned.
The problem is, it will only work once every time the application is started. For example, a user open the application and enter his details, the submit button is pressed and the corresponding articleID, ticketID and ticketnumber are returned. Then he tries to submit a second one by returning to the previous activity. He enters his detail again and press submit. This time, null is returned.
Images of example is shown here http://imgur.com/a/uY6gR
However, the application works again if it is quitted and the RAM is cleared.
I tried to use this method here to restart the application but still it did not work.
Below is the kSoap code in the Process activity.
public class Process extends Activity{
private String URL = " /*WORKING URL*/";
private String NAMESPACE = "/*WORKING URL*/";
private String soapUsername = "/*WORKING USERNAME*/";
private String soapPass = "/*WORKING PASSWORD*/";
private String METHOD_NAME = "TicketCreate";
private String SOAP_ACTION = "/*WORKING URL*/";
private Handler handler = new Handler();
private Thread thread;
TextView emailT, subjectT, complaintT, responseT, nameT;
String email, subject, complaint, name;
String articleid , ticketid ,ticketnumber;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.process);
webservice();
nameT = (TextView) findViewById(R.id.name);
emailT = (TextView) findViewById(R.id.email);
subjectT = (TextView) findViewById(R.id.subject);
complaintT = (TextView) findViewById(R.id.complaint);
responseT = (TextView) findViewById(R.id.responsevalue);
Intent i = getIntent();
// Receiving the Data
name = i.getStringExtra("name");
email = i.getStringExtra("email");
subject = i.getStringExtra("subject");
complaint = i.getStringExtra("complaint");
// Displaying Received data
nameT.setText(name);
emailT.setText(email);
subjectT.setText(subject);
complaintT.setText(complaint);
Button fin= (Button)findViewById(R.id.finish);
fin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
}
public void webservice(){
thread = new Thread(){
public void run(){
try
{
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
// Set all input params
request.addProperty("UserLogin", soapUsername);
request.addProperty("Password", soapPass);
Hashtable<String, String> ticket = new Hashtable<String, String>();
ticket.put("Title", subject);
ticket.put("CustomerUser", email);
ticket.put("CustomerID", "soapwebnologin");
ticket.put("QueueID", "3");
ticket.put("State", "new");
ticket.put("PriorityID", "1");
ticket.put("Lock", "unlock");
ticket.put("OwnerID", "1");
request.addProperty("Ticket", ticket);
Hashtable<String, String> article = new Hashtable<String, String>();
article.put("Subject", subject);
article.put("Body", complaint);
article.put("ContentType", "text/plain; charset=utf8");
request.addProperty("Article", article);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
new MarshalHashtable().register(envelope);
envelope.dotNet = true;
envelope.bodyOut = request;
String check = checkSSL(URL);
if(check == "SSL"){
KeepAliveHttpsTransportSE httpT = new KeepAliveHttpsTransportSE("/*WORKING URL*/", /*WORKING PORT*/, METHOD_NAME, 15000);
httpT.debug = true;
httpT.call(SOAP_ACTION, envelope);
KvmSerializable ks = (KvmSerializable)envelope.bodyIn;
articleid = ks.getProperty(0).toString();
ticketid = ks.getProperty(1).toString();
ticketnumber = ks.getProperty(2).toString();
Log.e("dump Request: " ,httpT.requestDump);
Log.e("dump response: " ,httpT.responseDump);
Log.e("object response : ", ks.toString());
}
else{
HttpTransportSE httpT = new HttpTransportSE(URL);
httpT.debug = true;
httpT.call(SOAP_ACTION, envelope);
KvmSerializable ks = (KvmSerializable)envelope.bodyIn;
articleid = ks.getProperty(0).toString();
ticketid = ks.getProperty(1).toString();
ticketnumber = ks.getProperty(2).toString();
Log.e("dump Request: " ,httpT.requestDump);
Log.e("dump response: " ,httpT.responseDump);
Log.e("object response : ", ks.toString());
}
}
catch(Exception e)
{
e.printStackTrace();
}
handler.post(createUI);
}
};
thread.start();
}
final Runnable createUI = new Runnable() {
public void run(){
responseT.setText("Your ticket id =" + ticketid+ " Article id ="+ articleid+" TICKET NUMBER ="+ ticketnumber);
}
};
protected String checkSSL(String url){
String https = url.substring(0, 4);
if(https == "https"){
return "SSL";
}
else{
return "noSSL";
}
}
}
EDIT: When I rotate the the screen, it requested another ticket from the server and it actually works. I am so confused.
Apparently it is a bug which can be fixed by adding this line:
System.setProperty("http.keepAlive", "false");
I ran into an Android OS bug recently that is pretty harsh related to
HTTPS connections. Basically, what happens is this:
You want to setup a connection between the phone and a server, and you need to control both the input and the output. As a result, you
use URL.openConnection(), with setDoInput() and setDoOutput() set to
true:
URL url = new URL("https://blahblahblah.com"); URLConnection conn =
url.openConnection(); conn.setDoInput(true); conn.setDoOutput(true);
At some point you use both conn.getOutputStream() to write to the
stream, then conn.getInputStream() to get the response.
You're doing an HTTPS connection. Some people report this happening on normal HTTP, but I've only seen it happen on HTTPS.
The first request goes through fine and dandy.
The second time you try to make the request, the connection doesn't send any data out and doesn't receive any data; it looks like it
happens instantly. If you cast to an HttpURLConnection,
conn.getResponseCode() returns -1 instead of anything meaningful.
In other words, every other request, the request fails outright. This
is a noted bug in Android, but it isn't fixed yet in any released
versions. Even when it's fixed, you'll still have to deal with this on
older versions of Android.
There are a few workarounds. The first is to simply not use
URLConnection; if you can find some way around it, avoid it. The
second is to repeatedly make the same request until it works; it's a
little too much of a hack for my tastes, but it'll work.
Then there's the third workaround, which I do not claim to understand
why it fixes the issue but it does. Just set this setting when your
application begins:
System.setProperty("http.keepAlive", "false");
Unfortunately this has some drawbacks (keep-alive is a good thing
normally), but in comparison to mysteriously failed requests I'll
ditch it.
Source: http://daniel-codes.blogspot.com/2010_07_01_archive.html
And regarding the problems with orientation change, read here
Change screen orientation in Android without reloading the activity

webservice client implementaion in axis2-1.6.2 in java

I have implemented webservice client in axis2-1.6.2 in java and I get response when I call first time and for subsequent second time I get below error
java.lang.NullPointerException
at org.apache.axis2.client.OperationClient.prepareMessageContext(OperationClient.java:293)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:180)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
at org.apache.axis2.ccws.CustomerCareServiceStub.subscriberRetrieveLite(CustomerCareServiceStub.java:2380)
at Prepost.SubscriberRetrieveBalance.subscriberRetrieveLite(SubscriberRetrieveBalance.java:111)
at Prepost.CheckUser.doGet(CheckUser.java:149)
here is the API implementation class constructor which sets unique parameter which is same for all requests
public SubscriberRetrieveBalance(String url, String strCON_TimeOut, String strSO_TimeOut) {
try {
this.url = url;
stub = new CustomerCareServiceStub(url);
ServiceClient sClient = stub._getServiceClient();
Options options = sClient.getOptions();
options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Constants.VALUE_TRUE);
options.setProperty(AddressingConstants.WS_ADDRESSING_VERSION, AddressingConstants.Submission.WSA_NAMESPACE);
//options.setTimeOutInMilliSeconds(2000);
TransportInDescription transportIn = new TransportInDescription("HTTP");
options.setTransportIn(transportIn);
options.setProperty(HTTPConstants.SO_TIMEOUT, Integer.parseInt(strSO_TimeOut));
options.setProperty(HTTPConstants.CONNECTION_TIMEOUT, Integer.parseInt(strCON_TimeOut));
sClient.setOptions(options);
} catch (Exception e) {
if (e.getMessage().equals("Can not find the external id")) {
System.out.println("Exception ::" + e.getMessage());
}
}
}
and it is called in a servlet and for performance issue I make object of this class for different-2 states(urls) and saved these object to hashmap when first request comes for respective states then make new object and use that object for subsequent requests for that state
SubscriberRetrieveBalance objBal = null;
BalanceBean bal = new BalanceBean();
if (mapObj.isEmpty() || (mapObj.get(strIP) == null)) {
objBal = new SubscriberRetrieveBalance(url, strCON_TimeOut, strSO_TimeOut);
mapObj.put(strIP, objBal);
} else {
objBal = mapObj.get(strIP);
}
bal = objBal.subscriberRetrieveLite(strMsisdn, userId, token, strCircleId, strCircleName, strSessionId, strDlgId);
first time it gives response and then gives nullpointer exception and above error for all requests that belongs to that state
This code is working fine with axis2-1.5
Is there any change in axis2-1.6.2 version that every time it needs new object of API implemented class
Please suggest.

How to connect facebook with java desktop application

I need to connect and authenticate users from java desk top application , i have tried facebook-java-api using facebookjsonclient and facebookRestclient but not able to get session key. is there any changes in facebook due to which we r not able to connect , or is there asny other best java api or example how to connect. my code is
private static void getUserID(String email, String password){
String session = null;
try {
HttpClient http = new HttpClient();
http.getHostConfiguration().setHost("www.facebook.com");
String api_key = "key";
String secret = "sec";
FacebookJaxbRestClient client = new FacebookJaxbRestClient(api_key, secret);
System.out.println("====>"+client.isDesktop());
String token = client.auth_createToken();
System.out.println(" :::::::"+token);
System.out.println(" :::::::::: "+token);
PostMethod post = new PostMethod("/login.php?");
post.addParameter("api_key", api_key);
post.addParameter("email", email);
post.addParameter("pass", password);
int postStatus = http.executeMethod(post);
System.out.println("url : " + post.getURI());
System.out.println("Response : " + postStatus);
for (Header h : post.getResponseHeaders()) {
System.out.println(h);
}
session = client.auth_getSession(token); // Here I am getting error
System.out.println("Session string: " + session);
long userid = client.users_getLoggedInUser();
//System.out.println("User Id is : " + userid);*/
} catch (FacebookException fe) {
fe.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
AFAIK , there is no way as of now to connect to facebook from a "desktop app" in a straight forward way. You can use apache http client library to mimick a browser and get it done. But it cannot be guranteed to work always.I have also been trying to do it for sometime with some libraries,but they seem broken.
I've had some success doing this. My approach was to use an embedded browser to display the authentication to the user. Facebook handles the authentication and redirects you to a "login successful" page with the access token and expiration time tacked onto the URL as GET data. Most of the code below is for creating and displaying the browser using the org.eclipse.swt library.
private static final String APP_ID = "###########";
private static final String PERMISSIONS =
"COMMA SEPARATED LIST OF REQUESTED PERMISSIONS";
private String access_token;
private long expirationTimeMillis;
/**
* Implements facebook's authentication flow to obtain an access token. This
* method displays an embedded browser and defers to facebook to obtain the
* user's credentials.
* According to facebook, the request as we make it here should return a
* token that is valid for 60 days. That means this method should be called
* once every sixty days.
*/
private void authenticationFlow() {
Display display = new Display();
Shell shell = new Shell(display);
final Browser browser;
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
shell.setLayout(gridLayout);
try {
browser = new Browser(shell, SWT.NONE);
} catch (SWTError e){
System.err.println("Could not instantiate Browser: " + e.getMessage());
display.dispose();
display = null;
return;
}
browser.setJavascriptEnabled(true);
GridData data = new GridData();
data.horizontalAlignment = GridData.FILL;
data.verticalAlignment = GridData.FILL;
data.horizontalSpan = 3;
data.grabExcessHorizontalSpace = true;
data.grabExcessVerticalSpace = true;
browser.setLayoutData(data);
final ProgressBar progressBar = new ProgressBar(shell, SWT.MOZILLA);
data = new GridData();
data.horizontalAlignment = GridData.END;
progressBar.setLayoutData(data);
/* Event Handling */
browser.addProgressListener(new ProgressListener(){
public void changed(ProgressEvent event){
if(event.total == 0) return;
int ratio = event.current * 100 / event.total;
progressBar.setSelection(ratio);
}
public void completed(ProgressEvent event) {
progressBar.setSelection(0);
}
});
browser.addLocationListener(new LocationListener(){
public void changed(LocationEvent e){
// Grab the token if the browser has been redirected to
// the login_success page
String s = e.location;
String token_identifier = "access_token=";
if(s.contains("https://www.facebook.com/connect/login_success.html#access_token=")){
access_token = s.substring(s.lastIndexOf(token_identifier)+token_identifier.length(),s.lastIndexOf('&'));
String expires_in = s.substring(s.lastIndexOf('=')+1);
expirationTimeMillis = System.currentTimeMillis() + (Integer.parseInt(expires_in) * 1000);
}
}
public void changing(LocationEvent e){}
});
if(display != null){
shell.open();
browser.setUrl("https://www.facebook.com/dialog/oauth?"
+ "client_id=" + APP_ID
+ "&redirect_uri=https://www.facebook.com/connect/login_success.html"
+ "&scope=" + PERMISSIONS
+ "&response_type=token");
while(!shell.isDisposed()) {
if(!display.readAndDispatch()){
display.sleep();
if(access_token != null && !access_token.isEmpty()){
try{ Thread.sleep(3000);}catch(Exception e){}
shell.dispose();
}
}
}
display.dispose();
}
}
So all you have to do is figure out what permissions you're going to need to have for your application to work. Be aware that "second dialog" permissions can be picked from by the user so there is no guarantee that you will actually have these permissions.
First off, you need to get the access_token and then I would recommend using restfb library. In order to get the token I would recommend reading this: https://developers.facebook.com/docs/authentication/
A simple summary:
HTTP GET: https://www.facebook.com/dialog/oauth?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream&
response_type=token
Use the code you get from above and then, do: https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE
Exact the access_token and use FacebookClient from restfb to make the API requests.

Categories