├── .idea └── libraries │ ├── Maven__javax_servlet_jstl_1_2.xml │ ├── Maven__javax_servlet_servlet_api_2_5.xml │ └── Maven__org_slf4j_slf4j_api_1_6_4.xml ├── README ├── pom.xml ├── pushNotificationService.iml └── src └── main ├── java └── com │ └── mobiledaily │ └── pushnotificationservice │ ├── domain │ ├── Account.java │ ├── Location.java │ ├── MobileApp.java │ ├── MobileDevice.java │ └── NotificationToken.java │ ├── repository │ ├── KeyUtil.java │ ├── NotificationRepository.java │ └── NotificationRepositoryImpl.java │ ├── service │ ├── MobileAppService.java │ ├── MobileAppServiceImpl.java │ ├── NotificationService.java │ ├── NotificationServiceImpl.java │ ├── NotificationTokenService.java │ └── NotificationTokenServiceImpl.java │ └── web │ ├── MobileAppServiceController.java │ ├── NotificationRegisteringController.java │ └── NotificationSenderController.java ├── resources ├── config.properties └── pushCertificate.p12 └── webapp ├── META-INF └── Context.xml ├── WEB-INF ├── applicationContext.xml ├── dispatcher-servlet.xml ├── jsp │ └── push.jsp └── web.xml └── index.jsp /.idea/libraries/Maven__javax_servlet_jstl_1_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__javax_servlet_servlet_api_2_5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_slf4j_slf4j_api_1_6_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This file was created by IntelliJ IDEA 11.1.3 for binding GitHub repository -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | pushNotificationService 5 | pushNotificationService 6 | war 7 | 1.0 8 | pushNotificationService Maven Webapp 9 | http://maven.apache.org 10 | 11 | 3.1.2.RELEASE 12 | 13 | 14 | 15 | org.springframework 16 | spring-context 17 | ${org.springframework.version} 18 | 19 | 20 | org.springframework 21 | spring-webmvc 22 | ${org.springframework.version} 23 | 24 | 25 | org.springframework 26 | spring-aspects 27 | ${org.springframework.version} 28 | 29 | 30 | org.springframework.data 31 | spring-data-redis 32 | 1.0.1.RELEASE 33 | 34 | 35 | com.fasterxml.jackson.core 36 | jackson-annotations 37 | 2.0.6 38 | 39 | 40 | com.fasterxml.jackson.core 41 | jackson-databind 42 | 2.0.6 43 | 44 | 45 | redis.clients 46 | jedis 47 | 2.1.0 48 | 49 | 50 | cglib 51 | cglib 52 | 2.2.2 53 | 54 | 55 | commons-codec 56 | commons-codec 57 | 1.7 58 | 59 | 60 | commons-io 61 | commons-io 62 | 2.4 63 | 64 | 65 | commons-pool 66 | commons-pool 67 | 1.6 68 | 69 | 70 | org.apache.commons 71 | commons-lang3 72 | 3.1 73 | 74 | 75 | ch.qos.logback 76 | logback-classic 77 | 1.0.7 78 | 79 | 80 | commons-beanutils 81 | commons-beanutils 82 | 1.8.3 83 | 84 | 85 | javax.servlet 86 | servlet-api 87 | 2.5 88 | provided 89 | 90 | 91 | javax.servlet 92 | jstl 93 | 1.2 94 | 95 | 96 | 97 | pushNotificationService 98 | 99 | 100 | org.apache.tomcat.maven 101 | tomcat7-maven-plugin 102 | 2.0 103 | 104 | 105 | org.springframework 106 | spring-instrument-tomcat 107 | ${org.springframework.version} 108 | 109 | 110 | 111 | 112 | maven-compiler-plugin 113 | 114 | 1.6 115 | 1.6 116 | 117 | 118 | 119 | org.apache.maven.plugins 120 | maven-surefire-plugin 121 | 2.4 122 | 123 | 124 | 125 | 126 | 127 | Johnson.He@mobileDaily.cn 128 | Johnson He 129 | 130 | Architect 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /pushNotificationService.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | file://$MODULE_DIR$/src/main/webapp/WEB-INF/applicationContext.xml 18 | file://$MODULE_DIR$/src/main/webapp/WEB-INF/dispatcher-servlet.xml 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/domain/Account.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.domain; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: johnson 6 | * Date: 10/31/12 7 | * Time: 8:46 AM 8 | * To change this template use File | Settings | File Templates. 9 | */ 10 | public class Account { 11 | public static final String USER_NAME = "userName"; 12 | public static final String PASSWORD = "password"; 13 | public static final String EMAIL = "email"; 14 | public static final String PHONE = "phone"; 15 | public static final String ADDRESS = "address"; 16 | private String userName; 17 | private String password; 18 | private String email; 19 | private String phone; 20 | private String address; 21 | 22 | public String getUserName() { 23 | return userName; 24 | } 25 | 26 | public void setUserName(String userName) { 27 | this.userName = userName; 28 | } 29 | 30 | public String getPassword() { 31 | return password; 32 | } 33 | 34 | public void setPassword(String password) { 35 | this.password = password; 36 | } 37 | 38 | public String getEmail() { 39 | return email; 40 | } 41 | 42 | public void setEmail(String email) { 43 | this.email = email; 44 | } 45 | 46 | public String getPhone() { 47 | return phone; 48 | } 49 | 50 | public void setPhone(String phone) { 51 | this.phone = phone; 52 | } 53 | 54 | public String getAddress() { 55 | return address; 56 | } 57 | 58 | public void setAddress(String address) { 59 | this.address = address; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/domain/Location.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.domain; 2 | 3 | import java.math.BigDecimal; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: johnson 8 | * Date: 10/27/12 9 | * Time: 9:04 AM 10 | * To change this template use File | Settings | File Templates. 11 | */ 12 | public class Location { 13 | private final BigDecimal longitude; 14 | private final BigDecimal latitude; 15 | 16 | public Location(BigDecimal longitude, BigDecimal latitude) { 17 | this.latitude = latitude; 18 | this.longitude = longitude; 19 | } 20 | 21 | public BigDecimal getLongitude() { 22 | return longitude; 23 | } 24 | 25 | public BigDecimal getLatitude() { 26 | return latitude; 27 | } 28 | 29 | public static Location valueOf(String longitude, String latitude) { 30 | BigDecimal lo = new BigDecimal(latitude); 31 | BigDecimal la = new BigDecimal(latitude); 32 | return new Location(lo, la); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/domain/MobileApp.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.domain; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: johnson 6 | * Date: 10/28/12 7 | * Time: 6:06 PM 8 | * To change this template use File | Settings | File Templates. 9 | */ 10 | public class MobileApp { 11 | public static final String APP_NAME = "appName"; 12 | public static final String APP_DESC = "appDesc"; 13 | public static final String PUSH_CERTIFICATE = "pushCertificate"; 14 | private String appKey; 15 | private String appName; 16 | private String appDesc; 17 | private String pushCertificate; 18 | 19 | public String getAppName() { 20 | return appName; 21 | } 22 | 23 | public void setAppName(String appName) { 24 | this.appName = appName; 25 | } 26 | 27 | public String getAppDesc() { 28 | return appDesc; 29 | } 30 | 31 | public void setAppDesc(String appDesc) { 32 | this.appDesc = appDesc; 33 | } 34 | 35 | public String getPushCertificate() { 36 | return pushCertificate; 37 | } 38 | 39 | public void setPushCertificate(String pushCertificate) { 40 | this.pushCertificate = pushCertificate; 41 | } 42 | 43 | public String getAppKey() { 44 | return appKey; 45 | } 46 | 47 | public void setAppKey(String appKey) { 48 | this.appKey = appKey; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/domain/MobileDevice.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.domain; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: johnson 6 | * Date: 10/27/12 7 | * Time: 8:28 AM 8 | * To change this template use File | Settings | File Templates. 9 | */ 10 | public class MobileDevice { 11 | private String uid; 12 | private String resolution; 13 | private String platform; 14 | private String network; 15 | private String carrier; 16 | 17 | public String getUid() { 18 | return uid; 19 | } 20 | 21 | public void setUid(String uid) { 22 | this.uid = uid; 23 | } 24 | 25 | public String getResolution() { 26 | return resolution; 27 | } 28 | 29 | public void setResolution(String resolution) { 30 | this.resolution = resolution; 31 | } 32 | 33 | public String getPlatform() { 34 | return platform; 35 | } 36 | 37 | public void setPlatform(String platform) { 38 | this.platform = platform; 39 | } 40 | 41 | public String getNetwork() { 42 | return network; 43 | } 44 | 45 | public void setNetwork(String network) { 46 | this.network = network; 47 | } 48 | 49 | public String getCarrier() { 50 | return carrier; 51 | } 52 | 53 | public void setCarrier(String carrier) { 54 | this.carrier = carrier; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/domain/NotificationToken.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnore; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: johnson 8 | * Date: 10/27/12 9 | * Time: 8:42 AM 10 | * To change this template use File | Settings | File Templates. 11 | */ 12 | public class NotificationToken { 13 | public static final String PATTERN = "appKey:%s:serviceToken:%s"; 14 | public static final String USERNAME = "userName"; 15 | public static final String LONGITUDE = "longitude"; 16 | public static final String LATITUDE = "longitude"; 17 | private String appKey; 18 | private String serviceToken; 19 | private String userName; 20 | private String longitude; 21 | private String latitude; 22 | 23 | public NotificationToken() { 24 | } 25 | 26 | public NotificationToken(String appKey, String serviceToken) { 27 | this.appKey = appKey; 28 | this.serviceToken = serviceToken; 29 | } 30 | 31 | public String getAppKey() { 32 | return appKey; 33 | } 34 | 35 | public void setAppKey(String appKey) { 36 | this.appKey = appKey; 37 | } 38 | 39 | public String getServiceToken() { 40 | return serviceToken; 41 | } 42 | 43 | public void setServiceToken(String serviceToken) { 44 | this.serviceToken = serviceToken; 45 | } 46 | 47 | public String getUserName() { 48 | return userName; 49 | } 50 | 51 | public void setUserName(String userName) { 52 | this.userName = userName; 53 | } 54 | 55 | public String getLongitude() { 56 | return longitude; 57 | } 58 | 59 | public void setLongitude(String longitude) { 60 | this.longitude = longitude; 61 | } 62 | 63 | public String getLatitude() { 64 | return latitude; 65 | } 66 | 67 | public void setLatitude(String latitude) { 68 | this.latitude = latitude; 69 | } 70 | 71 | @JsonIgnore 72 | public Location getLocation() { 73 | return Location.valueOf(longitude, latitude); 74 | } 75 | 76 | @Override 77 | public String toString() { 78 | return String.format(PATTERN, getAppKey(), getServiceToken()); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/repository/KeyUtil.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.repository; 2 | 3 | /** 4 | * Created with IntelliJ IDEA. 5 | * User: johnson 6 | * Date: 10/27/12 7 | * Time: 1:05 PM 8 | * To change this template use File | Settings | File Templates. 9 | */ 10 | public final class KeyUtil { 11 | private static final String MATCH_TOKEN_KEY_PATTERN = "appKey:%s:serviceToken:*"; 12 | private static final String TOKEN_KEY_PATTERN = "appKey:%s:serviceToken:%s"; 13 | private static final String APP_KEY_PATTERN = "app:%s"; 14 | 15 | public static final String MATCH_APPKEY = "appKey:*"; 16 | public static final String MATCH_APP = "app:*"; 17 | 18 | public static String matchTokenKey(final String appKey) { 19 | return String.format(MATCH_TOKEN_KEY_PATTERN, appKey); 20 | } 21 | 22 | public static String tokenKey(String appKey, String serviceToken) { 23 | return String.format(TOKEN_KEY_PATTERN, appKey, serviceToken); 24 | } 25 | 26 | public static String mobileApp(final String appKey) { 27 | return String.format(APP_KEY_PATTERN, appKey); 28 | } 29 | 30 | public static String accountKey(final String userName) { 31 | return String.format("user:" + userName, userName); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/repository/NotificationRepository.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.repository; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.Account; 4 | import com.mobiledaily.pushnotificationservice.domain.MobileApp; 5 | import com.mobiledaily.pushnotificationservice.domain.NotificationToken; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created with IntelliJ IDEA. 11 | * User: johnson 12 | * Date: 10/27/12 13 | * Time: 10:17 AM 14 | * To change this template use File | Settings | File Templates. 15 | */ 16 | public interface NotificationRepository { 17 | public void add(NotificationToken token); 18 | 19 | public void remove(NotificationToken token); 20 | 21 | public List getAppKeys(); 22 | 23 | public List getTokens(final String appKey); 24 | 25 | public NotificationToken findBy(final String appKey, final String serviceToken); 26 | 27 | public List findBy(final String appKey); 28 | 29 | public List findAll(); 30 | 31 | public void addApp(MobileApp app); 32 | 33 | public void removeApp(String appKey); 34 | 35 | public MobileApp getApp(String appKey); 36 | 37 | public List getApps(); 38 | 39 | public void addAccount(Account account); 40 | 41 | public void removeAccount(Account account); 42 | 43 | public Account getAccount(String userName); 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/repository/NotificationRepositoryImpl.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.repository; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.Account; 4 | import com.mobiledaily.pushnotificationservice.domain.MobileApp; 5 | import com.mobiledaily.pushnotificationservice.domain.NotificationToken; 6 | import org.springframework.context.ApplicationContext; 7 | import org.springframework.context.support.FileSystemXmlApplicationContext; 8 | import org.springframework.data.redis.core.HashOperations; 9 | import org.springframework.data.redis.core.StringRedisTemplate; 10 | import org.springframework.stereotype.Repository; 11 | 12 | import javax.annotation.PostConstruct; 13 | import javax.annotation.Resource; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | import static com.mobiledaily.pushnotificationservice.repository.KeyUtil.MATCH_APPKEY; 18 | 19 | /** 20 | * Created with IntelliJ IDEA. 21 | * User: johnson 22 | * Date: 10/27/12 23 | * Time: 11:56 AM 24 | * To change this template use File | Settings | File Templates. 25 | */ 26 | @Repository(value = "notificationRepository") 27 | public class NotificationRepositoryImpl implements NotificationRepository { 28 | @Resource(name = "template") 29 | private StringRedisTemplate template; 30 | private HashOperations hashOperations; 31 | 32 | @PostConstruct 33 | private void init() { 34 | hashOperations = template.opsForHash(); 35 | } 36 | 37 | @Override 38 | public void add(NotificationToken token) { 39 | final String key = KeyUtil.tokenKey(token.getAppKey(), token.getServiceToken()); 40 | hashOperations.put(key, NotificationToken.USERNAME, token.getUserName()); 41 | hashOperations.put(key, NotificationToken.LONGITUDE, token.getLongitude()); 42 | hashOperations.put(key, NotificationToken.LATITUDE, token.getLatitude()); 43 | template.persist(key); 44 | } 45 | 46 | @Override 47 | public void remove(NotificationToken token) { 48 | final String key = KeyUtil.tokenKey(token.getAppKey(), token.getServiceToken()); 49 | hashOperations.delete(key, NotificationToken.USERNAME); 50 | hashOperations.delete(key, NotificationToken.LONGITUDE); 51 | hashOperations.delete(key, NotificationToken.LATITUDE); 52 | template.delete(key); 53 | } 54 | 55 | public List getAppKeys() { 56 | List result = new ArrayList(); 57 | for (String k : template.keys(MATCH_APPKEY)) { 58 | result.add(Key.valueOf(k).getServiceToken()); 59 | } 60 | return result; 61 | } 62 | 63 | public List getTokens(final String appKey) { 64 | List result = new ArrayList(); 65 | for (String k : template.keys(KeyUtil.matchTokenKey(appKey))) { 66 | result.add(Key.valueOf(k).getServiceToken()); 67 | } 68 | return result; 69 | } 70 | 71 | public NotificationToken findBy(final String appKey, final String serviceToken) { 72 | NotificationToken result = new NotificationToken(); 73 | result.setAppKey(appKey); 74 | result.setServiceToken(serviceToken); 75 | final String key = KeyUtil.tokenKey(appKey, serviceToken); 76 | result.setUserName(get(key, NotificationToken.USERNAME)); 77 | result.setLatitude(get(key, NotificationToken.LATITUDE)); 78 | result.setLongitude(get(key, NotificationToken.LONGITUDE)); 79 | return result; 80 | } 81 | 82 | public List findBy(final String appKey) { 83 | List result = new ArrayList(); 84 | for (String token : getTokens(appKey)) { 85 | result.add(findBy(appKey, token)); 86 | } 87 | return result; 88 | } 89 | 90 | @Override 91 | public List findAll() { 92 | List result = new ArrayList(); 93 | for (String k : template.keys(MATCH_APPKEY)) { 94 | Key key = Key.valueOf(k); 95 | result.add(findBy(key.getAppKey(), key.getServiceToken())); 96 | } 97 | return result; 98 | } 99 | 100 | @Override 101 | public void addApp(MobileApp app) { 102 | final String key = KeyUtil.mobileApp(app.getAppKey()); 103 | hashOperations.put(key, MobileApp.APP_NAME, app.getAppName()); 104 | hashOperations.put(key, MobileApp.APP_DESC, app.getAppDesc()); 105 | hashOperations.put(key, MobileApp.PUSH_CERTIFICATE, app.getPushCertificate()); 106 | template.persist(key); 107 | } 108 | 109 | @Override 110 | public void removeApp(String appKey) { 111 | final String key = KeyUtil.mobileApp(appKey); 112 | hashOperations.delete(key, MobileApp.APP_NAME); 113 | hashOperations.delete(key, MobileApp.APP_DESC); 114 | hashOperations.delete(key, MobileApp.PUSH_CERTIFICATE); 115 | template.delete(key); 116 | } 117 | 118 | @Override 119 | public MobileApp getApp(String appKey) { 120 | MobileApp result = new MobileApp(); 121 | result.setAppKey(appKey); 122 | final String key = KeyUtil.mobileApp(appKey); 123 | result.setAppName(hashOperations.get(key, MobileApp.APP_NAME)); 124 | result.setAppDesc(hashOperations.get(key, MobileApp.APP_DESC)); 125 | result.setPushCertificate(hashOperations.get(key, MobileApp.PUSH_CERTIFICATE)); 126 | return result; 127 | } 128 | 129 | @Override 130 | public List getApps() { 131 | List result = new ArrayList(); 132 | for (String k : template.keys(KeyUtil.MATCH_APP)) { 133 | final String appKey = k.substring(4); 134 | result.add(getApp(appKey)); 135 | } 136 | return result; 137 | } 138 | 139 | public void addAccount(Account account) { 140 | final String key = KeyUtil.accountKey(account.getUserName()); 141 | hashOperations.put(key, Account.PASSWORD, account.getPassword()); 142 | hashOperations.put(key, Account.EMAIL, account.getEmail()); 143 | hashOperations.put(key, Account.PHONE, account.getPhone()); 144 | hashOperations.put(key, Account.ADDRESS, account.getAddress()); 145 | template.persist(key); 146 | } 147 | 148 | public Account getAccount(String userName) { 149 | Account result = new Account(); 150 | final String key = KeyUtil.accountKey(userName); 151 | result.setUserName(userName); 152 | result.setEmail(hashOperations.get(key, Account.EMAIL)); 153 | result.setPassword(hashOperations.get(key, Account.PASSWORD)); 154 | result.setAddress(hashOperations.get(key, Account.ADDRESS)); 155 | result.setPhone(hashOperations.get(key, Account.PHONE)); 156 | return result; 157 | } 158 | 159 | public void removeAccount(Account account) { 160 | final String key = KeyUtil.accountKey(account.getUserName()); 161 | hashOperations.delete(key, Account.PASSWORD); 162 | hashOperations.delete(key, Account.EMAIL); 163 | hashOperations.delete(key, Account.PHONE); 164 | hashOperations.delete(key, Account.ADDRESS); 165 | template.delete(key); 166 | } 167 | 168 | private String get(final String key, final String hashKey) { 169 | return hashOperations.get(key, hashKey); 170 | } 171 | 172 | public static final class Key { 173 | private final String appKey; 174 | private final String serviceToken; 175 | 176 | public Key(String appKey, String serviceToken) { 177 | this.appKey = appKey; 178 | this.serviceToken = serviceToken; 179 | } 180 | 181 | public String getAppKey() { 182 | return appKey; 183 | } 184 | 185 | public String getServiceToken() { 186 | return serviceToken; 187 | } 188 | 189 | public static Key valueOf(final String k) { 190 | String[] parts = k.split(":"); 191 | return new Key(parts[1], parts[3]); 192 | } 193 | } 194 | 195 | public static void main(String[] args) { 196 | ApplicationContext ctx = new FileSystemXmlApplicationContext("src/main/webapp/WEB-INF/applicationContext.xml"); 197 | NotificationRepository repository = ctx.getBean("notificationRepository", NotificationRepository.class); 198 | NotificationToken token = new NotificationToken(); 199 | token.setAppKey("00000"); 200 | token.setLatitude("12.0000"); 201 | token.setLongitude("35.000001"); 202 | token.setUserName("Johnson"); 203 | token.setServiceToken("12ea0103f"); 204 | repository.add(token); 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/service/MobileAppService.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.service; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.MobileApp; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created with IntelliJ IDEA. 9 | * User: johnson 10 | * Date: 10/28/12 11 | * Time: 6:12 PM 12 | * To change this template use File | Settings | File Templates. 13 | */ 14 | public interface MobileAppService { 15 | public void add(MobileApp app); 16 | 17 | public List getApps(); 18 | 19 | public void remove(String appKey); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/service/MobileAppServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.service; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.MobileApp; 4 | import com.mobiledaily.pushnotificationservice.repository.NotificationRepository; 5 | import org.springframework.stereotype.Service; 6 | 7 | import javax.annotation.Resource; 8 | import java.util.List; 9 | 10 | /** 11 | * Created with IntelliJ IDEA. 12 | * User: johnson 13 | * Date: 10/28/12 14 | * Time: 6:15 PM 15 | * To change this template use File | Settings | File Templates. 16 | */ 17 | @Service(value = "mobileAppService") 18 | public class MobileAppServiceImpl implements MobileAppService { 19 | @Resource 20 | private NotificationRepository notificationRepository; 21 | 22 | @Override 23 | public void add(MobileApp app) { 24 | notificationRepository.addApp(app); 25 | } 26 | 27 | @Override 28 | public List getApps() { 29 | return notificationRepository.getApps(); 30 | } 31 | 32 | @Override 33 | public void remove(final String appKey) { 34 | notificationRepository.removeApp(appKey); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/service/NotificationService.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.service; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created with IntelliJ IDEA. 7 | * User: johnson 8 | * Date: 10/27/12 9 | * Time: 9:08 AM 10 | * To change this template use File | Settings | File Templates. 11 | */ 12 | public interface NotificationService { 13 | public void send(final List serviceTokens, final String message); 14 | 15 | public void send(final String serviceToken, final String message); 16 | 17 | public void broadcast(final String appKey, final String message); 18 | 19 | public void broadcast(final String message); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/service/NotificationServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.service; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.NotificationToken; 4 | import com.mobiledaily.pushnotificationservice.repository.NotificationRepository; 5 | import javapns.Push; 6 | import javapns.communication.exceptions.CommunicationException; 7 | import javapns.communication.exceptions.KeystoreException; 8 | import org.apache.log4j.Logger; 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.stereotype.Service; 11 | 12 | import javax.annotation.PostConstruct; 13 | import javax.annotation.Resource; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | /** 18 | * Created with IntelliJ IDEA. 19 | * User: johnson 20 | * Date: 10/27/12 21 | * Time: 12:13 PM 22 | * To change this template use File | Settings | File Templates. 23 | */ 24 | @Service(value = "notificationService") 25 | public class NotificationServiceImpl implements NotificationService { 26 | private static final Logger LOGGER = Logger.getLogger(NotificationService.class); 27 | @Resource 28 | private NotificationRepository notificationRepository; 29 | @Value("${push.keyStore}") 30 | private String keyStore; 31 | @Value("${push.keyStorePassword}") 32 | private String keyStorePassword; 33 | private String keyStorePath; 34 | 35 | @PostConstruct 36 | private void init() { 37 | try { 38 | keyStorePath = Thread.currentThread().getContextClassLoader().getResource(keyStore).getPath(); 39 | } catch (NullPointerException ex) { 40 | LOGGER.error(ex.getMessage()); 41 | } 42 | } 43 | 44 | public void send(final List serviceTokens, final String message) { 45 | sendMessage(message, serviceTokens); 46 | } 47 | 48 | public void send(final String serviceToken, final String message) { 49 | List tokens = new ArrayList(); 50 | tokens.add(serviceToken); 51 | sendMessage(message, tokens); 52 | } 53 | 54 | public void broadcast(final String appKey, final String message) { 55 | send(notificationRepository.getTokens(appKey), message); 56 | } 57 | 58 | public void broadcast(final String message) { 59 | for (NotificationToken token : notificationRepository.findAll()) { 60 | send(token.getServiceToken(), message); 61 | } 62 | } 63 | 64 | private void sendMessage(final String message, final List serviceTokens) { 65 | try { 66 | Push.alert(message, keyStorePath, keyStorePassword, false, serviceTokens); 67 | } catch (CommunicationException e) { 68 | LOGGER.error(e.getMessage()); 69 | } catch (KeystoreException e) { 70 | LOGGER.error(e.getMessage()); 71 | } catch (NullPointerException e) { 72 | LOGGER.error(e.getMessage()); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/service/NotificationTokenService.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.service; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.Location; 4 | import com.mobiledaily.pushnotificationservice.domain.NotificationToken; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created with IntelliJ IDEA. 10 | * User: johnson 11 | * Date: 10/27/12 12 | * Time: 8:59 AM 13 | * To change this template use File | Settings | File Templates. 14 | */ 15 | public interface NotificationTokenService { 16 | public void register(final NotificationToken token); 17 | 18 | public void updateIdentity(String appKey, String serviceToken, String user); 19 | 20 | public void updateLocation(String appKey, String ServiceToken, Location location); 21 | 22 | public List getBy(final String appKey); 23 | 24 | public List get(); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/service/NotificationTokenServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.service; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.Location; 4 | import com.mobiledaily.pushnotificationservice.domain.NotificationToken; 5 | import com.mobiledaily.pushnotificationservice.repository.NotificationRepository; 6 | import org.springframework.stereotype.Service; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.List; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: johnson 14 | * Date: 10/27/12 15 | * Time: 9:07 AM 16 | * To change this template use File | Settings | File Templates. 17 | */ 18 | @Service(value = "notificationTokenService") 19 | public class NotificationTokenServiceImpl implements NotificationTokenService { 20 | @Resource 21 | private NotificationRepository notificationRepository; 22 | 23 | @Override 24 | public void register(NotificationToken token) { 25 | notificationRepository.add(token); 26 | } 27 | 28 | @Override 29 | public void updateIdentity(String appKey, String serviceToken, String user) { 30 | } 31 | 32 | @Override 33 | public void updateLocation(String appKey, String ServiceToken, Location location) { 34 | } 35 | 36 | @Override 37 | public List getBy(String appKey) { 38 | return notificationRepository.findBy(appKey); 39 | } 40 | 41 | @Override 42 | public List get() { 43 | return notificationRepository.findAll(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/web/MobileAppServiceController.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.web; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.MobileApp; 4 | import com.mobiledaily.pushnotificationservice.service.MobileAppService; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.List; 10 | 11 | /** 12 | * Created with IntelliJ IDEA. 13 | * User: johnson 14 | * Date: 10/28/12 15 | * Time: 6:08 PM 16 | * To change this template use File | Settings | File Templates. 17 | */ 18 | @Controller 19 | public class MobileAppServiceController { 20 | @Resource 21 | private MobileAppService mobileAppService; 22 | 23 | @RequestMapping(value = "/apps/add", method = RequestMethod.GET) 24 | public void addApp(@RequestBody MobileApp app) { 25 | mobileAppService.add(app); 26 | } 27 | 28 | @RequestMapping(value = "/apps", method = RequestMethod.GET) 29 | public 30 | @ResponseBody 31 | List getApps() { 32 | return mobileAppService.getApps(); 33 | } 34 | 35 | @RequestMapping(value = "/apps/remove/{appKey}", method = RequestMethod.GET) 36 | public 37 | @ResponseBody 38 | void removeApp(@PathVariable String appKey) { 39 | mobileAppService.remove(appKey); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/web/NotificationRegisteringController.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.web; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.NotificationToken; 4 | import com.mobiledaily.pushnotificationservice.service.NotificationTokenService; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.PathVariable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.RequestMethod; 9 | import org.springframework.web.bind.annotation.ResponseBody; 10 | 11 | import javax.annotation.Resource; 12 | import java.util.List; 13 | 14 | /** 15 | * Created with IntelliJ IDEA. 16 | * User: johnson 17 | * Date: 10/27/12 18 | * Time: 8:16 AM 19 | * This class is responsible for registering the notification service based on different 20 | * mobile platforms like Android and iOS. 21 | */ 22 | @Controller(value = "notificationRegisteringController") 23 | public class NotificationRegisteringController { 24 | @Resource 25 | private NotificationTokenService notificationTokenService; 26 | 27 | @RequestMapping(value = "/register", method = RequestMethod.GET) 28 | public void register(NotificationToken token) { 29 | notificationTokenService.register(token); 30 | } 31 | 32 | @RequestMapping(value = "/tokens", method = RequestMethod.GET) 33 | public 34 | @ResponseBody 35 | List getNotificationTokens() { 36 | return notificationTokenService.get(); 37 | } 38 | 39 | @RequestMapping(value = "/tokens/{appKey}", method = RequestMethod.GET) 40 | public 41 | @ResponseBody 42 | List getNotificationTokensBy(@PathVariable String appKey) { 43 | return notificationTokenService.getBy(appKey); 44 | } 45 | 46 | @RequestMapping(value = "/host", method = RequestMethod.GET) 47 | public 48 | @ResponseBody 49 | String getHost() { 50 | return System.getenv("VCAP_APP_HOST"); 51 | } 52 | 53 | @RequestMapping(value = "/port", method = RequestMethod.GET) 54 | public 55 | @ResponseBody 56 | String getPort() { 57 | return System.getenv("VCAP_APP_PORT"); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/mobiledaily/pushnotificationservice/web/NotificationSenderController.java: -------------------------------------------------------------------------------- 1 | package com.mobiledaily.pushnotificationservice.web; 2 | 3 | import com.mobiledaily.pushnotificationservice.domain.NotificationToken; 4 | import com.mobiledaily.pushnotificationservice.service.NotificationService; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.ui.Model; 7 | import org.springframework.ui.ModelMap; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | 11 | import javax.annotation.Resource; 12 | import javax.servlet.http.HttpServletRequest; 13 | import java.util.Map; 14 | 15 | /** 16 | * Created with IntelliJ IDEA. 17 | * User: johnson 18 | * Date: 10/28/12 19 | * Time: 1:05 PM 20 | * To change this template use File | Settings | File Templates. 21 | */ 22 | @Controller 23 | public class NotificationSenderController { 24 | @Resource 25 | private NotificationService notificationService; 26 | 27 | @RequestMapping(value = "/push", method = RequestMethod.POST) 28 | public String pushNotification(HttpServletRequest request) { 29 | String serviceToken = request.getParameter("serviceToken"); 30 | String message = request.getParameter("message"); 31 | notificationService.send(serviceToken, message); 32 | return "push"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/config.properties: -------------------------------------------------------------------------------- 1 | db.host=127.0.0.1 2 | db.port=6379 3 | db.usePool=true 4 | push.keyStore=pushCertificate.p12 5 | push.keyStorePassword=heqiao75518 6 | -------------------------------------------------------------------------------- /src/main/resources/pushCertificate.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qiaohe/pushNotificationService/7859ec3730914dc55d72d90bd2e85ae1dd545632/src/main/resources/pushCertificate.p12 -------------------------------------------------------------------------------- /src/main/webapp/META-INF/Context.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/dispatcher-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/jsp/push.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: johnson 4 | Date: 10/28/12 5 | Time: 2:16 PM 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | Push Notification 12 | 13 | 14 | push Notification Message success with provided service token. 15 | 16 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | mobile Daily push Notification Service 8 | 9 | contextConfigLocation 10 | /WEB-INF/applicationContext.xml /WEB-INF/dispatcher-servlet.xml 11 | 12 | 13 | org.springframework.web.context.ContextLoaderListener 14 | 15 | 16 | 17 | encodingFilter 18 | org.springframework.web.filter.CharacterEncodingFilter 19 | 20 | encoding 21 | UTF-8 22 | 23 | 24 | forceEncoding 25 | true 26 | 27 | 28 | 29 | encodingFilter 30 | /* 31 | 32 | 33 | dispatcher 34 | org.springframework.web.servlet.DispatcherServlet 35 | 1 36 | 37 | 38 | dispatcher 39 | *.html 40 | 41 | 42 | index.jsp 43 | 44 | -------------------------------------------------------------------------------- /src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | ServiceToken: 5 |
6 | Message: 7 | 8 |
9 | 10 | 11 | --------------------------------------------------------------------------------