zoukankan      html  css  js  c++  java
  • 诡异的编码和字节长度

    由于工作需求的原因,需要给苹果的客户端推送消息,但是苹果服务器端对这个消息的内容做了限制,

    最大只能发送256个字节,发送的方式是以json的方式,256指的是发送的时候json数据的字节数。

    详情见:https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW1

    我在程序里动态的截取消息内容的长度(包括生成的“,”、“""”和“[]”)然后用256减去不是消息内容的字节的长度,

    由于消息内容是中文的,所以我就用String.getBytes().length来判断消息的长度,我用应用程序测试没有问题,

    但是在项目里就有出现了超出最大字节数的异常,让我非常郁闷,我把发送的json的内容打印出来,然后在应用程序中Json数据.getBytes().length是275

    而在项目中就是240,项目的服务器是weblogic10.3的,两个文件的编码都是utf-8,找了好久才发现项目中调试的时候他是按照一个汉字占两个字节算的,

    而utf-8的编码的大部分汉字是占用了3个字节,这就是出现异常的原因了。最后的解决办法,直接获得字符串的长度然后*3就是他们占用的字节数量,但是还是感觉有点不太靠谱普,目前没有找到其他的解决办法。

    消息推送的代码如下:

    需要的jar包:

    commons-lang-2.5.jar

    javapns-jdk16-163.jar

    log4j-1.2.15.jar

    bcprov-jdk16-145-1.jar

    不过还需要苹果的证书

    public static void recieveNotice(String deviceToken,Notice notice,String key,List<String> list) throws Exception {
      //deviceToken是手机的设备编号,Notice 是通知的对象,String 这条通知内容对应的key,list 通知的内容这里放在了一个list中

    PushNotificationManager pushManager = null;
    try {
    PayLoadCustomAlert alert2 = new PayLoadCustomAlert();
    alert2.addLocKey(key);

    PayLoad payLoad = new PayLoad();
    payLoad.addBadge(1);
    payLoad.addSound("default");
    payLoad.addCustomAlert(alert2);

    List<String> myList = new ArrayList<String>();
    myList.add(notice.getNoticeid() + "");
    myList.add(notice.getClaimid() + "");
    myList.add(notice.getStatus()+"");
    myList.add(notice.getClaimStatus()+"");
    myList.add(DATE_FORMAT.format(notice.getCreateTime()));

    payLoad.addCustomDictionary("p", myList);

    String logTags = ",\"loc-key\":\"\"[]";
    int temLength = payLoad.toString().getBytes().length+logTags.getBytes().length;//这个是没有添加数组的长度
    System.out.println("没有添加之前:"+payLoad.toString()+"长度:"+payLoad.toString().getBytes().length);
    int surplus = 256-temLength;//剩余可用的字节
    List<String> temList = new ArrayList<String>();//临时的数组 用来存放可以显示的文字
    boolean falg = true;//判断有没有价格
    int i = -1;
    if(list !=null && list.size()>0){
    for(String str : list){
    if(falg){
    try {
    Double.parseDouble(str);
    surplus = surplus - str.length()-3;
    temList.add(0,str);
    i++;
    continue;
    } catch (Exception e) {
    }finally{
    falg = false;
    }
    }
    int tem = str.length()*3+5;//“等”这个汉字占用了3个字节 “""”这个占用了2个字节 所以首先要把这五个的位子给算上
    if(surplus>tem){
    temList.add(str);
    surplus = surplus- tem+2;//算上之后满足条件 把“等”这个占用的空间给去掉 让他参与下次运算 “,”占用一个字节 如果有下一个中间要有“,”分割 所以共去掉加3减1个字节
    i++;
    }else{
    temList.set(i, list.get(i)+"等");
    break;
    }
    }
    alert2.addLocArgs(temList);//这里指的是价格,缺少的单证
    }

    System.out.println("添加之后:"+payLoad.toString()+"长度:"+payLoad.toString().getBytes().length);
    Log.opLogger.info("iphone 获得的通知:"+payLoad.toString()+"长度:"+payLoad.toString().getBytes().length);

    pushManager = PushNotificationManager.getInstance();
    pushManager.addDevice("iPhone", deviceToken);

    String certificatePath = Thread.currentThread().getContextClassLoader().getResource("").getPath()+ "push_p.p12";//证书存放的路径
    String certificatePassword = "abcd";//证书的密码
    pushManager.initializeConnection("gateway.sandbox.push.apple.com", 2195, certificatePath,certificatePassword,SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);
    Device client = pushManager.getDevice("iPhone");
    pushManager.sendNotification(client, payLoad);
    } catch (Exception e) {
    e.printStackTrace();
    Log.opLogger.error("Exception", e);
    } finally {
    pushManager.stopConnection();
    pushManager.removeDevice("iPhone");
    }

    }

  • 相关阅读:
    [enum]enum的用法
    gridview汇出EXCEL (ExportGridViewToExcel(dt, HttpContext.Current.Response);)
    c#用正则表达式判断字符串是否全是数字、小数点、正负号组成 Regex reg = new Regex(@"^(([0-9]+.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*.[0-9]+)|([0-9]*[1-9][0-9]*))$");
    GridView里的文本框改变事件
    转发 win7+iis7.5+asp.net下 CS0016: 未能写入输出文件“c:WindowsMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Files 解决方案
    验证上转文件类型的正则表达式
    EXCEL设置选中单元格样式
    转发!HTML 复选框 checkbox 的 JavaScript 的全选和全反选
    dataGrid转换dataTable
    wince mobile环境下播放WAV声音
  • 原文地址:https://www.cnblogs.com/andysd/p/2748052.html
Copyright © 2011-2022 走看看