Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
Repo info
@serious6 Can we use this to send email using Non-Microsoft Server?
Hi, can anyone help me please...
I have implemented a Liferay calendar portlet. I have started with ews-java-api 2.0. For testing, I gave always username/password as Hard-Code in my Code.
and Now I want to test it with signed in Liferay user. The problem is that Liferay gives me only the username and the encrypted password.
How can I do ews-authentication without forcing user to login again?
Amit Joshi
We have built a basic javax-mail provider for EWS using the EWS API and were looking to opensource it
Seemed like putting it with the ews-java api would be the best spot. Wanted to check if the OfficeDev team would be willing to host it?
Hello to all. Who can explane how to subscribe to pull notifications to Calendar folder?
Jose Carlos

@retor I did that a while ago, but maybe it helps you.

Subscribe to pull events:

        List  folder = new ArrayList();
        folder.add(new FolderId().getFolderIdFromWellKnownFolderName(WellKnownFolderName.Calendar));

        PullSubscription subscription = ExchangeClient.getExchangeService().subscribeToPullNotifications(folder,5, /* timeOut: the subscription will end if the server is not polled within 5 minutes. */
                null, /* watermark: null to start a new subscription. */

        LOG.info("Subscription successful Id: ! "+subscription.getId() + " - Watermark: ! "+subscription.getWaterMark());
        LOG.info("Starting thread...");
        new Thread(new RetrieveEvents(subscription)).start();

RetrieveEvents thread:

    public void run() {
        LOG.info("Thread started!");
        try {
            sleep (60000);
            LOG.info("Awake! Let's check the events!");
            // Wait a couple minutes, then poll the server for new events.
            GetEventsResults events = subscription.getEvents();

            if (events != null && events.getItemEvents() != null && events.getAllEvents().size() > 0) {
                // Loop through all item-related events.
                for (ItemEvent itemEvent : events.getItemEvents()) {
                    LOG.info("itemEvent id: " + itemEvent.getItemId());
            else {
                LOG.info("No result! :(");
        catch (Exception e) {
            LOG.error("Exception", e);
@josecyn thanks. Tomorrow I understand how to do it. And I do it on RxJava.
Here subscription is an object on server, what store updates and I can retrieve any updates from them.
Sorry for my English. Yesterday not tomorrow)))))
Gervais Blaise
Hello there. Sorry to disrupt but I'm wondering if there is some way to search for all Tasks in one mailbox.
I can get some tasks form the WellKnownFolerName.Tasks but I have some task created form mails but cannot find them.
Gervais Blaise
At this time I'm able to get tasks from WellKnownFolderName.Tasks and I was able to get all EmailMessage from WellKnownFolderName.Inbox that have the follow-up flag via one extended property: new ExtendedPropertyDefinition(0x1090, MapiPropertyType.Integer)
Jatinder Malik
Hello Guys, not sure if this question has been asked before - I am trying to use this API and create a Java REST micro service using this which can work with user calendars .. but I don't want the web client to pass me users username and password and instead used windows SSO authentication and pass me the token (NTLM maybe) which I can use in microservice to connect to exchange using ews java API - do you think the same is possible? Are there any references you can point me to using which I can build this scenario locally?
Hello Guys,
I am working on a project and need some help with the java api. I need "Add and remove email addresses from the Blocked Senders List by using EWS in Exchange" as mentioned in this link
Any idea's? Appreciate your time.
Hello Guys
Domenic Datti
I don't know if anyone uses this room for support 😐

hello guys, im using push notification subscribe :

System.out.println("START MAIL EXCHANGE");
            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
            service.setUrl(new URI("https://outlook.office365.com/EWS/Exchange.asmx"));
            ExchangeCredentials credentials = new WebCredentials(username, passworrd, "outlook.office365.com");

            URI uri = new URI("http://localhost:8087/api/mail");

            WellKnownFolderName wkFolder = WellKnownFolderName.Inbox;
            FolderId folderId = new FolderId(wkFolder);
            List<FolderId> folder = new ArrayList<FolderId>();
            PushSubscription subscription = service.subscribeToPushNotifications(
                folder, uri , 1, null,
                EventType.NewMail, EventType.Created, EventType.Deleted, EventType.Modified, EventType.Moved);
            /*IAsyncResult result = service.beginSubscribeToPushNotifications(null, null, folder, uri, 1, null, EventType.NewMail, EventType.Created, EventType.Deleted);
            PushSubscription subscription1 = service.endSubscribeToPushNotifications(result);*/
            System.out.println("END MAIL EXCHANGE");
        } catch (Exception e) {
            System.out.println("EXCEPTION MAIL EXCHANGE");

Then my Listener :
@PostMapping(value = "/mail", consumes = MediaType.TEXT_XML_VALUE)
public void mailExchange(HttpServletRequest request, HttpServletResponse response){
log.debug("---------- MAIL_EXCHANGE_LISTERNER SUECCESS ----------");

i set break point in log.debug("---------- MAIL_EXCHANGE_LISTERNER SUECCESS ----------"); .when i sent email nothings happens. please help me
Pavel Kropachev
It's too late... But in any way, it's quite strange to wait for some events on the endpoint "localhost".

hello guys Im new to the use of ews-java-API. when i try to get inbox folder i get this error.
microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. An element node 'soap:Envelope' of the type START_ELEMENT was expected, but node '{http://schemas.xmlsoap.org/wsdl/}definitions' of type START_ELEMENT was found.

please help me

Pavel Kropachev
Could you show your piece of code and SOAP request that is sent to server?
How are you setting the URL of the service?
I try only to get inbox item count with this code
public class EwsService extends AbstractService {

    private ExchangeService service;

    public EwsService() {
            this.service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);


     * Open a ews connection and return number of inbox's item
     * @return INBOX item
     * @throws Exception
    public String testService() throws Exception {
        try {
            service.setCredentials(new WebCredentials("username@domain.com", "password", "domain.com"));
            service.setUrl(new URI("https://xxxxxxxxxxxxxxxxxx.com/ews/Exchange.asmx"));
            Folder inbox = new Folder(this.service);
            inbox = Folder.bind(service, WellKnownFolderName.Inbox);
            return new StringBuilder("INBOX (").append(inbox.getTotalCount()).append(")").toString();

        } catch (Exception e) {
            this.getLogger().warn("Error occured ", e);
        return "{error}";

Pavel Kropachev

You can join declaration and assignment for 'inbox' variable.

Folder inbox = Folder.bind(this.service, WellKnownFolderName.Inbox);

Instead of:

Folder inbox = new Folder(this.service);
inbox = Folder.bind(this.service, WellKnownFolderName.Inbox);

Your code works in my case, I use Office 365.


<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <t:RequestServerVersion Version="Exchange2010_SP2"/>
                <t:DistinguishedFolderId Id="inbox"/>

And EwsResponse:

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
        <h:ServerVersionInfo MajorBuildNumber="1294" MajorVersion="15" MinorBuildNumber="46" MinorVersion="20" Version="V2018_01_08" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
        <m:GetFolderResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                <m:GetFolderResponseMessage ResponseClass="Success">
                            <t:FolderId ChangeKey="AQAAABYAAABomMeTjbKLT4eZwT5LFu4VAAB18/r8" Id="AQMkADk1ZWNmODVkLWE0YmMtNGQ1Ni1hYzQ3LWYxZmFlMmFhADQ1NzYALgAAA+DspbZlAwZNth3fVoDGeR8BAGiYx5ONsotPh5nBPksW7hUAAAIBDAAAAA=="/>
                            <t:ParentFolderId ChangeKey="AQAAAA==" Id="AQMkADk1ZWNmODVkLWE0YmMtNGQ1Ni1hYzQ3LWYxZmFlMmFhADQ1NzYALgAAA+DspbZlAwZNth3fVoDGeR8BAGiYx5ONsotPh5nBPksW7hUAAAIBCAAAAA=="/>
Do you use on-premise Exchange server? Could you capture raw SOAP?
Just add the following code before use the ExchangeService:
            this.service.setTraceListener(new ITraceListener() {
                public void trace(String type, String message) {
                    System.out.println("Type: " + type + "\nMessage: " + message);
Hello thanks, after join declaration and assignment for 'inbox' variable and adding trace code , i got this:
Type: EwsRequestHttpHeaders
Message: <Trace Tag="EwsRequestHttpHeaders" Tid="16" Time="2018-11-19 13:15:20Z">
POST /ews/Exchange.asmx HTTP/1.1
Keep-Alive : 300
Content-type : text/xml; charset=utf-8
Accept : text/xml
User-Agent : ExchangeServicesClient/
Connection : Keep-Alive
Accept-Encoding : gzip,deflate


Type: EwsRequest
Message: <Trace Tag="EwsRequest" Tid="16" Time="2018-11-19 13:15:20Z">
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"><soap:Header><t:RequestServerVersion Version="Exchange2010_SP2"></t:RequestServerVersion></soap:Header><soap:Body><m:GetFolder><m:FolderShape><t:BaseShape>AllProperties</t:BaseShape></m:FolderShape><m:FolderIds><t:DistinguishedFolderId Id="inbox"></t:DistinguishedFolderId></m:FolderIds></m:GetFolder></soap:Body></soap:Envelope>

13:15:21.153 [http-nio-8080-exec-1] WARN  c.o.s.e.a.s.EwsService - Error occured 
microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException: The request failed. The request failed. Certificate for <domaine.com> doesn't match any of the subject alternative names: [webmail.xxxxx.com, mail.xxxxx.com, autodiscover.xxxxx.com]
    at microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:74)
and my test service
public String testService() {
        try {
            ExchangeCredentials credentials = new WebCredentials("*********@***********.com", "********!");
            this.service.setUrl(new URI("https://********************.com/ews/Exchange.asmx"));
            this.service.setTraceListener(new ITraceListener() {
                public void trace(String type, String message) {
                    System.out.println("Type: " + type + "\nMessage: " + message);

            Folder inbox = Folder.bind(this.service, WellKnownFolderName.Inbox);
            return new StringBuilder("INBOX (").append(inbox.getTotalCount()).append(")").toString();

        } catch (Exception e) {
            this.getLogger().warn("Error occured ", e);
        return "error";
Pavel Kropachev
EWS SOAP request is correct.
Looks like that hostname which you use to connect to EWS is not included to certificate of your Exchange server. In the result, verification of this hostname is failed.
You can use one of the subject alternative names from certificate to connect, e.g. "https://webmail.xxxxx.com/EWS/Exchange.asmx", "https://mail.xxxxx.com/EWS/Exchange.asmx".
Or use custom service (with non-default hostname verifier) to ignore verification of hostname (in fact, allow all hosts).
Thank you now its works.
I customize the Exchange services and switch off hostname verification. So i have a question
To understand better, what is the disadvantage to override hostname verifier
Pavel Kropachev
Your application will accept invalid and wildcard certificates. This may be acceptable for testing and/or usage inside intranet, but not for production and public usage. One of the way is add option in your application to ignore verification of hostname.
If you requested certificate for your Exchange server from Certificate Authority provider then just request issue a certificate with additional subject alternative names that are used by your server.
If you're using your own Certificate Services in AD then just issue a new certificate for your Exchange server.
Thank you I appreciate your help

I come back with a new question.
I try to resolve a Name using

NameResolutionCollection response = this.service.resolveName(name, ResolveNameSearchLocation.DirectoryThenContacts, true);

Is there a way to return more than the 100 as provided by the documentation ?
Thank you

Pavel Kropachev
As far as I know limit (100 items) in ResolveNames is a hard limit and it can't be changed.
You should make request with more precise name to decrease number of items. Maybe something wrong in your business logic if you receive more than 100 results on one request.
I am not able to fetch InternetMessageHeader for the Mails in SentItems
Is there a way to fetch the emails
And I have one more query... Is there any easy way to fetch emails across nested subfolders in Inbox
Pavel Kropachev
  1. As far as I know, Exchange doesn't store "InternetMessageHeaders" for items in "Sent Items" folder. Headers are added to messages when they go through transport.
  2. Common way of fetching items from subfolders doesn't look difficult. Retrieve all subfolders of "Inbox" folder and then retrieve items for each sub-folders.

Thanks Paval I was able to achieve what I intended. Now I have some queries regarding push notifications. @pkropachev @serious6 @vboctor @ahaarrestad

I have successfully subscribed to push notifications and I have developed a Servlet listener and I am able to receive notifications. But I am not able to parse the XML. HttpServletRequest.getInputStream.available(); always returns value as zero. I am not sure whether I am receiving the right XML. If yes Kindly guide me where I am getting wrong.

Kindly find the below code snippets for your reference

Subscription code

URI callback = new URI(https://vignesh.local.com/msexchange/pushnotification?uniqueKey=b057db49-8238-488c-bebd-7b2e54f9cf31);
PushSubscription pushSubscription = service.subscribeToPushNotificationsOnAllFolders(callback, 1, null,EventType.NewMail,EventType.Created,EventType.Deleted,EventType.Copied,EventType.Modified,EventType.Moved);

MSExchangePushNotificationListener code

public class MSExchangePushNotificationListener extends HttpServlet {

private static final Logger LOGGER = Logger.getLogger(MSExchangePushNotificationListener.class.getName());

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

    try {
        LOGGER.log(Level.WARNING,"------MSExchangePushNotificationListener POST Called----");
        MSExchangePushNotificationDataProcessor dataProcessor = new MSExchangePushNotificationDataProcessor();
        dataProcessor.processData(req, res);
    } catch (Exception exc) {



public void processData(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

InputStream inputStream = req.getInputStream();
      LOGGER.log(Level.INFO,"InputStream value is "+inputStream.available());


anyone around
how do I read the contacts notes in ews
Pavel Kropachev


void retrieveAllContactNotes() {
    try {
        ContactsFolder contactsFolder = ContactsFolder.bind(service, WellKnownFolderName.Contacts);
        ItemView view = new ItemView(contactsFolder.getTotalCount());
        view.setPropertySet(new PropertySet(BasePropertySet.IdOnly));
        FindItemsResults<Item> contactItems = service.findItems(WellKnownFolderName.Contacts, view);

        for (Item item : contactItems) {
            if (item instanceof Contact) {
                Contact contact = (Contact) item;
                contact.load(new PropertySet(ContactSchema.DisplayName, ContactSchema.Body));
                System.out.println("Contact name: " + contact.getDisplayName() + "\nNotes: " + contact.getBody());
    } catch (Exception e) {

See #132.

Pavel Kropachev

Check the documentation for InputStream#available():
"Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream."
"The available method for class InputStream always returns 0."

Actually, available() says how many bytes can be read until read() call will block the execution.

So, just read the text from input stream.

import org.apache.commons.io.IOUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Frontend extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        // TODO

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //String xml = IOUtils.toString(new BufferedReader(new InputStreamReader(request.getInputStream())));
        // or
        String xml = IOUtils.toString(request.getReader());

        String responseXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:m=\"http://schemas.microsoft.com/exchange/services/2006/messages\" xmlns:t=\"http://schemas.microsoft.com/exchange/services/2006/types\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
                "   <soap:Body>\n" +
                "      <m:SendNotificationResult>\n" +
                "         <m:SubscriptionStatus>OK</m:SubscriptionStatus>\n" +
                "      </m:SendNotificationResult>\n" +
                "   </soap:Body>\n" +

        byte[] bytes = responseXml.getBytes("UTF-8");
        ServletOutputStream out = response.getOutputStream();
        out.write(bytes, 0, bytes.length);

It's better to implement the push notification listener as RESTful Web Service (JAX-RS) or SOAP Web Service (JAX-WS).
Look at Jersey, Apache CXF.

Thank You so much Pavel (y) @pkropachev
gowtham b

Hi @pkropachev

We are trying to create an appointment in EWS. The event has been created successfully.

But the timezone for the event is set as UTC and I am unable to fetch the current user's Timezone.

Is there a way to fetch the timezone of the current user ?

Kindly assist me, if there is any suggestions/workaround from your end.