网建短信通 使用java调用API发送短信时总是返回-41,关键的关键,仅在于一个问号:(
2019-08-22 17:07
309 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41885819/article/details/100019477
今天突发奇想做一个定时给女朋友发送表白短信的功能,发送短信的接口很多,不过基本都是收费的,情有可原。在网建短信通平台(http://sms.webchinese.cn/default.shtml)可以非常找到各语言的示例代码。我自己没有采用默认版本的jar包,直接在maven里面加载了对应包的最新版本,那么,问题就来了,特别是org.apache.httpcomponents在4.0后应该有了较大的更新,很多方法就不能直接使用,测试了很久返回值都是-41,按照平台API可以知道,显示的是:手机号为空,下面是部分代码:
import java.io.IOException; import java.util.LinkedList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.config.CookieSpecs; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class SendMessageService { // 接口地址 private Log logger = LogFactory.getLog(this.getClass()); private HttpClient httpClient = null; private HttpPost httpPost = null; private long startTime = 0L; private long endTime = 0L; private int status = 0; //测试方法 public static void main(String[] args) { SendMessageService ac = new SendMessageService("http://utf8.api.smschinese.cn/"); List<NameValuePair> list = new LinkedList<NameValuePair>(); //设置用户名 NameValuePair param1 = new BasicNameValuePair("Uid", "xxx"); //设置秘钥,这个秘钥不是你用户名密码,要去网站上查看 NameValuePair param2 = new BasicNameValuePair("Key", "xxx"); //设置收信人号码 NameValuePair param3 = new BasicNameValuePair("smsMob", "xxx"); //设置短信内容,内容中不宜出现空格等特殊符号 NameValuePair param4 = new BasicNameValuePair("smsText", "xxx"); list.add(param1); list.add(param2); list.add(param3); list.add(param4); System.out.println(ac.post(list)); System.out.println(ac.getStatus()); } //构造方法 public SendMessageService(String url) { if (url != null) { this.apiURL = url; } if (apiURL != null) { RequestConfig config = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT).build(); this.httpClient = HttpClients.custom().setDefaultRequestConfig(config).build(); this.httpPost = new HttpPost(apiURL); } } //调用接口API public String post(List<NameValuePair> list) { String body = null; if (this.httpPost != null & list != null ) { try { UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8"); httpPost.setEntity(entityParam); this.startTime = System.currentTimeMillis(); HttpResponse response = httpClient.execute(this.httpPost); this.endTime = System.currentTimeMillis(); int statusCode = response.getStatusLine().getStatusCode(); logger.info("statusCode:" + statusCode); logger.info("调用API 花费时间(单位:毫秒):" + (this.endTime - this.startTime)); if (statusCode != HttpStatus.SC_OK) { logger.error("Method failed:" + response.getStatusLine()); this.status = 1; } // Read the response body body = EntityUtils.toString(response.getEntity()); } catch (IOException e) { // 网络错误 this.status = 3; } finally { logger.info("调用接口状态:" + this.status); } } return body; } /** * 0.成功 1.执行方法失败 2.协议错误 3.网络错误 * @return the status */ public int getStatus() { return this.status; } public long getStartTime() { return this.startTime; } public long getEndTime() { return this.endTime; } }
既然不能识别请求信息中的电话号码,即请求参数,那么肯定是在配置参数时有问题。所以得查看httpClient源码一探究竟,根据一骨碌的继承关系,最终找到了org.apache.http.client.utils.URLEncodedUtils这个工具类中。
public static String format( final List <? extends NameValuePair> parameters, final String charset) { return format(parameters, QP_SEP_A, charset); } public static String format( final List <? extends NameValuePair> parameters, final char parameterSeparator, final String charset) { final StringBuilder result = new StringBuilder(); for (final NameValuePair parameter : parameters) { final String encodedName = encodeFormFields(parameter.getName(), charset); final String encodedValue = encodeFormFields(parameter.getValue(), charset); if (result.length() > 0) { result.append(parameterSeparator); } result.append(encodedName); if (encodedValue != null) { result.append(NAME_VALUE_SEPARATOR); result.append(encodedValue); } } return result.toString(); }
从第二个format方法可以看到,就是把参数名和参数值取出来,中间连接一个“&”,等等,是不是差点什么,第一个参数与前面URL之间的“?”呢??果然,在声明URL的时候加上一个问号直接解决问题:http://utf8.api.smschinese.cn/?,这样在后续的拼接过程后,才能正确的读取参数。
另外,更加简单粗暴的方法是直接在声明URL的时候,加上对应的参数信息,就可以一步到位了,但是这样不是特别利于代码的维护及扩展。
相关文章推荐
- Linux平台,使用JavaComm3 API及SMSLib项目实现在Web Application中发送手机短信的功能
- 使用JAVA实现模拟登陆并发送新浪微博(非调用新浪API)
- java调用发送短信API
- java开发系统内核:使用一个中断实现多个API调用
- 使用云之讯API借口发送短信(Java,Json版)
- SMS短信通API——(1)Java应用发送手机短信
- 一个非常不错的纯源码“PDF转换swf”完全脱离安装第三方插件,直接使用java调用Flash api将PDF转换成图片,在将图片转换成swf。
- java调用短信api发送短信进行注册
- 程序调用飞信API发送免费短信(JAVA例子,其他语言一样用)
- 程序调用飞信API发送免费短信(JAVA例子,其他语言一样用)
- Java使用云片API发送短信验证码
- 程序调用飞信API发送免费短信(JAVA例子,其他语言一样用)
- java 调用云通信的api发送短信
- java 使用短信猫 发送短信
- java调用支付平台API--解析XML返回bean
- Java得到一个整数的绝对值,不使用任何判断和比较语句,包括API
- 使用Eclipse运行Java代码调用JDBC读写MySQL中文变成问号的终极解决办法
- Java调用SMSLib发送短信详解
- 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用
- 使用飞信API 发送 短信