zoukankan      html  css  js  c++  java
  • ①HttpURLConnection通过报文提交

    在进行短信发送的接口,因厂家不同,有的厂家会采用报文的格式进行短信请求的发送与接收。本文主要介绍利用HttpURLConnection进行短信报文的请求与响应。

    一般的url请求分为两种,一种是GET,一种是POST:
    1.GET请求的参数是放在url后面拼接的,请求大小有限制,具体多少大家可以自行去百度,在这里就不多说了
    2.POST请求参数是放在HTTP请求的正文里的,可传输的内容远大于GET请求,而且理论上来说POST请求是没有大小限制的,所以使用POST请求较多
    一般正常的请求,get参数会显示在地址栏上,参数很容易被获取,安全性也较低,所以使用POST请求会比较好

    HttpURLConnection有两种简单的设置请求头的方法

    setRequestProperty(key,value)
    addRequestProperty(key,value)

    setRequestProperty和addRequestProperty的区别就是,setRequestProperty会覆盖已经存在的key的所有values,有清零重新赋值的作用。而addRequestProperty则是在原来key的基础上继续添加其他value。

    发送报文格式如图所示:

    短信发送:

       try {
     String postXml = "<?xml version='1.0' encoding='UTF-8'?>"; postXml = postXml + "<mtpacket>"; postXml = postXml + "<cpid>" +ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_CPID)+ "</cpid>"; postXml = postXml + "<userpass>" + ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_USERPASS) + "</userpass>"; postXml = postXml + "<port>" + ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_PORT)+ "</port>"; postXml = postXml + "<respDataType>XML</respDataType>"; postXml = postXml + "<cpmid>" + ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_CPMID)+ "</cpmid>"; postXml = postXml + "<flag>1</flag>"; postXml = postXml + "<mobile><![CDATA[" + mobile + "]]></mobile>"; postXml = postXml + "<message><![CDATA[" + new String(content.getBytes(), "utf-8") + "]]></message>"; postXml = postXml + "</mtpacket>"; logger.info("发送url:{},发送内容:{}",ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_POSTURL), postXml);
         //1.连接的URL URL url
    = new URL(ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_POSTURL));
         //2.这个地方的conn是根据请求协议(此处是http协议)生成的URLConnection类的子类HttpURLConnection
    //所以将其转化为HttpURLConnection类,以便使用HttpURLConnection更过的API
    HttpURLConnection conn
    = (HttpURLConnection)url.openConnection();
    //3.POST可以更好的传参 conn.setRequestMethod(
    "POST");
        //4.是否使用缓存,Post 请求不能使用缓存 conn.setUseCaches(
    false);
             //5.设置之后可以向服务端写入数据、、可以使用conn.getOutputStream().write()
         // 可以传输参数,POST请求数据放在正文内,所以需要开启传参
    conn.setDoOutput(
    true);
             //6.http读取数据
             // 默认是true,所以可以一般的请求都可以获取数据
             urlConnection.setDoInput(true);
         //7.设置请求头
    conn.setRequestProperty(
    "Content-type", "text/xml;charset=UTF-8");
       //8.输出流,进行传参,所有数据放在这里 OutputStreamWriter
    out = new OutputStreamWriter(conn.getOutputStream());
           //9.写入参数内容
    out.write(postXml);
           //10.刷新输出流,把所有的数据流数据都传输过去
    out.flush();
             //11.关闭输出流
    out.close();

    }catch (Exception e){
    e.printStackTrace();
    }

     接收短信报文:

    接收短信代码:

                  if (conn.getResponseCode() != 200) {
                      logger.info("发送失败:返回状态:" + conn.getResponseCode());
                  }
                  String result = "";
             //获取输入流,这段是正式请求,会把所有的设置和参数以http方式进行请求 BufferedReader
    in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK")); String line; while ((line = in.readLine()) != null) { result = result + line + " "; } in.close(); String re = result.trim().replaceAll("'", """);
             //打印获取的数据 logger.info(
    "请求返回:" + re); if (!re.contains("<respCode>0</respCode>")) { logger.info("发送失败:返回:" + re); }

    完整示例代码:

        @Override
        public void sendSms(String mobile, String content, Map<String, Object> params) {
             try {
                  String postXml = "<?xml version='1.0' encoding='UTF-8'?>";
                  postXml = postXml + "<mtpacket>";
                  postXml = postXml + "<cpid>" +ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_CPID)+ "</cpid>";
                  postXml = postXml + "<userpass>" + ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_USERPASS) + "</userpass>";
                  postXml = postXml + "<port>" + ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_PORT)+ "</port>";
                  postXml = postXml + "<respDataType>XML</respDataType>";
                  postXml = postXml + "<cpmid>" + ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_CPMID)+ "</cpmid>";
                  postXml = postXml + "<flag>1</flag>";
    
                  postXml = postXml + "<mobile><![CDATA[" + mobile + "]]></mobile>";
                  postXml = postXml + "<message><![CDATA[" + new String(content.getBytes(), "utf-8") + "]]></message>";
                  postXml = postXml + "</mtpacket>";
                  logger.info("发送url:{},发送内容:{}",ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_POSTURL), postXml);
    
                  URL url = new URL(ZkjnSmsConfig.getConfigValue(ZkjnSmsConfig.SMS_ZKJN_POSTURL));
                  HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                  conn.setRequestMethod("POST");
                  conn.setUseCaches(false);
                  conn.setDoOutput(true);
                  conn.setRequestProperty("Content-type", "text/xml;charset=UTF-8");
                  OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());
                  out.write(postXml);
                  out.flush();
                  out.close();
    
                  if (conn.getResponseCode() != 200) {
                      logger.info("发送失败:返回状态:" + conn.getResponseCode());
                  }
    
                  String result = "";
                  BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"));
                  String line;
                  while ((line = in.readLine()) != null) {
                    result = result + line + "
    ";
                  }
                  in.close();
                  String re = result.trim().replaceAll("'", """);
                  logger.info("请求返回:" + re);
                  if (!re.contains("<respCode>0</respCode>")) {
                      logger.info("发送失败:返回:" + re);
                  }
                }catch (Exception e){
                    e.printStackTrace();
                }
            
        }

    注意事项:

    1.set一些设置的时候必须在connection之前,如果在connection之后这些set都没有效果了
    2.post请求的正文是通过outputStream流写入的,但是在这并没有真正的去发送请求,只是放在了内存缓冲区,只有当getInputStream()调用的时候才真正的去请求
    3.设置超时,防止网络异常的情况下,可能会导致程序僵死而不继续往下执行 

    //超时设置必须在connection之前
    urlConnection.setConnectTimeout(5 * 1000);// 5秒连接超时
    urlConnection.setReadTimeout(5 * 1000);// 5秒获取内容超时

    4.添加请求头的时候如果有中文,就有可能造成中文乱码这时候可以使用这个方法

    // 参数进行encode(编码),防止中文乱码
    urlConnection.setRequestProperty("test", URLEncoder.encode("一个测试请求头", "UTF-8"));

    对某个参数进行URLEncoder.encode,服务端获取参数之后再通过URLDecoder.decode一下就可以获得完整的中文了 

    5.如果环境是采用GBK编码,而短信是采用utf-8中文英文数字组合的方式组织的,这个时候要注意。要做一下操作

    首先要将中文字符进行转换, 

     postXml = postXml + "<message><![CDATA[" + new String(content.getBytes("UTF-8"),"UTF-8") + "]]></message>"

    其次在进行流输出的时候,要设定输出字符,否则在转换的时候,容易出现,字符不匹配出现乱码的问题【环境GBK,流输出默认是采用环境编码的】:

     OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(),Charset.forName("UTF-8"));

  • 相关阅读:
    MySQL+Navicat for MySQL安装
    intellij idea14 +svn配置
    java重载(实现同一方法名,不同参数)
    Java连接MySQL数据库及操作
    通过Chrome的inspect对手机webview进行调试
    使用fiddler对手机上的程序进行抓包
    开始一个Android的appium实例
    Android模拟器内安装应用
    Appium的inspector使用
    python webdriver启动IE浏览器
  • 原文地址:https://www.cnblogs.com/shawWey/p/9554999.html
Copyright © 2011-2022 走看看