Java client infrastructure / API for calling Windows push notification service

Does anyone know if there is a Java / API client infrastructure to call the Windows Phone Notification Service? I know that there is a JavaPNS project that is specific to Apple PNS. I am looking for something similar to this, but specific to a Windows phone.

Any help?

+4
source share
2 answers

Java-mpns seems to be close to what you are looking for.

https://github.com/notnoop/java-mpns

+2
source

I developed a solution with Spring and the Apache Commons HTTP client to send RAW messages using WNS (Windows Notification Service)

Paste these dependencies into your pom.xml:

<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.2.1</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.12</version> </dependency> 

And the following lines in applicationContext.xml

 <bean class="java.lang.String" id="authenticateUrlPostWNS"> <constructor-arg> <value>https://login.live.com/accesstoken.srf</value> </constructor-arg> </bean> <util:map id="authenticateWNSHeaders"> <entry key="Content-Type" value="application/x-www-form-urlencoded" /> </util:map> <util:map id="authenticateWNSPostParams"> <entry key="grant_type" value="client_credentials" /> <entry key="client_id" value="ms-app://" /> <entry key="client_secret" value="" /> <entry key="scope" value="notify.windows.com" /> </util:map> <util:map id="sendMessageWNSHeaders"> <entry key="X-WNS-Type" value="wns/raw" /> <entry key="Content-Type" value="application/octet-stream" /> <entry key="X-WNS-RequestForStatus" value="true" /> <entry key="X-NotificationClass" value="3" /> </util:map> 

* Remember to fill in client_id and client_secret

In my project, I divided the implementation into four classes, which I will discuss below

OAuthToken is used to store and format the access token:

 public class OAuthToken { private String token; private String tokenType; public OAuthToken(String token, String tokenType) { super(); this.token = token; this.tokenType = tokenType; } public String getAuthorization() { return StringUtils.capitalize(tokenType) + " " + token; } } 

The HttpClientFactory (shown below) is used to create a new client whenever you send a message. If you reuse the same HttpClient to send the message, the WNS timeout after sending the second message. I do not know why this is happening, but it decided when I stopped reusing the client.

 @Service public class HttpClientFactory { private static final int TIMEOUT = 20 * 1000; public HttpClient create() { SystemDefaultHttpClient httpClient = new SystemDefaultHttpClient(); httpClient.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, TIMEOUT); httpClient.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT, TIMEOUT); httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(NumberUtils.INTEGER_ZERO, false)); return httpClient; } } 

This is the base class, according to your desire, you can display all the code on WindowsPushNotificationMediator

 public abstract class AbstractCloudMediator { private static final Logger LOG = Logger.getLogger(AbstractCloudMediator.class.getSimpleName()); @Autowired private HttpClientFactory clientFactory; @Autowired protected ObjectMapper mapper; public abstract boolean sendMessage(Jogador destinatario, Action mensagem); protected String postToString(HttpPost post) throws IOException, ClientProtocolException { HttpResponse response = executeMethod(post); return responseToString(response); } protected String responseToString(HttpResponse response) throws IOException { InputStream conteudoResposta = response.getEntity().getContent(); try { return IOUtils.toString(conteudoResposta); } finally { IOUtils.closeQuietly(conteudoResposta); } } protected HttpResponse executeMethod(HttpPost post) throws IOException, ClientProtocolException { LOG.info("posting to... " + post); return clientFactory.create().execute(post); } } 

The next class should do the bulk of the work, but be sure to create a cloudMessagingDAO to retrieve and store the access token. You must replace the Jogador class for another class that contains the client URL used to send the message to the Windows Phone device.

 @Service(SharedConstants.WINDOWS_CLOUD_BEAN) public class WindowsPushNotificationMediator extends AbstractCloudMediator { // NO_UCD (test only) private static final Logger LOG = Logger.getLogger(WindowsPushNotificationMediator.class.getName()); private static final String KEY_ACCESS_TOKEN = "access_token"; private static final String KEY_TOKEN_TYPE = "token_type"; @Resource(name = "authenticateWNSHeaders") private Map<String, String> authenticateWNSHeaders; @Resource(name = "authenticateWNSPostParams") private Map<String, String> authenticateWNSPostParams; @Resource(name = "sendMessageWNSHeaders") private Map<String, String> sendMessageWNSHeaders; @Autowired @Qualifier("authenticateUrlPostWNS") private String authenticateUrlPostWNS; @Autowired private CloudMessagingDAO cloudMessagingDAO; private OAuthToken oathToken; @Override public boolean sendMessage(Jogador destinatario, Action mensagem) { try { OAuthToken token = getToken(); String jsonString = mapper.writeValueAsString(mensagem); StringEntity entity = new StringEntity(jsonString, Consts.UTF_8); return sendMessage(destinatario, entity, token); } catch (IOException e) { LOG.log(Level.SEVERE, e.getMessage(), e); throw new RuntimeException(e); } } private boolean sendMessage(Jogador destinatario, HttpEntity entity, OAuthToken token) throws IOException { HttpPost post = new HttpPost(destinatario.getCloudMessagingInfo());// this is the client url post.addHeader("Authorization", token.getAuthorization()); addPostHeaders(post, sendMessageWNSHeaders); post.setEntity(entity); HttpResponse response = executeMethod(post); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { return sendMessage(destinatario, entity, getNewToken()); } Header[] allHeaders = response.getAllHeaders(); StringBuilder builder = new StringBuilder(); for (Header header : allHeaders) { builder.append(header.getName() + ": " + header.getValue()); builder.append('\n'); } LOG.info(builder.toString()); return response.getStatusLine().getStatusCode() == HttpStatus.SC_OK; } private void addPostHeaders(HttpPost post, Map<String, String> postHeaders) { for (String key : postHeaders.keySet()) { post.addHeader(key, postHeaders.get(key)); } } private OAuthToken getToken() throws IOException { if (oathToken == null) { //You should store your access token, so you can reuse it until it expires String token = cloudMessagingDAO.getValue(KEY_ACCESS_TOKEN); String tokenType = cloudMessagingDAO.getValue(KEY_TOKEN_TYPE); if (StringUtils.isNotBlank(token) && StringUtils.isNotBlank(tokenType)) { return oathToken = new OAuthToken(token, tokenType); } return getNewToken(); } return oathToken; } private OAuthToken getNewToken() throws IOException { HttpPost post = new HttpPost(authenticateUrlPostWNS); addPostHeaders(post, authenticateWNSHeaders); List<NameValuePair> params = new ArrayList<>(); for (String key : authenticateWNSPostParams.keySet()) { params.add(new BasicNameValuePair(key, authenticateWNSPostParams.get(key))); } post.setEntity(new UrlEncodedFormEntity(params)); HttpResponse response = executeMethod(post); String conteudo = responseToString(response); LOG.info(conteudo); if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { throw new NegocioException("Falha ao autenticar no serviΓ§o: " + conteudo); } @SuppressWarnings("unchecked") Map<String, String> resultMap = mapper.readValue(conteudo, HashMap.class); cloudMessagingDAO.setValues(resultMap); return oathToken = new OAuthToken(resultMap.get(KEY_ACCESS_TOKEN), resultMap.get(KEY_TOKEN_TYPE)); } } 
+1
source

All Articles