Package com.jeck.microblogging.utils

Source Code of com.jeck.microblogging.utils.GAEHttpClient

package com.jeck.microblogging.utils;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.activation.MimetypesFileTypeMap;

import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HeaderElement;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.PartBase;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.util.EncodingUtil;
import org.apache.log4j.Logger;

import weibo4j.http.HttpClient;
import weibo4j.http.Response;
import weibo4j.model.Configuration;
import weibo4j.model.Paging;
import weibo4j.model.PostParameter;
import weibo4j.model.WeiboException;
import weibo4j.org.json.JSONException;

import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.jeck.microblogging.shared.interfaces.IHttpClient;

public class GAEHttpClient implements IHttpClient {

  private static final long serialVersionUID = -176092625883595547L;
  private static final int OK = 200; // OK: Success!
  private static final int NOT_MODIFIED = 304; // Not Modified: There was no
                          // new data to return.
  private static final int BAD_REQUEST = 400; // Bad Request: The request was
                        // invalid. An accompanying
                        // error message will explain
                        // why. This is the status code
                        // will be returned during rate
                        // limiting.
  private static final int NOT_AUTHORIZED = 401; // Not Authorized:
                          // Authentication
                          // credentials were missing
                          // or incorrect.
  private static final int FORBIDDEN = 403; // Forbidden: The request is
                        // understood, but it has been
                        // refused. An accompanying
                        // error message will explain
                        // why.
  private static final int NOT_FOUND = 404; // Not Found: The URI requested is
                        // invalid or the resource
                        // requested, such as a user,
                        // does not exists.
  private static final int NOT_ACCEPTABLE = 406; // Not Acceptable: Returned
                          // by the Search API when an
                          // invalid format is
                          // specified in the request.
  private static final int INTERNAL_SERVER_ERROR = 500;// Internal Server
                              // Error: Something
                              // is broken. Please
                              // post to the group
                              // so the Weibo team
                              // can investigate.
  private static final int BAD_GATEWAY = 502;// Bad Gateway: Weibo is down or
                        // being upgraded.
  private static final int SERVICE_UNAVAILABLE = 503;// Service Unavailable:
                            // The Weibo servers are
                            // up, but overloaded
                            // with requests. Try
                            // again later. The
                            // search and trend
                            // methods use this to
                            // indicate when you are
                            // being rate limited.

  private String proxyHost = Configuration.getProxyHost();
  private int proxyPort = Configuration.getProxyPort();
  private String proxyAuthUser = Configuration.getProxyUser();
  private String proxyAuthPassword = Configuration.getProxyPassword();
  private String token;

  public String getProxyHost() {
    return proxyHost;
  }

  /**
   * Sets proxy host. System property -Dsinat4j.http.proxyHost or
   * http.proxyHost overrides this attribute.
   *
   * @param proxyHost
   */
  public void setProxyHost(String proxyHost) {
    this.proxyHost = Configuration.getProxyHost(proxyHost);
  }

  public int getProxyPort() {
    return proxyPort;
  }

  /**
   * Sets proxy port. System property -Dsinat4j.http.proxyPort or
   * -Dhttp.proxyPort overrides this attribute.
   *
   * @param proxyPort
   */
  public void setProxyPort(int proxyPort) {
    this.proxyPort = Configuration.getProxyPort(proxyPort);
  }

  public String getProxyAuthUser() {
    return proxyAuthUser;
  }

  /**
   * Sets proxy authentication user. System property -Dsinat4j.http.proxyUser
   * overrides this attribute.
   *
   * @param proxyAuthUser
   */
  public void setProxyAuthUser(String proxyAuthUser) {
    this.proxyAuthUser = Configuration.getProxyUser(proxyAuthUser);
  }

  public String getProxyAuthPassword() {
    return proxyAuthPassword;
  }

  /**
   * Sets proxy authentication password. System property
   * -Dsinat4j.http.proxyPassword overrides this attribute.
   *
   * @param proxyAuthPassword
   */
  public void setProxyAuthPassword(String proxyAuthPassword) {
    this.proxyAuthPassword = Configuration
        .getProxyPassword(proxyAuthPassword);
  }

  public String setToken(String token) {
    this.token = token;
    return this.token;
  }

  private final static boolean DEBUG = Configuration.getDebug();
  static Logger log = Logger.getLogger(HttpClient.class.getName());

  private SimpleHttpConnectionManager connectionManager;
  private int maxSize;

  private URLFetchService service;

  public GAEHttpClient() {
    // change timeout to 2s avoid block thread-pool (Tim)
    this(150, 2000, 2000, 1024 * 1024);
  }

  public GAEHttpClient(int maxConPerHost, int conTimeOutMs, int soTimeOutMs,
      int maxSize) {
    connectionManager = new SimpleHttpConnectionManager();
    HttpConnectionManagerParams params = connectionManager.getParams();
    params.setDefaultMaxConnectionsPerHost(maxConPerHost);
    params.setConnectionTimeout(conTimeOutMs);
    params.setSoTimeout(soTimeOutMs);

    HttpClientParams clientParams = new HttpClientParams();
    // 忽略cookie 避免 Cookie rejected 警告
    clientParams.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
    service = URLFetchServiceFactory.getURLFetchService();
  }

  /**
   * log调试
   *
   */
  private static void log(String message) {
    if (DEBUG) {
      log.debug(message);
    }
  }

  /**
   * 处理http getmethod 请求
   *
   */

  public Response get(String url) throws WeiboException {

    return get(url, new PostParameter[0]);

  }

  public Response get(String url, PostParameter[] params)
      throws WeiboException {
    log("Request:");
    log("GET:" + url);
    if (null != params && params.length > 0) {
      String encodedParams = HttpClient.encodeParameters(params);
      if (-1 == url.indexOf("?")) {
        url += "?" + encodedParams;
      } else {
        url += "&" + encodedParams;
      }
    }
    GetMethod getmethod = new GetMethod(url);
    return httpRequest(getmethod);

  }

  public Response get(String url, PostParameter[] params, Paging paging)
      throws WeiboException {
    if (null != paging) {
      List<PostParameter> pagingParams = new ArrayList<PostParameter>(4);
      if (-1 != paging.getMaxId()) {
        pagingParams.add(new PostParameter("max_id", String
            .valueOf(paging.getMaxId())));
      }
      if (-1 != paging.getSinceId()) {
        pagingParams.add(new PostParameter("since_id", String
            .valueOf(paging.getSinceId())));
      }
      if (-1 != paging.getPage()) {
        pagingParams.add(new PostParameter("page", String
            .valueOf(paging.getPage())));
      }
      if (-1 != paging.getCount()) {
        if (-1 != url.indexOf("search")) {
          // search api takes "rpp"
          pagingParams.add(new PostParameter("rpp", String
              .valueOf(paging.getCount())));
        } else {
          pagingParams.add(new PostParameter("count", String
              .valueOf(paging.getCount())));
        }
      }
      PostParameter[] newparams = null;
      PostParameter[] arrayPagingParams = pagingParams
          .toArray(new PostParameter[pagingParams.size()]);
      if (null != params) {
        newparams = new PostParameter[params.length
            + pagingParams.size()];
        System.arraycopy(params, 0, newparams, 0, params.length);
        System.arraycopy(arrayPagingParams, 0, newparams,
            params.length, pagingParams.size());
      } else {
        if (0 != arrayPagingParams.length) {
          String encodedParams = HttpClient
              .encodeParameters(arrayPagingParams);
          if (-1 != url.indexOf("?")) {
            url += "&" + encodedParams;
          } else {
            url += "?" + encodedParams;
          }
        }
      }
      return get(url, newparams);
    } else {
      return get(url, params);
    }
  }

  /**
   * 处理http deletemethod请求
   */

  public Response delete(String url, PostParameter[] params)
      throws WeiboException {
    if (0 != params.length) {
      String encodedParams = HttpClient.encodeParameters(params);
      if (-1 == url.indexOf("?")) {
        url += "?" + encodedParams;
      } else {
        url += "&" + encodedParams;
      }
    }
    DeleteMethod deleteMethod = new DeleteMethod(url);
    return httpRequest(deleteMethod);

  }

  /**
   * 处理http post请求
   *
   */

  public Response post(String url, PostParameter[] params)
      throws WeiboException {
    return post(url, params, true);

  }

  public Response post(String url, PostParameter[] params,
      Boolean WithTokenHeader) throws WeiboException {
    log("Request:");
    log("POST:" + url);
    PostMethod postMethod = new PostMethod(url);
    for (int i = 0; i < params.length; i++) {
      postMethod.addParameter(params[i].getName(), params[i].getValue());
    }
    HttpMethodParams param = postMethod.getParams();
    param.setContentCharset("UTF-8");
    if (WithTokenHeader) {
      return httpRequest(postMethod);
    } else {
      return httpRequest(postMethod, WithTokenHeader);
    }
  }

  /**
   * 支持multipart方式上传图片
   *
   */
//  public Response multPartURL(String url, PostParameter[] params,
//      ImageItem item) throws WeiboException {
//    PostMethod postMethod = new PostMethod(url);
//    try {
//      Part[] parts = null;
//      if (params == null) {
//        parts = new Part[1];
//      } else {
//        parts = new Part[params.length + 1];
//      }
//      if (params != null) {
//        int i = 0;
//        for (PostParameter entry : params) {
//          parts[i++] = new StringPart(entry.getName(),
//              (String) entry.getValue());
//        }
//        parts[parts.length - 1] = new ByteArrayPart(item.getContent(),
//            item.getName(), item.getContentType());
//      }
//      postMethod.setRequestEntity(new MultipartRequestEntity(parts,
//          postMethod.getParams()));
//      return httpRequest(postMethod);
//
//    } catch (Exception ex) {
//      throw new WeiboException(ex.getMessage(), ex, -1);
//    }
//  }

  public Response multPartURL(String fileParamName, String url,
      PostParameter[] params, File file, boolean authenticated)
      throws WeiboException {
    PostMethod postMethod = new PostMethod(url);
    try {
      Part[] parts = null;
      if (params == null) {
        parts = new Part[1];
      } else {
        parts = new Part[params.length + 1];
      }
      if (params != null) {
        int i = 0;
        for (PostParameter entry : params) {
          parts[i++] = new StringPart(entry.getName(),
              (String) entry.getValue());
        }
      }
      FilePart filePart = new FilePart(fileParamName, file.getName(),
          file, new MimetypesFileTypeMap().getContentType(file),
          "UTF-8");
      filePart.setTransferEncoding("binary");
      parts[parts.length - 1] = filePart;

      postMethod.setRequestEntity(new MultipartRequestEntity(parts,
          postMethod.getParams()));
      return httpRequest(postMethod);
    } catch (Exception ex) {
      throw new WeiboException(ex.getMessage(), ex, -1);
    }
  }

  public Response httpRequest(HttpMethod method) throws WeiboException {
    return httpRequest(method, true);
  }

  public Response httpRequest(HttpMethod method, Boolean WithTokenHeader)
      throws WeiboException {
    InetAddress ipaddr;
    int responseCode = -1;
    try {
      HTTPMethod m=null;
      if (method instanceof PostMethod){
        m = HTTPMethod.POST;
      }else{
        m = HTTPMethod.GET;
      }
     
      log("method:"+m+" URI:"+method.getURI()
          .toString());
     
      HTTPRequest request = new HTTPRequest(new URL(method.getURI().toString()),m);
      ipaddr = InetAddress.getLocalHost();
     
      log("WithTokenHeader:"+ WithTokenHeader);
      log("token:" + token);
     
      if (WithTokenHeader) {
        if (token == null) {
          throw new IllegalStateException("Oauth2 token is not set!");
        }
        request.addHeader(new HTTPHeader("Authorization", "OAuth2 "
            + token));
        request.addHeader(new HTTPHeader("API-RemoteIP", ipaddr
            .getHostAddress()));
      }

      if (method instanceof PostMethod){
        String content = EncodingUtil.formUrlEncode(((PostMethod)method).getParameters(), getRequestCharSet((PostMethod)method));
        request.setPayload(EncodingUtil.getAsciiBytes(content));
      }
     
      List<HTTPHeader> reqHeaders=request.getHeaders();
      log("reqHeaders:"+ reqHeaders);
      if (reqHeaders != null){
        for (HTTPHeader httpHeader : reqHeaders) {
          log("RequestHeader name:"+httpHeader.getName()+" value:"+ httpHeader.getValue());
        }
      }
     
      log("final URL:"+request.getURL().toString());
     
      HTTPResponse responseFromServer = service.fetch(request);

      responseCode = responseFromServer.getResponseCode();
      log("Response:");
      log("https StatusCode:" + String.valueOf(responseCode));

      Response response = new Response();
      List<HTTPHeader> resposeHeaderList = responseFromServer
          .getHeaders();
      Header header = new Header();
      if (resposeHeaderList != null) {
        for (HTTPHeader httpHeader : resposeHeaderList) {
          if (httpHeader.getName().equals("Content-Type")) {
            header.setName(httpHeader.getName());
            header.setValue(httpHeader.getValue());
            break;
          }
        }
      }
      response.setResponseAsString(EncodingUtil.getString(
          responseFromServer.getContent(), getContentCharSet(header)));
      log(response.toString() + "\n");

      if (responseCode != OK)

      {
        log(response.asString());
        try {
          throw new WeiboException(getCause(responseCode),
              response.asJSONObject(), responseCode);
        } catch (JSONException e) {
          e.printStackTrace();
        }
      }
      return response;

    } catch (IOException ioe) {
      throw new WeiboException(ioe.getMessage(), ioe, responseCode);
    } finally {
      method.releaseConnection();
    }

  }

  protected String getContentCharSet(Header contentheader) {
    String charset = null;
    if (contentheader != null) {
      HeaderElement values[] = contentheader.getElements();
      // I expect only one header element to be there
      // No more. no less
      if (values.length == 1) {
        NameValuePair param = values[0].getParameterByName("charset");
        if (param != null) {
          // If I get anything "funny"
          // UnsupportedEncondingException will result
          charset = param.getValue();
        }
      }
    }
    if (charset ==null ){
      charset = "UTF-8";
    }
    return charset;
  }
 
  public String getRequestCharSet(PostMethod method) {
            return method.getRequestCharSet();
    }

  /*
   * 对parameters进行encode处理
   */
  public static String encodeParameters(PostParameter[] postParams) {
    StringBuffer buf = new StringBuffer();
    for (int j = 0; j < postParams.length; j++) {
      if (j != 0) {
        buf.append("&");
      }
      try {
        buf.append(URLEncoder.encode(postParams[j].getName(), "UTF-8"))
            .append("=")
            .append(URLEncoder.encode(postParams[j].getValue(),
                "UTF-8"));
      } catch (java.io.UnsupportedEncodingException neverHappen) {
      }
    }
    return buf.toString();
  }

  private static class ByteArrayPart extends PartBase {
    private byte[] mData;
    private String mName;

    public ByteArrayPart(byte[] data, String name, String type)
        throws IOException {
      super(name, type, "UTF-8", "binary");
      mName = name;
      mData = data;
    }

    protected void sendData(OutputStream out) throws IOException {
      out.write(mData);
    }

    protected long lengthOfData() throws IOException {
      return mData.length;
    }

    protected void sendDispositionHeader(OutputStream out)
        throws IOException {
      super.sendDispositionHeader(out);
      StringBuilder buf = new StringBuilder();
      buf.append("; filename=\"").append(mName).append("\"");
      out.write(buf.toString().getBytes());
    }
  }

  private static String getCause(int statusCode) {
    String cause = null;
    switch (statusCode) {
    case NOT_MODIFIED:
      break;
    case BAD_REQUEST:
      cause = "The request was invalid.  An accompanying error message will explain why. This is the status code will be returned during rate limiting.";
      break;
    case NOT_AUTHORIZED:
      cause = "Authentication credentials were missing or incorrect.";
      break;
    case FORBIDDEN:
      cause = "The request is understood, but it has been refused.  An accompanying error message will explain why.";
      break;
    case NOT_FOUND:
      cause = "The URI requested is invalid or the resource requested, such as a user, does not exists.";
      break;
    case NOT_ACCEPTABLE:
      cause = "Returned by the Search API when an invalid format is specified in the request.";
      break;
    case INTERNAL_SERVER_ERROR:
      cause = "Something is broken.  Please post to the group so the Weibo team can investigate.";
      break;
    case BAD_GATEWAY:
      cause = "Weibo is down or being upgraded.";
      break;
    case SERVICE_UNAVAILABLE:
      cause = "Service Unavailable: The Weibo servers are up, but overloaded with requests. Try again later. The search and trend methods use this to indicate when you are being rate limited.";
      break;
    default:
      cause = "";
    }
    return statusCode + ":" + cause;
  }

}
TOP

Related Classes of com.jeck.microblogging.utils.GAEHttpClient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.