当前位置: 首页 > 面试题库 >

Exchange Web服务Java APi + RESTful推送通知侦听器

左丘兴生
2023-03-14
问题内容

我想让我的监听器使用ews java API,但我做不到。.希望您能对我有所帮助!

我已完成以下步骤:

1)连接到交换网络服务

    ExchangeService newService = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
    newService.setUrl("https://myurl/ews/Exchange.asmx");
    ExchangeCredentials credentials = new WebCredentials("user","password");
    newService.setCredentials(credentials);

2)然后订阅推送通知:

@Override
public PushSubscription subscribeToPushNotifications(){

    URI callback = null;
    PushSubscription pushSubscription = null;
    try{
        logger.info("Subscribing to push notifications.. Endpoint Listener URI = " + config.getNotificationListenerURI());
        callback = new URI(config.getNotificationListenerURI());
        pushSubscription = service.subscribeToPushNotifications(
                getFoldersForSubscription(), callback , 5, null, 
                EventType.NewMail, EventType.Created, EventType.Deleted, EventType.Modified, EventType.Moved); 
        logger.info("Done! --> PushSubscription ID= " + pushSubscription.getId());
    }catch(URISyntaxException e){
        logger.error("EWS ==> Invalid Notification Listener URL = " + config.getNotificationListenerURI() +". Please, verify <integration-modules>");
        Throwables.propagate(e);
    }catch (Exception e){
        logger.error("EWS ==> Error subscribing to push notifications", e);
        Throwables.propagate(e);
    }

    return pushSubscription;
}

3)然后将我的侦听器开发为一种Restful Web服务(我已经使用虚拟方法进行了测试,并且可以正常工作)

首先定义servlet:

<servlet>
    <servlet-name>jersey-serlvet</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>  
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.rest</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>jersey-serlvet</servlet-name> 
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

之后,创建Listener类以映射servlet中定义的url(我传递给ExchangeService的那个)

@Path("/emailnotification")
public class ExchangeNotificationListener {

    private static final Log logger = LogFactory.getLog(ExchangeNotificationListener.class);

    @Path("/incomingevent")
    @POST()
    @Produces(MediaType.TEXT_XML)
    public Response onNotificationReceived() throws Exception {
        logger.info("Received EWS notification !!!");
    return Response.ok().build();
    }

    @GET
    @Path("/{param}")
    public Response getMsg(@PathParam("param") String msg) {
        String output = "Jersey say : " + msg;
        return Response.status(200).entity(output).build();
    }
}

但是我设置了断点,然后给我发送了一封电子邮件,但是什么都没有发生。请帮忙 !

PS:虚拟方法getMsg()起作用,因此其余服务正在起作用

提前致谢 !!


问题答案:

问题是防火墙阻止传入的EWS消息进入我的开发环境。

这是侦听器的最终版本。我希望有人能发现它有用

@Path("/emailnotification")
public class ExchangeNotificationListener {

private static final Log logger = LogFactory.getLog(ExchangeNotificationListener.class);
private static final String OK = "OK";
private static final String UNSUBSCRIBE = "Unsubscribe";

/**
 * This method receives a SOAP message from Microsoft Exchange Web Services, parses it into a ExchangeNotification object,
 * do some business logic and sends an ACK response to keep the subscription alive.
 * 
 * @param request
 *            EWS Push Notification request
 * @param response
 * @throws Exception
 */
@Path("/incomingevent")
@POST()
@Consumes(MediaType.TEXT_XML)
public void onNotificationReceived(@Context HttpServletRequest request, @Context HttpServletResponse response)
        throws Exception {

    // Establish the start time so we can report total elapsed time to execute the call later.
    long startTime = GregorianCalendar.getInstance().getTimeInMillis();
    long endTime;

    // Retrieve the EWS Notification message as an XML document
    Document notificationXML = loadXML(IOUtils.toString(request.getInputStream()));

    // Deserialize the document
    ExchangeNotification notif = new ExchangeNotification(notificationXML);

    // We need the subscription id in order to proceed
    String subscriptionId = notif.getSubscriptionId();

    if (isBlank(subscriptionId)) {
        logger.error("SOAP Envelope MUST contains the subscriptionId");
        // If we did not successfully parse the XML document, tell Exchange that we got a bad request.
        response.sendError(HttpServletResponse.SC_BAD_REQUEST);
    }

    if (!ExchangeSubscriptionMap.getInstance().getSubscriptionsMap().containsKey(subscriptionId)) {
        logger.warn("SubscriptionId = " + subscriptionId
                + " was not found in the subscriptions map. Unsubscribing...");
        sendResponse(response, UNSUBSCRIBE);
        return;
    }

    // Do some logic here depending on the current EventType
    businessLogic(notif, response);

    // Flush the buffer and report the total time taken to execute for this notification.
    response.flushBuffer();
    endTime = GregorianCalendar.getInstance().getTimeInMillis();
    logger.debug(String.format("Total execution time: %1$s (ms)", (Long) (endTime - startTime)));
}

/**
 * Sends an ACK response to the Exchange Web Service
 * 
 * @param response
 * @param msg
 *            the content of the response message
 */
private void sendResponse(HttpServletResponse response, String msg) {
    try {
        // Build the HTTP response
        String str = ExchangeUtils.getResponseXML(msg);
        response.setCharacterEncoding("UTF-8");
        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType("text/xml; charset=UTF-8");
        response.setContentLength(str.length());

        // Send the response.
        PrintWriter w = response.getWriter();
        w.print(str);
        w.flush();
    } catch (IOException e) {
        logger.error("Error getting the response writer");
        Throwables.propagate(e);
    }
}

/**
 * Process the incoming notification, do some business logic and send an ACK response to Exchange
 * 
 * @param notification
 *            to be processed
 * @param response
 *            to be returned
 */
@SuppressWarnings("unchecked")
private void businessLogic(ExchangeNotification notification, HttpServletResponse response) {
    try {
        // Iterate the notification events
        for (SubscriptionEvent event : notification.getEvents()) {
            // Only take care of the Modified event
            switch (event.getEventType()) {
            case MODIFIED:
                // logic here
                // Get the ExchangeService instance this user use for Subscribing
                MSExchangeServiceManager service = ExchangeSubscriptionMap.getInstance().getSubscriptionsMap().get(notification.getSubscriptionId()).getService();

               //e.g: service.getUnreadMessages(WellKnownFolderName.Inbox));
                break;
            default:
                logger.debug("Skipping: " + event.getEventType());
                break;
            }
        }

        // Finally, send the response.
        sendResponse(response, OK);

    } catch (Exception e) {
        logger.error("EWS ==> Error processing request", e.getCause());
        Throwables.propagate(e);
    }
}

/**
 * Create a XML Document using a raw xml string
 * 
 * @param rawXML
 *            the raw xml string to be converted
 * @return XML EWS Nofitication document
 */
private Document loadXML(String rawXML) {
    Document doc = null;
    try {
        logger.debug("Incoming request input stream : " + rawXML);

        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();

        // turn on this flag in order to resolve manually the namespaces of the document
        domFactory.setNamespaceAware(true);
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        doc = builder.parse(new InputSource(new ByteArrayInputStream(rawXML.getBytes("UTF-8"))));
    } catch (ParserConfigurationException e) {
        logger.error("Unable to create a new DocumentBuilder");
        Throwables.propagate(e);
    } catch (UnsupportedEncodingException e) {
        logger.error("Unsupported Encoding: UTF-8");
        Throwables.propagate(e);
    } catch (SAXException e) {
        logger.error("Error parsing XML");
        Throwables.propagate(e);
    } catch (IOException e) {
        logger.error("IOException");
        Throwables.propagate(e);
    }
    return doc;
  }
}


 类似资料:
  • 我正在使用新的Firebase平台。我试图让我的应用程序服务器发送消息推送到我的iPhone。 我的设置正在运行,我在网站上的Firebase通知区域手动发送消息,但当我尝试将消息发送到https://fcm.googleapis.com/fcm/send 我没有收到发送到设备的消息。 我正在发送以下内容(带有auth头) 我从POST得到了200个响应,有以下身体: 如果我尝试直接通过Fireb

  • 我在android应用程序中使用nodeJS和mongodb作为后端服务,并使用FCM向用户发送推送通知。为了实现这一点,我在MongoDB上保存了firebase注册令牌。 我想在相应的用户在MongoDb服务器上添加数据时向他们发送推送通知。 这是我在下面添加数据库数据的代码。 现在,一旦数据添加到数据库中,我想向用户发送通知。有人请让我知道如何才能实现所需的任务。任何帮助都将不胜感激。 谢谢

  • 问题内容: 在MySQL中是否有等效于PostgresQL的notify和listen?基本上,我需要在Java应用程序服务器中监听触发器。 问题答案: 不,还没有像这样的内置函数。您需要使用诸如“ read” 0/1之类的预制标志进行选择来“ ping”(每1-5秒)数据库。后 用read = 1更新它

  • 我正在尝试创建一个应用程序,使用新的Android服务来读取所有通知,也可以删除它们,但它并不起作用。在我的舱单上: 我有一个类NotificationListener扩展了NotificationListenerService我重写了两个方法OnNotificationPost(StatusBarNotification sbn)、onNotificationRemoved(StatusBarN

  • 首先,我想声明我一直在研究推送通知和web通知之间的关系,但我有点困惑。 我从这里读到PWAs的推送通知在Safari上的iOS(iPhone)不起作用:从PWA向iOS发送推送通知 然而,如果iPhone用户使用的是Chrome,这是否意味着它们可以工作呢?或者推送通知在任何浏览器上对iPhone中的PWAs都不起作用? 这就把我带到了web通知。web通知在后台对PWAs起作用吗?我的问题是w

  • 假设我的应用程序没有启动,它不在运行状态,或者它在后台。如果有一些烤面包或瓷砖通知收到。和服务器在此推送中发送一些有效负载。我们可以得到当应用程序推出后,推送和我们可以得到这个有效载荷在我们的应用程序。 什么是TTL(生存时间),推送的时间,或者我们可以在我们的有效负载中设置它。