极光推送服务端开发

1. 需求

因门户app开发需求,要求对从crm推送过来的新订单对用户进行定向推送提醒,使得相关人员能够及时处理订单(注:以下是按照自己的业务需求来写的,相关方法没有做抽取和封装,只是提供最基础的实现参考)

2. 实现方案

使用极光推送作为推送服务,极光推送为免费版即可满足需求,如果后期推送量大,可申请使用付费版本。极光推送分为客户端开发和服务端开发。客户端有android和ios相关开发人员参照极光官网官方文档完成对app的开发集成。而服务端采用调用REST API v3 – Push接口的方式进行调用。本接口为restful风格,只需要按照极光的api要求格式发送https请求即可实现调用,不需要在服务器端编写java api代码。因需求要求为定向推送,按照极光官网说明,要过要定向推送,需要服务端保存用户和对应的registration_idregistration_id根据用户登录的设备客户端调用极光api生成的。当crm推送过来的新订单时,服务端根据customer_id查找对应的用户,然后再根据用户和registration_id查出用户对应的registration_id,根据registration_id调用极光REST API v3 – Push接口即可。

3. 具体实现

3.1 申请极光账号得到AppKey和MasterSecret

3.2保存用户和对应的registration_id

要实现定向对应需要保存用户和对应的registration_id,新增表emp_registration_id_rel如下:


在用户使用移动设备登录时,保存用户账号和registration_id,代码如下:

    /**

     * 登陆验证

     */

    @RequestMapping("login")

    public @ResponseBody String login(HttpServletRequestrequest,HttpServletResponse response) {

        JSONObject json = CommonUtil.getParams(request);

        // 人员账号

        String empAccount =(String)json.getString("empAccount");

        // 人员密码

        String password =(String)json.getString("password");

        // 极光推送registration_id(设备标识)

        String registrationId =(String)json.getString("registrationId");

        // 查询用户数据

        String str = appLoginService.doLogin(empAccount,password);

        //登录成功保存极光ID

      appLoginService.saveRegistrationId(empAccount,registrationId);

       

        //appLoginService.updateSendJpush("06","100000042", "1016052401808581");

       

       

        return str;

}

保存逻辑为:为防止用户在多台设备上登录过,或者一台设备多个用户登录过而导致定向推送信息误推送,保存时先根据用户账号或者registration_id作为查询条件,如果能查出记录,则先根据用户账号或者registration_id作为

条件删除记录在做保存操作,登录成功保存极光ID方法如下:

/**

 *

 * @param empAccount用户账号

 * @param registration_id极光推送设备id

 * @return

 */

    public int saveRegistrationId(StringempAccount, String registrationId) {

        Map<String, String> map  = new HashMap<String, String>();

        map.put("empAccount", empAccount);

        map.put("registrationId", registrationId);

        List<Map<String, String>>list  = jpushDao.getRegId(map);

        if(list!=null&&list.size()>0){

           jpushDao.delRegId(map);

        }

        int result =jpushDao.saveRegId(map);

        return result;

}

相关sql如下:

<selectid="getRegId"resultType="map"parameterType="map">

        select * from emp_registration_id_rel awhere 1=1

        <iftest="empAccount != null and empAccount != '' ">

           and a.emp_account = #{empAccount}

        </if>

        <iftest="registrationId != null and registrationId != ''">

           or a.registration_id =#{registrationId}

        </if>

    </select>

    <!-- 根据用户账号或registration_id删除相关信息-->

    <deleteid="delRegId"parameterType="map">

        delete from

        emp_registration_id_rel where emp_account= #{empAccount} or

        registration_id = #{registrationId}

    </delete>

    <!-- 保存用户账号和 registration_id-->

    <insertid="saveRegId"parameterType="map">

        insert into

        emp_registration_id_rel(emp_account,registration_id) values

        (#{empAccount},

        #{registrationId})

    </insert>

    <!-- 根据biz_info_t表中的customer_id查看对应的emp_account -->

    <selectid="getEmpAccount"resultType="map"parameterType="string">

        select t1.emp_account from om_employee_tt1,biz_info_t

        t2,customerid_org_rel_t t3

        where t1.org_id=t3.org_id andt2.customer_id=t3.customer_id and

        t2.customer_id=#{registrationId}

        group by

        t1.emp_account

</select>

3.3调用封装的极光推送方法进行定向对送

因为极光推送要求使用restful接口调用时要发送https请求,推送内容完全使用 JSON 的格式,所以在JPushUtil中封装了sendSSLPostRequest方法用于方式https请求,请求方式为post,请求数据格式设置为json。发送json数据需要设置contentType  为   application/json。具体的json格式可以参照http://docs.jiguang.cn/server/rest_api_v3_push/

因极光使用 HTTP Basic Authentication 的方式做访问授权,需要我们在HTTP Header(头)里加一个字段(Key/Value对),如下图所示:


相关代码:

String base64_auth_string ="Basic "+getBASE64(JPushUtil.AppKey+":"+JPushUtil.masterScrect);

            System.out.println("base64_auth_string"+base64_auth_string);

          

           httpPost.addHeader("Authorization", base64_auth_string);

其中的AppKey,masterScrect为我们申请极光账号得到AppKey和MasterSecret。

 

具体完整代码如下:

package com.tower.webframe.app.tool;

import java.io.IOException;

importjava.io.UnsupportedEncodingException;

importjava.security.KeyManagementException;

import java.security.NoSuchAlgorithmException;

importjava.security.cert.CertificateException;

import java.security.cert.X509Certificate;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

 

 

import javax.net.ssl.SSLContext;

import javax.net.ssl.TrustManager;

import javax.net.ssl.X509TrustManager;

 

 

 

import net.sf.json.JSONObject;

 

import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.NameValuePair;

import org.apache.http.ParseException;

importorg.apache.http.client.ClientProtocolException;

import org.apache.http.client.HttpClient;

importorg.apache.http.client.entity.UrlEncodedFormEntity;

importorg.apache.http.client.methods.HttpPost;

import org.apache.http.conn.scheme.Scheme;

importorg.apache.http.conn.ssl.SSLSocketFactory;

import org.apache.http.entity.StringEntity;

importorg.apache.http.impl.client.DefaultHttpClient;

importorg.apache.http.message.BasicNameValuePair;

import org.apache.http.util.EntityUtils;

 

public class JPushUtil {

        privatestatic final String AppKey ="xxxxxxxxxxx";//登录极光官网申请的appKey

        privatestatic final  String masterScrect ="xxxxxxxxxxxxxxx";//登录极光官网申请的masterScrect 

 

        publicstatic void main(String[] args) throws Exception {

                 Map<String,String> params = new HashMap<String, String>();

                 Strings =

//                              "{"

//                                 +"\"platform\":\"all\","

//                                 +    "\"audience\" :\"all\","  

//                                + "\"notification\": {"

//                                +    "\"android\": {"

//                                +        "\"alert\": \"订单确认:需求单号:123456789!\","

//                                +        "\"title\": \"Send to Android\","

//                                +        "\"builder_id\": 1,"

//                                +        "\"extras\": {"

//                                +            "\"newsid\": 321"

//                                +        "}"

//                                +   "},"

//                                +    "\"ios\": {"

//                                +        "\"alert\": \"订单确认:需求单号:123456789\","

//                                +        "\"sound\": \"default\","

//                                +        "\"badge\": \"+1\","

//                                +        "\"extras\": {"

//                                +            "\"newsid\": 321"

//                                +        "}"

//                                +    "}"

//                                + "},"

//                                + "\"message\": {"

//                                +    "\"msg_content\": \"订单确认:需求单号:123456789\","

//                                +    "\"content_type\": \"text\","

//                                +    "\"title\": \"msg\","

//                                +    "\"extras\": {"

//                                +        "\"key\": \"value\""

//                                +    "}"

//                                + "},"

//                                + "\"sms_message\":{"

//                                +    "\"content\":\"sms msg content\","

//                                +    "\"delay_time\":3600"

//                                + "},"

//                                + "\"options\": {"

//                                +    "\"time_to_live\": 60,"

//                                +    "\"apns_production\": false"

//                                + "}"

//                              +"}";

                 "{"

//              +"\"platform\":\"all\","

                 +"\"platform\":\"ios\","

                 +        "\"audience\" : { \"registration_id\" :[\"101d85590941878f97a\",\"141fe1da9ead512c5a8\"]},"

                 +"\"notification\": {"

                 +     "\"android\": {"

                 +         "\"alert\": \"订单确认:需求单号:123456789!\","

                 +         "\"title\": \"Sendto Android\","

                 +         "\"builder_id\":1,"

                 +         "\"extras\": {"

                 +             "\"newsid\":321"

                 +         "}"

                 +    "},"

                 +     "\"ios\": {"

                 +         "\"alert\": \"订单确认:需求单号:123456789\","

                 +         "\"sound\":\"default\","

                 +         "\"badge\":\"+1\","

                 +         "\"content-available\":true,"

                 +         "\"extras\": {"

                 +             "\"bizType\":\"06\""

                 +         "}"

                 +     "}"

                 +"},"

                 +"\"message\": {"

                 +     "\"msg_content\": \"订单确认:需求单号:123456789\","

                 +     "\"content_type\":\"text\","

                 +     "\"title\":\"msg\","

                 +     "\"extras\": {"

                 +      "\"bizType\":\"06\""

                 +     "}"

                 +"},"

                 +"\"sms_message\":{"

                 +     "\"content\":\"sms msgcontent\","

                 +     "\"delay_time\":3600"

                 +"},"

                 +"\"options\": {"

                 +     "\"time_to_live\":60,"

                 +     "\"apns_production\":false"

                 +"}"

                 +"}";

//                                       "{"

//                              +                 "\"platform\": \"all\","

//                              +                 "\"audience\" : \"all\","

//                              +                 "\"notification\" : {"

//                              +                      "\"android\" : {"

//                      +   "\"alert\" : \"hello,world!\","

//                      +   "\"title\" : \"而退哦;立刻脚后跟范德萨无色的日方提供用户均可\","

//                      +   "\"builder_id\" : 3,"

//                      +   "\"extras\" : {"

//                      +         "\"news_id\" :134,"

//                      +         "\"my_key\" : \"avalue\""

//                      +   "}"

//                      +"}"

//                              +                     "}"

//                              +                 "}"

//                              +               "}";

                 JSONObjectjs = JSONObject.fromObject(s);

                 System.out.println(js);

 

                 sendSSLPostRequest("https://api.jpush.cn/v3/push",js);

        }

 

        publicstatic void sendJPush(String registration_id,String msg_content,Stringbiz_type){

                 Strings =

                 "{"

                 +"\"platform\":\"all\","

                 +        "\"audience\" : { \"registration_id\" :[\""+registration_id+"\"]},"

                 +"\"notification\": {"

                 +     "\"android\": {"

                 +         "\"alert\":\""+msg_content+"\","

                 +         "\"title\": \"Sendto Android\","

                 +         "\"builder_id\":1,"

                 +         "\"extras\": {"

                 +             "\"bizType\":"+biz_type+""

                 +         "}"

                 +    "},"

                 +     "\"ios\": {"

                 +         "\"alert\":\""+msg_content+"\","

                 +         "\"sound\":\"default\","

                 +         "\"badge\":\"+1\","

                 +         "\"extras\": {"

                 +             "\"bizType\":"+biz_type+""

                 +         "}"

                 +     "}"

                 +"},"

                 +"\"message\": {"

                 +     "\"msg_content\":\""+msg_content+"\","

                 +     "\"content_type\":\"text\","

                 +     "\"title\":\"msg\","

                 +     "\"extras\": {"

                 +         "\"bizType\":"+biz_type+""

                 +     "}"

                 +"},"

                 +"\"sms_message\":{"

                 +     "\"content\":\"sms msgcontent\","

                 +     "\"delay_time\":3600"

                 +"},"

                 +"\"options\": {"

                 +     "\"time_to_live\":60,"

                 +     "\"apns_production\":false"

                 +"}"

                 +"}";

                 JSONObjectjs = JSONObject.fromObject(s);

                 System.out.println(js);

 

                 sendSSLPostRequest("https://api.jpush.cn/v3/push",js);

        }

        /**

         * 向HTTPS地址发送POST请求

         *

         * @param reqURL

         *           请求地址

         * @param params

         *           请求参数

         * @return 响应内容

         */

        @SuppressWarnings("finally")

        publicstatic String sendSSLPostRequest(String reqURL,

                         JSONObjectparams) {

                 longresponseLength = 0; // 响应长度

                 StringresponseContent = null; // 响应内容

                 HttpClienthttpClient = new DefaultHttpClient(); // 创建默认的httpClient实例

                 X509TrustManagerxtm = new X509TrustManager() { // 创建TrustManager

                         publicvoid checkClientTrusted(X509Certificate[] chain,

                                          StringauthType) throws CertificateException {

                         }

 

                         publicvoid checkServerTrusted(X509Certificate[] chain,

                                          StringauthType) throws CertificateException {

                         }

 

                         publicX509Certificate[] getAcceptedIssuers() {

                                  returnnull;

                         }

                 };

                 try{

                         //TLS1.0与SSL3.0基本上没有太大的差别,可粗略理解为TLS是SSL的继承者,但它们使用的是相同的SSLContext

                         SSLContextctx = SSLContext.getInstance("TLS");

 

                         //使用TrustManager来初始化该上下文,TrustManager只是被SSL的Socket所使用

                         ctx.init(null,new TrustManager[] { xtm }, null);

 

                         //创建SSLSocketFactory

                         SSLSocketFactorysocketFactory = new SSLSocketFactory(ctx);

 

                         //通过SchemeRegistry将SSLSocketFactory注册到我们的HttpClient上

                         httpClient.getConnectionManager().getSchemeRegistry()

                                          .register(newScheme("https", 443, socketFactory));

 

                         HttpPosthttpPost = new HttpPost(reqURL); // 创建HttpPost

                         List<NameValuePair>formParams = new ArrayList<NameValuePair>(); // 构建POST请求的表单参数

//                      for(Map.Entry<String, String> entry : params.entrySet()) {

//                              formParams.add(newBasicNameValuePair(entry.getKey(), entry

//                                               .getValue()));

//                      }

                          StringEntity s = newStringEntity(params.toString(),"UTF-8");

                       s.setContentEncoding("UTF-8");

                      s.setContentType("application/json");//发送json数据需要设置contentType  multipart/form-data   application/json

//                      Stringbase64_auth_string = "Basic "+getBASE64("xxxxxxxxxxx"//登录极光官网申请的appKey"xxxxxxxxxxxxxxx"//登录极光官网申请的masterScrect );//test

                         Stringbase64_auth_string = "Basic "+getBASE64(JPushUtil.AppKey+":"+JPushUtil.masterScrect);

                         System.out.println("base64_auth_string"+base64_auth_string);

                        

                         httpPost.addHeader("Authorization",base64_auth_string); //认证token

 

                         httpPost.setEntity(s);

 

                         HttpResponseresponse = httpClient.execute(httpPost); // 执行POST请求

                         HttpEntityentity = response.getEntity(); // 获取响应实体

 

                         if(null != entity) {

                                  responseLength= entity.getContentLength();

                                  responseContent= EntityUtils.toString(entity, "UTF-8");

                                  EntityUtils.consume(entity);// Consume response content

                         }

                         System.out.println("请求地址: "+ httpPost.getURI());

                         System.out.println("响应状态: "+ response.getStatusLine());

                         System.out.println("响应长度: "+ responseLength);

                         System.out.println("响应内容: "+ responseContent);

                 }catch (KeyManagementException e) {

                         e.printStackTrace();

                 }catch (NoSuchAlgorithmException e) {

                         e.printStackTrace();

                 }catch (UnsupportedEncodingException e) {

                         e.printStackTrace();

                 }catch (ClientProtocolException e) {

                         e.printStackTrace();

                 }catch (ParseException e) {

                         e.printStackTrace();

                 }catch (IOException e) {

                         e.printStackTrace();

                 }finally {

                         httpClient.getConnectionManager().shutdown();// 关闭连接,释放资源

                         returnresponseContent;

                 }

        }

        ///将 s 进行 BASE64 编码

        publicstatic String getBASE64(String s) {

                 if(s == null)

                         returnnull;

                 return(new sun.misc.BASE64Encoder()).encode(s.getBytes());

        }

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值