1. 程式人生 > >使用搜狐Sendcloud的Webapi傳送郵件 Jodd和Apache Httpclient

使用搜狐Sendcloud的Webapi傳送郵件 Jodd和Apache Httpclient

                最近,在使用搜狐Sendcloud發郵件。
    Sendcloud提供http格式的webapi,方便地傳送郵件,當然是要付費的。

   很早之前,http工具一直用Httpclient,後來覺得jodd更簡單,就傾向於jodd的一些工具庫了。

   使用jodd遇到一個問題:
  當郵件內容比較大時,比如1萬多字元的時候,傳送郵件失敗。
Sendcloud伺服器所在的Nginx,提示

414 Request-URI Too Large


<html>

<head><title>414 Request-URI Too Large</title></head>

<body bgcolor="white">

<center><h1>414 Request-URI Too Large</h1></center>

<hr><center>nginx</center>

</body>

</html>

  提交工單,與客服和技術支援,交流了幾個小時,終於解決了問題。

第1種方法:使用官方給的Apache Httpclient的例子,傳送郵件。
第2種方法:原來用Jodd,使用方式有問題。
Map<String, String> queryMap = new HashMap<String, String>();  queryMap.put("api_user"
, API_USER);  queryMap.put("api_key", API_KEY);  queryMap.put("from", FROM);  queryMap.put("to", to);  queryMap.put("subject", subject);  queryMap.put("html", html.substring(0,html.length()));  HttpResponse response = HttpRequest.post(URL)// .contentType(contentType)    .query(queryMap).send();  String body = response.bodyText();



這個地方用的是“post” ,但是引數仍然放在了url後面,當資料量過大時,就有問題了。
正確的做法是: 
HttpResponse response = HttpRequest.post(URL)// .contentType(contentType).form(queryMap).send();
用form方法替代query方法。


有2個疑惑:
1.用post傳送,為啥會把引數放在url後面?或者說,url後面接引數,還是post傳送麼?
2. jodd官方,有這句話:
Query parameters may be specified in the URL line (but then they have to be correctly encoded).
為啥是“可能”?

以下是一些程式碼 
Apache傳送:
public static void send(String to, String subject, String html) {  if (!check()) {   return;  }  String url = URL;  HttpClient httpclient = new DefaultHttpClient();  HttpPost httpost = new HttpPost(url);  List nvps = new ArrayList();  nvps.add(new BasicNameValuePair("api_user", API_USER));  nvps.add(new BasicNameValuePair("api_key", API_KEY));  nvps.add(new BasicNameValuePair("from", FROM));  nvps.add(new BasicNameValuePair("to", to));  nvps.add(new BasicNameValuePair("subject", subject));  nvps.add(new BasicNameValuePair("html", html));  try {   httpost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));   HttpResponse response = httpclient.execute(httpost);   if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { // 正常返回    HttpEntity entity = response.getEntity();    System.out.println(EntityUtils.toString(entity));   } else {    System.err.println("error");   }  } catch (Exception e) {   e.printStackTrace();  } }



Jodd傳送:
public static void send(String to, String subject, String html) {  if (!check()) {   return;  }  Map<String, Object> queryMap = new HashMap<String, Object>();  queryMap.put("api_user", API_USER);  queryMap.put("api_key", API_KEY);  queryMap.put("from", FROM);  queryMap.put("to", to);  queryMap.put("subject", subject);  queryMap.put("html", html.substring(0,html.length()));  HttpResponse response = HttpRequest.post(URL)// .contentType(contentType)    .form(queryMap).send();  String body = response.bodyText();  try {   JSONObject jsonObject = JSONObject.parseObject(body);   MailMessage msg = JSONObject.toJavaObject(jsonObject,     MailMessage.class);   String sendInfo = "to=" + to + ",subject=" + subject;   if (msg.getMessage().equals(MailMessage.ERROR)) {    logger.error("sendcloud,send mail failed:" + msg + ",sendInfo:"      + sendInfo);   } else if (msg.getMessage().equals(MailMessage.SUCCESS)) {    logger.info("sendcloud,send mail ok,sendInfo:" + sendInfo);   }  } catch (Exception e) {   logger.error("send mail failed",e);   logger.info(body);  }  // System.out.println(response); } 


   jodd資料:http://jodd.org/doc/http.html